scrypt 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ /*
2
+ * scrypt_calibrate.h
3
+ * scrypt
4
+ *
5
+ * Created by Patrick Hogan on 12/15/10.
6
+ *
7
+ */
8
+
9
+ #ifndef _SCRYPT_CALIBRATE_H_
10
+ #define _SCRYPT_CALIBRATE_H_
11
+
12
+ #include <stdint.h>
13
+ #include <stdio.h>
14
+
15
+ int calibrate( size_t maxmem, double maxmemfrac, double maxtime, uint64_t * n, uint32_t * r, uint32_t * p );
16
+
17
+ #endif
18
+
19
+
Binary file
@@ -0,0 +1,126 @@
1
+ #include "ruby.h"
2
+ #include "scrypt_calibrate.h"
3
+ #include "crypto_scrypt.h"
4
+
5
+
6
+ static VALUE mSCrypt;
7
+ static VALUE cSCryptEngine;
8
+
9
+
10
+ #ifndef RSTRING_PTR
11
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
12
+ #endif
13
+
14
+
15
+ static VALUE sc_calibrate( VALUE self, VALUE maxmem, VALUE maxmemfrac, VALUE maxtime )
16
+ {
17
+ uint64_t n = 0;
18
+ uint32_t r = 0;
19
+ uint32_t p = 0;
20
+
21
+ size_t mm = rb_num2uint( maxmem );
22
+ double mf = rb_num2dbl( maxmemfrac );
23
+ double mt = rb_num2dbl( maxtime );
24
+
25
+ if (calibrate( mm, mf, mt, & n, & r, & p ) == 0)
26
+ {
27
+ char cost_str[33];
28
+ memset( cost_str, '\0', 33 );
29
+ sprintf( cost_str, "%Lx$%x$%x$", n, r, p );
30
+ return rb_str_new2( cost_str );
31
+ }
32
+
33
+ return Qnil;
34
+ }
35
+
36
+
37
+ static VALUE sc_crypt( VALUE self, VALUE key, VALUE salt, VALUE cost )
38
+ {
39
+ const char * safe_key = RSTRING_PTR(key) ? RSTRING_PTR(key) : "";
40
+ const char * safe_salt = RSTRING_PTR(salt) ? RSTRING_PTR(salt) : "";
41
+
42
+ const size_t buffer_size = 256;
43
+ char buffer[buffer_size];
44
+ memset( buffer, '\0', buffer_size );
45
+
46
+ if (!RSTRING_PTR( cost ))
47
+ {
48
+ return Qnil;
49
+ }
50
+
51
+ uint64_t n = 0;
52
+ uint32_t r = 0;
53
+ uint32_t p = 0;
54
+ sscanf( RSTRING_PTR( cost ), "%Lx$%x$%x$", & n, & r, & p );
55
+
56
+ int result = crypto_scrypt(
57
+ (uint8_t *) safe_key, strlen(safe_key),
58
+ (uint8_t *) safe_salt, strlen(safe_salt),
59
+ n, r, p,
60
+ (uint8_t *) buffer, buffer_size
61
+ );
62
+
63
+ if (result == 0)
64
+ {
65
+ return rb_str_new( buffer, buffer_size );
66
+ }
67
+
68
+ printf( "error %d \n", result );
69
+
70
+ return Qnil;
71
+ }
72
+
73
+
74
+ void Init_scrypt_ext()
75
+ {
76
+ mSCrypt = rb_define_module( "SCrypt" );
77
+ cSCryptEngine = rb_define_class_under( mSCrypt, "Engine", rb_cObject );
78
+
79
+ rb_define_singleton_method( cSCryptEngine, "__sc_calibrate", sc_calibrate, 3 );
80
+ rb_define_singleton_method( cSCryptEngine, "__sc_crypt", sc_crypt, 3 );
81
+ }
82
+
83
+
84
+ /*
85
+ #include <stdio.h>
86
+ #include <string.h>
87
+ #include "scrypt_calibrate.h"
88
+ #include "crypto_scrypt.h"
89
+
90
+ int main (int argc, const char * argv[])
91
+ {
92
+ uint64_t n;
93
+ uint32_t r;
94
+ uint32_t p;
95
+
96
+ int result = calibrate( 0, 0.001, 0.25, & n, & r, & p );
97
+
98
+ printf( "%Ld %d %d \n", n, r, p );
99
+
100
+ char header[33];
101
+ sprintf( header, "%.16Lx%.8x%.8x", n, r, p );
102
+ printf( "%s \n", header );
103
+
104
+ uint64_t a = 0;
105
+ uint32_t b = 0;
106
+ uint32_t c = 0;
107
+ sscanf( header, "%16Lx%8x%8x", & a, & b, & c );
108
+ printf( "%Ld %d %d \n", a, b, c );
109
+
110
+ char password[] = "helloworld!";
111
+ char salt[] = "qwerty";
112
+ const size_t buffer_size = 32;
113
+ char buffer[buffer_size];
114
+ memset(buffer, '\0', buffer_size);
115
+
116
+ result = crypto_scrypt( (uint8_t *) password, strlen(password), (uint8_t *) salt, strlen(salt), n, r, p, (uint8_t *) buffer, buffer_size );
117
+
118
+ for (size_t i=0; i<buffer_size; i++)
119
+ {
120
+ printf( "%.2x", buffer[i] );
121
+ }
122
+ printf( "\n" );
123
+
124
+ return 0;
125
+ }
126
+ */
@@ -0,0 +1,4 @@
1
+ #ifndef _SCRYPT_PLATFORM_H_
2
+ #define _SCRYPT_PLATFORM_H_
3
+
4
+ #endif
@@ -0,0 +1,185 @@
1
+ /*-
2
+ * Copyright 2009 Colin Percival
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ * SUCH DAMAGE.
25
+ *
26
+ * This file was originally written by Colin Percival as part of the Tarsnap
27
+ * online backup system.
28
+ */
29
+ #include "scrypt_platform.h"
30
+
31
+ #include <sys/time.h>
32
+
33
+ #include <stdint.h>
34
+ #include <stdio.h>
35
+ #include <time.h>
36
+
37
+ #include "crypto_scrypt.h"
38
+
39
+ #include "scryptenc_cpuperf.h"
40
+
41
+ #ifdef HAVE_CLOCK_GETTIME
42
+
43
+ static clock_t clocktouse;
44
+
45
+ static int
46
+ getclockres(double * resd)
47
+ {
48
+ struct timespec res;
49
+
50
+ /*
51
+ * Try clocks in order of preference until we find one which works.
52
+ * (We assume that if clock_getres works, clock_gettime will, too.)
53
+ * The use of if/else/if/else/if/else rather than if/elif/elif/else
54
+ * is ugly but legal, and allows us to #ifdef things appropriately.
55
+ */
56
+ #ifdef CLOCK_VIRTUAL
57
+ if (clock_getres(CLOCK_VIRTUAL, &res) == 0)
58
+ clocktouse = CLOCK_VIRTUAL;
59
+ else
60
+ #endif
61
+ #ifdef CLOCK_MONOTONIC
62
+ if (clock_getres(CLOCK_MONOTONIC, &res) == 0)
63
+ clocktouse = CLOCK_MONOTONIC;
64
+ else
65
+ #endif
66
+ if (clock_getres(CLOCK_REALTIME, &res) == 0)
67
+ clocktouse = CLOCK_REALTIME;
68
+ else
69
+ return (-1);
70
+
71
+ /* Convert clock resolution to a double. */
72
+ *resd = res.tv_sec + res.tv_nsec * 0.000000001;
73
+
74
+ return (0);
75
+ }
76
+
77
+ static int
78
+ getclocktime(struct timespec * ts)
79
+ {
80
+
81
+ if (clock_gettime(clocktouse, ts))
82
+ return (-1);
83
+
84
+ return (0);
85
+ }
86
+
87
+ #else
88
+ static int
89
+ getclockres(double * resd)
90
+ {
91
+
92
+ *resd = 1.0 / CLOCKS_PER_SEC;
93
+
94
+ return (0);
95
+ }
96
+
97
+ static int
98
+ getclocktime(struct timespec * ts)
99
+ {
100
+ struct timeval tv;
101
+
102
+ if (gettimeofday(&tv, NULL))
103
+ return (-1);
104
+ ts->tv_sec = tv.tv_sec;
105
+ ts->tv_nsec = tv.tv_usec * 1000;
106
+
107
+ return (0);
108
+ }
109
+ #endif
110
+
111
+ static int
112
+ getclockdiff(struct timespec * st, double * diffd)
113
+ {
114
+ struct timespec en;
115
+
116
+ if (getclocktime(&en))
117
+ return (1);
118
+ *diffd = (en.tv_nsec - st->tv_nsec) * 0.000000001 +
119
+ (en.tv_sec - st->tv_sec);
120
+
121
+ return (0);
122
+ }
123
+
124
+ /**
125
+ * scryptenc_cpuperf(opps):
126
+ * Estimate the number of salsa20/8 cores which can be executed per second,
127
+ * and return the value via opps.
128
+ */
129
+ int
130
+ scryptenc_cpuperf(double * opps)
131
+ {
132
+ struct timespec st;
133
+ double resd, diffd;
134
+ uint64_t i = 0;
135
+
136
+ /* Get the clock resolution. */
137
+ if (getclockres(&resd))
138
+ return (2);
139
+
140
+ #ifdef DEBUG
141
+ fprintf(stderr, "Clock resolution is %f\n", resd);
142
+ #endif
143
+
144
+ /* Loop until the clock ticks. */
145
+ if (getclocktime(&st))
146
+ return (2);
147
+ do {
148
+ /* Do an scrypt. */
149
+ if (crypto_scrypt(NULL, 0, NULL, 0, 16, 1, 1, NULL, 0))
150
+ return (3);
151
+
152
+ /* Has the clock ticked? */
153
+ if (getclockdiff(&st, &diffd))
154
+ return (2);
155
+ if (diffd > 0)
156
+ break;
157
+ } while (1);
158
+
159
+ /* Could how many scryps we can do before the next tick. */
160
+ if (getclocktime(&st))
161
+ return (2);
162
+ do {
163
+ /* Do an scrypt. */
164
+ if (crypto_scrypt(NULL, 0, NULL, 0, 128, 1, 1, NULL, 0))
165
+ return (3);
166
+
167
+ /* We invoked the salsa20/8 core 512 times. */
168
+ i += 512;
169
+
170
+ /* Check if we have looped for long enough. */
171
+ if (getclockdiff(&st, &diffd))
172
+ return (2);
173
+ if (diffd > resd)
174
+ break;
175
+ } while (1);
176
+
177
+ #ifdef DEBUG
178
+ fprintf(stderr, "%ju salsa20/8 cores performed in %f seconds\n",
179
+ (uintmax_t)i, diffd);
180
+ #endif
181
+
182
+ /* We can do approximately i salsa20/8 cores per diffd seconds. */
183
+ *opps = i / diffd;
184
+ return (0);
185
+ }
@@ -0,0 +1,39 @@
1
+ /*-
2
+ * Copyright 2009 Colin Percival
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ * SUCH DAMAGE.
25
+ *
26
+ * This file was originally written by Colin Percival as part of the Tarsnap
27
+ * online backup system.
28
+ */
29
+ #ifndef _SCRYPTENC_CPUPERF_H_
30
+ #define _SCRYPTENC_CPUPERF_H_
31
+
32
+ /**
33
+ * scryptenc_cpuperf(opps):
34
+ * Estimate the number of salsa20/8 cores which can be executed per second,
35
+ * and return the value via opps.
36
+ */
37
+ int scryptenc_cpuperf(double *);
38
+
39
+ #endif /* !_SCRYPTENC_CPUPERF_H_ */
@@ -0,0 +1,412 @@
1
+ /*-
2
+ * Copyright 2005,2007,2009 Colin Percival
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ * SUCH DAMAGE.
25
+ */
26
+ #include "scrypt_platform.h"
27
+
28
+ #include <sys/types.h>
29
+
30
+ #include <stdint.h>
31
+ #include <string.h>
32
+
33
+ #include "sysendian.h"
34
+
35
+ #include "sha256.h"
36
+
37
+ /*
38
+ * Encode a length len/4 vector of (uint32_t) into a length len vector of
39
+ * (unsigned char) in big-endian form. Assumes len is a multiple of 4.
40
+ */
41
+ static void
42
+ be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
43
+ {
44
+ size_t i;
45
+
46
+ for (i = 0; i < len / 4; i++)
47
+ be32enc(dst + i * 4, src[i]);
48
+ }
49
+
50
+ /*
51
+ * Decode a big-endian length len vector of (unsigned char) into a length
52
+ * len/4 vector of (uint32_t). Assumes len is a multiple of 4.
53
+ */
54
+ static void
55
+ be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
56
+ {
57
+ size_t i;
58
+
59
+ for (i = 0; i < len / 4; i++)
60
+ dst[i] = be32dec(src + i * 4);
61
+ }
62
+
63
+ /* Elementary functions used by SHA256 */
64
+ #define Ch(x, y, z) ((x & (y ^ z)) ^ z)
65
+ #define Maj(x, y, z) ((x & (y | z)) | (y & z))
66
+ #define SHR(x, n) (x >> n)
67
+ #define ROTR(x, n) ((x >> n) | (x << (32 - n)))
68
+ #define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
69
+ #define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
70
+ #define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
71
+ #define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
72
+
73
+ /* SHA256 round function */
74
+ #define RND(a, b, c, d, e, f, g, h, k) \
75
+ t0 = h + S1(e) + Ch(e, f, g) + k; \
76
+ t1 = S0(a) + Maj(a, b, c); \
77
+ d += t0; \
78
+ h = t0 + t1;
79
+
80
+ /* Adjusted round function for rotating state */
81
+ #define RNDr(S, W, i, k) \
82
+ RND(S[(64 - i) % 8], S[(65 - i) % 8], \
83
+ S[(66 - i) % 8], S[(67 - i) % 8], \
84
+ S[(68 - i) % 8], S[(69 - i) % 8], \
85
+ S[(70 - i) % 8], S[(71 - i) % 8], \
86
+ W[i] + k)
87
+
88
+ /*
89
+ * SHA256 block compression function. The 256-bit state is transformed via
90
+ * the 512-bit input block to produce a new state.
91
+ */
92
+ static void
93
+ SHA256_Transform(uint32_t * state, const unsigned char block[64])
94
+ {
95
+ uint32_t W[64];
96
+ uint32_t S[8];
97
+ uint32_t t0, t1;
98
+ int i;
99
+
100
+ /* 1. Prepare message schedule W. */
101
+ be32dec_vect(W, block, 64);
102
+ for (i = 16; i < 64; i++)
103
+ W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
104
+
105
+ /* 2. Initialize working variables. */
106
+ memcpy(S, state, 32);
107
+
108
+ /* 3. Mix. */
109
+ RNDr(S, W, 0, 0x428a2f98);
110
+ RNDr(S, W, 1, 0x71374491);
111
+ RNDr(S, W, 2, 0xb5c0fbcf);
112
+ RNDr(S, W, 3, 0xe9b5dba5);
113
+ RNDr(S, W, 4, 0x3956c25b);
114
+ RNDr(S, W, 5, 0x59f111f1);
115
+ RNDr(S, W, 6, 0x923f82a4);
116
+ RNDr(S, W, 7, 0xab1c5ed5);
117
+ RNDr(S, W, 8, 0xd807aa98);
118
+ RNDr(S, W, 9, 0x12835b01);
119
+ RNDr(S, W, 10, 0x243185be);
120
+ RNDr(S, W, 11, 0x550c7dc3);
121
+ RNDr(S, W, 12, 0x72be5d74);
122
+ RNDr(S, W, 13, 0x80deb1fe);
123
+ RNDr(S, W, 14, 0x9bdc06a7);
124
+ RNDr(S, W, 15, 0xc19bf174);
125
+ RNDr(S, W, 16, 0xe49b69c1);
126
+ RNDr(S, W, 17, 0xefbe4786);
127
+ RNDr(S, W, 18, 0x0fc19dc6);
128
+ RNDr(S, W, 19, 0x240ca1cc);
129
+ RNDr(S, W, 20, 0x2de92c6f);
130
+ RNDr(S, W, 21, 0x4a7484aa);
131
+ RNDr(S, W, 22, 0x5cb0a9dc);
132
+ RNDr(S, W, 23, 0x76f988da);
133
+ RNDr(S, W, 24, 0x983e5152);
134
+ RNDr(S, W, 25, 0xa831c66d);
135
+ RNDr(S, W, 26, 0xb00327c8);
136
+ RNDr(S, W, 27, 0xbf597fc7);
137
+ RNDr(S, W, 28, 0xc6e00bf3);
138
+ RNDr(S, W, 29, 0xd5a79147);
139
+ RNDr(S, W, 30, 0x06ca6351);
140
+ RNDr(S, W, 31, 0x14292967);
141
+ RNDr(S, W, 32, 0x27b70a85);
142
+ RNDr(S, W, 33, 0x2e1b2138);
143
+ RNDr(S, W, 34, 0x4d2c6dfc);
144
+ RNDr(S, W, 35, 0x53380d13);
145
+ RNDr(S, W, 36, 0x650a7354);
146
+ RNDr(S, W, 37, 0x766a0abb);
147
+ RNDr(S, W, 38, 0x81c2c92e);
148
+ RNDr(S, W, 39, 0x92722c85);
149
+ RNDr(S, W, 40, 0xa2bfe8a1);
150
+ RNDr(S, W, 41, 0xa81a664b);
151
+ RNDr(S, W, 42, 0xc24b8b70);
152
+ RNDr(S, W, 43, 0xc76c51a3);
153
+ RNDr(S, W, 44, 0xd192e819);
154
+ RNDr(S, W, 45, 0xd6990624);
155
+ RNDr(S, W, 46, 0xf40e3585);
156
+ RNDr(S, W, 47, 0x106aa070);
157
+ RNDr(S, W, 48, 0x19a4c116);
158
+ RNDr(S, W, 49, 0x1e376c08);
159
+ RNDr(S, W, 50, 0x2748774c);
160
+ RNDr(S, W, 51, 0x34b0bcb5);
161
+ RNDr(S, W, 52, 0x391c0cb3);
162
+ RNDr(S, W, 53, 0x4ed8aa4a);
163
+ RNDr(S, W, 54, 0x5b9cca4f);
164
+ RNDr(S, W, 55, 0x682e6ff3);
165
+ RNDr(S, W, 56, 0x748f82ee);
166
+ RNDr(S, W, 57, 0x78a5636f);
167
+ RNDr(S, W, 58, 0x84c87814);
168
+ RNDr(S, W, 59, 0x8cc70208);
169
+ RNDr(S, W, 60, 0x90befffa);
170
+ RNDr(S, W, 61, 0xa4506ceb);
171
+ RNDr(S, W, 62, 0xbef9a3f7);
172
+ RNDr(S, W, 63, 0xc67178f2);
173
+
174
+ /* 4. Mix local working variables into global state */
175
+ for (i = 0; i < 8; i++)
176
+ state[i] += S[i];
177
+
178
+ /* Clean the stack. */
179
+ memset(W, 0, 256);
180
+ memset(S, 0, 32);
181
+ t0 = t1 = 0;
182
+ }
183
+
184
+ static unsigned char PAD[64] = {
185
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
188
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
189
+ };
190
+
191
+ /* Add padding and terminating bit-count. */
192
+ static void
193
+ SHA256_Pad(SHA256_CTX * ctx)
194
+ {
195
+ unsigned char len[8];
196
+ uint32_t r, plen;
197
+
198
+ /*
199
+ * Convert length to a vector of bytes -- we do this now rather
200
+ * than later because the length will change after we pad.
201
+ */
202
+ be32enc_vect(len, ctx->count, 8);
203
+
204
+ /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
205
+ r = (ctx->count[1] >> 3) & 0x3f;
206
+ plen = (r < 56) ? (56 - r) : (120 - r);
207
+ SHA256_Update(ctx, PAD, (size_t)plen);
208
+
209
+ /* Add the terminating bit-count */
210
+ SHA256_Update(ctx, len, 8);
211
+ }
212
+
213
+ /* SHA-256 initialization. Begins a SHA-256 operation. */
214
+ void
215
+ SHA256_Init(SHA256_CTX * ctx)
216
+ {
217
+
218
+ /* Zero bits processed so far */
219
+ ctx->count[0] = ctx->count[1] = 0;
220
+
221
+ /* Magic initialization constants */
222
+ ctx->state[0] = 0x6A09E667;
223
+ ctx->state[1] = 0xBB67AE85;
224
+ ctx->state[2] = 0x3C6EF372;
225
+ ctx->state[3] = 0xA54FF53A;
226
+ ctx->state[4] = 0x510E527F;
227
+ ctx->state[5] = 0x9B05688C;
228
+ ctx->state[6] = 0x1F83D9AB;
229
+ ctx->state[7] = 0x5BE0CD19;
230
+ }
231
+
232
+ /* Add bytes into the hash */
233
+ void
234
+ SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
235
+ {
236
+ uint32_t bitlen[2];
237
+ uint32_t r;
238
+ const unsigned char *src = in;
239
+
240
+ /* Number of bytes left in the buffer from previous updates */
241
+ r = (ctx->count[1] >> 3) & 0x3f;
242
+
243
+ /* Convert the length into a number of bits */
244
+ bitlen[1] = ((uint32_t)len) << 3;
245
+ bitlen[0] = (uint32_t)(len >> 29);
246
+
247
+ /* Update number of bits */
248
+ if ((ctx->count[1] += bitlen[1]) < bitlen[1])
249
+ ctx->count[0]++;
250
+ ctx->count[0] += bitlen[0];
251
+
252
+ /* Handle the case where we don't need to perform any transforms */
253
+ if (len < 64 - r) {
254
+ memcpy(&ctx->buf[r], src, len);
255
+ return;
256
+ }
257
+
258
+ /* Finish the current block */
259
+ memcpy(&ctx->buf[r], src, 64 - r);
260
+ SHA256_Transform(ctx->state, ctx->buf);
261
+ src += 64 - r;
262
+ len -= 64 - r;
263
+
264
+ /* Perform complete blocks */
265
+ while (len >= 64) {
266
+ SHA256_Transform(ctx->state, src);
267
+ src += 64;
268
+ len -= 64;
269
+ }
270
+
271
+ /* Copy left over data into buffer */
272
+ memcpy(ctx->buf, src, len);
273
+ }
274
+
275
+ /*
276
+ * SHA-256 finalization. Pads the input data, exports the hash value,
277
+ * and clears the context state.
278
+ */
279
+ void
280
+ SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
281
+ {
282
+
283
+ /* Add padding */
284
+ SHA256_Pad(ctx);
285
+
286
+ /* Write the hash */
287
+ be32enc_vect(digest, ctx->state, 32);
288
+
289
+ /* Clear the context state */
290
+ memset((void *)ctx, 0, sizeof(*ctx));
291
+ }
292
+
293
+ /* Initialize an HMAC-SHA256 operation with the given key. */
294
+ void
295
+ HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
296
+ {
297
+ unsigned char pad[64];
298
+ unsigned char khash[32];
299
+ const unsigned char * K = _K;
300
+ size_t i;
301
+
302
+ /* If Klen > 64, the key is really SHA256(K). */
303
+ if (Klen > 64) {
304
+ SHA256_Init(&ctx->ictx);
305
+ SHA256_Update(&ctx->ictx, K, Klen);
306
+ SHA256_Final(khash, &ctx->ictx);
307
+ K = khash;
308
+ Klen = 32;
309
+ }
310
+
311
+ /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
312
+ SHA256_Init(&ctx->ictx);
313
+ memset(pad, 0x36, 64);
314
+ for (i = 0; i < Klen; i++)
315
+ pad[i] ^= K[i];
316
+ SHA256_Update(&ctx->ictx, pad, 64);
317
+
318
+ /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
319
+ SHA256_Init(&ctx->octx);
320
+ memset(pad, 0x5c, 64);
321
+ for (i = 0; i < Klen; i++)
322
+ pad[i] ^= K[i];
323
+ SHA256_Update(&ctx->octx, pad, 64);
324
+
325
+ /* Clean the stack. */
326
+ memset(khash, 0, 32);
327
+ }
328
+
329
+ /* Add bytes to the HMAC-SHA256 operation. */
330
+ void
331
+ HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
332
+ {
333
+
334
+ /* Feed data to the inner SHA256 operation. */
335
+ SHA256_Update(&ctx->ictx, in, len);
336
+ }
337
+
338
+ /* Finish an HMAC-SHA256 operation. */
339
+ void
340
+ HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
341
+ {
342
+ unsigned char ihash[32];
343
+
344
+ /* Finish the inner SHA256 operation. */
345
+ SHA256_Final(ihash, &ctx->ictx);
346
+
347
+ /* Feed the inner hash to the outer SHA256 operation. */
348
+ SHA256_Update(&ctx->octx, ihash, 32);
349
+
350
+ /* Finish the outer SHA256 operation. */
351
+ SHA256_Final(digest, &ctx->octx);
352
+
353
+ /* Clean the stack. */
354
+ memset(ihash, 0, 32);
355
+ }
356
+
357
+ /**
358
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
359
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
360
+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
361
+ */
362
+ void
363
+ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
364
+ size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
365
+ {
366
+ HMAC_SHA256_CTX PShctx, hctx;
367
+ size_t i;
368
+ uint8_t ivec[4];
369
+ uint8_t U[32];
370
+ uint8_t T[32];
371
+ uint64_t j;
372
+ int k;
373
+ size_t clen;
374
+
375
+ /* Compute HMAC state after processing P and S. */
376
+ HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
377
+ HMAC_SHA256_Update(&PShctx, salt, saltlen);
378
+
379
+ /* Iterate through the blocks. */
380
+ for (i = 0; i * 32 < dkLen; i++) {
381
+ /* Generate INT(i + 1). */
382
+ be32enc(ivec, (uint32_t)(i + 1));
383
+
384
+ /* Compute U_1 = PRF(P, S || INT(i)). */
385
+ memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
386
+ HMAC_SHA256_Update(&hctx, ivec, 4);
387
+ HMAC_SHA256_Final(U, &hctx);
388
+
389
+ /* T_i = U_1 ... */
390
+ memcpy(T, U, 32);
391
+
392
+ for (j = 2; j <= c; j++) {
393
+ /* Compute U_j. */
394
+ HMAC_SHA256_Init(&hctx, passwd, passwdlen);
395
+ HMAC_SHA256_Update(&hctx, U, 32);
396
+ HMAC_SHA256_Final(U, &hctx);
397
+
398
+ /* ... xor U_j ... */
399
+ for (k = 0; k < 32; k++)
400
+ T[k] ^= U[k];
401
+ }
402
+
403
+ /* Copy as many bytes as necessary into buf. */
404
+ clen = dkLen - i * 32;
405
+ if (clen > 32)
406
+ clen = 32;
407
+ memcpy(&buf[i * 32], T, clen);
408
+ }
409
+
410
+ /* Clean PShctx, since we never called _Final on it. */
411
+ memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
412
+ }