scrypty 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/extconf.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'mkmf'
2
+
3
+ have_library('rt', 'clock_gettime')
4
+ have_library('crypto', 'AES_set_encrypt_key')
5
+ %w{err.h fcntl.h inttypes.h memory.h stddef.h stdint.h stdlib.h string.h strings.h sys/endian.h sys/param.h sys/stat.h sys/time.h sys/types.h termios.h unistd.h}.each do |header|
6
+ have_header(header)
7
+ end
8
+ have_type('size_t')
9
+ have_type('ssize_t')
10
+ have_type('uint32_t')
11
+ have_type('uint64_t')
12
+ have_type('uint8_t')
13
+ if have_header('sys/sysinfo.h')
14
+ if have_type('struct sysinfo', 'sys/sysinfo.h')
15
+ have_struct_member('struct sysinfo', 'mem_unit', 'sys/sysinfo.h')
16
+ have_struct_member('struct sysinfo', 'totalram', 'sys/sysinfo.h')
17
+ end
18
+ end
19
+ have_func('malloc')
20
+ have_func('mmap')
21
+ have_func('strtod')
22
+ %w{clock_gettime gettimeofday memmove memset munmap posix_memalign strcspn strdup strerror strtoumax sysinfo}.each do |func|
23
+ have_func(func)
24
+ end
25
+ have_const('be64enc')
26
+
27
+ system("sysctl hw.usermem >/dev/null 2>/dev/null")
28
+ if $?.exitstatus == 0
29
+ $defs.push("-DHAVE_SYSCTL_HW_USERMEM=1")
30
+ end
31
+ create_header
32
+ create_makefile('scrypty_ext')
data/ext/memlimit.c ADDED
@@ -0,0 +1,302 @@
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/types.h>
32
+ #include <sys/resource.h>
33
+
34
+ #ifdef HAVE_SYS_PARAM_H
35
+ #include <sys/param.h>
36
+ #endif
37
+ #ifdef HAVE_SYSCTL_HW_USERMEM
38
+ #include <sys/sysctl.h>
39
+ #endif
40
+ #ifdef HAVE_SYS_SYSINFO_H
41
+ #include <sys/sysinfo.h>
42
+ #endif
43
+
44
+ #include <errno.h>
45
+ #include <stddef.h>
46
+ #include <stdint.h>
47
+ #include <unistd.h>
48
+
49
+ #ifdef DEBUG
50
+ #include <stdio.h>
51
+ #endif
52
+
53
+ #include "memlimit.h"
54
+
55
+ #ifdef HAVE_SYSCTL_HW_USERMEM
56
+ static int
57
+ memlimit_sysctl_hw_usermem(size_t * memlimit)
58
+ {
59
+ int mib[2];
60
+ uint8_t usermembuf[8];
61
+ size_t usermemlen = 8;
62
+ uint64_t usermem;
63
+
64
+ /* Ask the kernel how much RAM we have. */
65
+ mib[0] = CTL_HW;
66
+ mib[1] = HW_USERMEM;
67
+ if (sysctl(mib, 2, usermembuf, &usermemlen, NULL, 0))
68
+ return (1);
69
+
70
+ /*
71
+ * Parse as either a uint64_t or a uint32_t based on the length of
72
+ * output the kernel reports having copied out. It appears that all
73
+ * systems providing a sysctl interface for reading integers copy
74
+ * them out as system-endian values, so we don't need to worry about
75
+ * parsing them.
76
+ */
77
+ if (usermemlen == sizeof(uint64_t))
78
+ usermem = *(uint64_t *)usermembuf;
79
+ else if (usermemlen == sizeof(uint32_t))
80
+ usermem = *(uint32_t *)usermembuf;
81
+ else
82
+ return (1);
83
+
84
+ /* Return the sysctl value, but clamp to SIZE_MAX if necessary. */
85
+ #if UINT64_MAX > SIZE_MAX
86
+ if (usermem > SIZE_MAX)
87
+ *memlimit = SIZE_MAX;
88
+ else
89
+ *memlimit = usermem;
90
+ #else
91
+ *memlimit = usermem;
92
+ #endif
93
+
94
+ /* Success! */
95
+ return (0);
96
+ }
97
+ #endif
98
+
99
+ /* If we don't HAVE_STRUCT_SYSINFO, we can't use sysinfo. */
100
+ #ifndef HAVE_STRUCT_SYSINFO
101
+ #undef HAVE_SYSINFO
102
+ #endif
103
+
104
+ /* If we don't HAVE_STRUCT_SYSINFO_TOTALRAM, we can't use sysinfo. */
105
+ #ifndef HAVE_STRUCT_SYSINFO_TOTALRAM
106
+ #undef HAVE_SYSINFO
107
+ #endif
108
+
109
+ #ifdef HAVE_SYSINFO
110
+ static int
111
+ memlimit_sysinfo(size_t * memlimit)
112
+ {
113
+ struct sysinfo info;
114
+ uint64_t totalmem;
115
+
116
+ /* Get information from the kernel. */
117
+ if (sysinfo(&info))
118
+ return (1);
119
+ totalmem = info.totalram;
120
+
121
+ /* If we're on a modern kernel, adjust based on mem_unit. */
122
+ #ifdef HAVE_STRUCT_SYSINFO_MEM_UNIT
123
+ totalmem = totalmem * info.mem_unit;
124
+ #endif
125
+
126
+ /* Return the value, but clamp to SIZE_MAX if necessary. */
127
+ #if UINT64_MAX > SIZE_MAX
128
+ if (totalmem > SIZE_MAX)
129
+ *memlimit = SIZE_MAX;
130
+ else
131
+ *memlimit = totalmem;
132
+ #else
133
+ *memlimit = totalmem;
134
+ #endif
135
+
136
+ /* Success! */
137
+ return (0);
138
+ }
139
+ #endif /* HAVE_SYSINFO */
140
+
141
+ static int
142
+ memlimit_rlimit(size_t * memlimit)
143
+ {
144
+ struct rlimit rl;
145
+ uint64_t memrlimit;
146
+
147
+ /* Find the least of... */
148
+ memrlimit = (uint64_t)(-1);
149
+
150
+ /* ... RLIMIT_AS... */
151
+ #ifdef RLIMIT_AS
152
+ if (getrlimit(RLIMIT_AS, &rl))
153
+ return (1);
154
+ if ((rl.rlim_cur != RLIM_INFINITY) &&
155
+ ((uint64_t)rl.rlim_cur < memrlimit))
156
+ memrlimit = rl.rlim_cur;
157
+ #endif
158
+
159
+ /* ... RLIMIT_DATA... */
160
+ if (getrlimit(RLIMIT_DATA, &rl))
161
+ return (1);
162
+ if ((rl.rlim_cur != RLIM_INFINITY) &&
163
+ ((uint64_t)rl.rlim_cur < memrlimit))
164
+ memrlimit = rl.rlim_cur;
165
+
166
+ /* ... and RLIMIT_RSS. */
167
+ #ifdef RLIMIT_RSS
168
+ if (getrlimit(RLIMIT_RSS, &rl))
169
+ return (1);
170
+ if ((rl.rlim_cur != RLIM_INFINITY) &&
171
+ ((uint64_t)rl.rlim_cur < memrlimit))
172
+ memrlimit = rl.rlim_cur;
173
+ #endif
174
+
175
+ /* Return the value, but clamp to SIZE_MAX if necessary. */
176
+ #if UINT64_MAX > SIZE_MAX
177
+ if (memrlimit > SIZE_MAX)
178
+ *memlimit = SIZE_MAX;
179
+ else
180
+ *memlimit = memrlimit;
181
+ #else
182
+ *memlimit = memrlimit;
183
+ #endif
184
+
185
+ /* Success! */
186
+ return (0);
187
+ }
188
+
189
+ #ifdef _SC_PHYS_PAGES
190
+
191
+ /* Some systems define _SC_PAGESIZE instead of _SC_PAGE_SIZE. */
192
+ #ifndef _SC_PAGE_SIZE
193
+ #define _SC_PAGE_SIZE _SC_PAGESIZE
194
+ #endif
195
+
196
+ static int
197
+ memlimit_sysconf(size_t * memlimit)
198
+ {
199
+ long pagesize;
200
+ long physpages;
201
+ uint64_t totalmem;
202
+
203
+ /* Set errno to 0 in order to distinguish "no limit" from "error". */
204
+ errno = 0;
205
+
206
+ /* Read the two limits. */
207
+ if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) ||
208
+ ((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) {
209
+ /* Did an error occur? */
210
+ if (errno != 0)
211
+ return (1);
212
+
213
+ /* If not, there is no limit. */
214
+ totalmem = (uint64_t)(-1);
215
+ } else {
216
+ /* Compute the limit. */
217
+ totalmem = (uint64_t)(pagesize) * (uint64_t)(physpages);
218
+ }
219
+
220
+ /* Return the value, but clamp to SIZE_MAX if necessary. */
221
+ #if UINT64_MAX > SIZE_MAX
222
+ if (totalmem > SIZE_MAX)
223
+ *memlimit = SIZE_MAX;
224
+ else
225
+ *memlimit = totalmem;
226
+ #else
227
+ *memlimit = totalmem;
228
+ #endif
229
+
230
+ /* Success! */
231
+ return (0);
232
+ }
233
+ #endif
234
+
235
+ int
236
+ memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit)
237
+ {
238
+ size_t sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit;
239
+ size_t sysconf_memlimit;
240
+ size_t memlimit_min;
241
+ size_t memavail;
242
+
243
+ /* Get memory limits. */
244
+ #ifdef HAVE_SYSCTL_HW_USERMEM
245
+ if (memlimit_sysctl_hw_usermem(&sysctl_memlimit))
246
+ return (1);
247
+ #else
248
+ sysctl_memlimit = (size_t)(-1);
249
+ #endif
250
+ #ifdef HAVE_SYSINFO
251
+ if (memlimit_sysinfo(&sysinfo_memlimit))
252
+ return (1);
253
+ #else
254
+ sysinfo_memlimit = (size_t)(-1);
255
+ #endif
256
+ if (memlimit_rlimit(&rlimit_memlimit))
257
+ return (1);
258
+ #ifdef _SC_PHYS_PAGES
259
+ if (memlimit_sysconf(&sysconf_memlimit))
260
+ return (1);
261
+ #else
262
+ sysconf_memlimit = (size_t)(-1);
263
+ #endif
264
+
265
+ #ifdef DEBUG
266
+ fprintf(stderr, "Memory limits are %zu %zu %zu %zu\n",
267
+ sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit,
268
+ sysconf_memlimit);
269
+ #endif
270
+
271
+ /* Find the smallest of them. */
272
+ memlimit_min = (size_t)(-1);
273
+ if (memlimit_min > sysctl_memlimit)
274
+ memlimit_min = sysctl_memlimit;
275
+ if (memlimit_min > sysinfo_memlimit)
276
+ memlimit_min = sysinfo_memlimit;
277
+ if (memlimit_min > rlimit_memlimit)
278
+ memlimit_min = rlimit_memlimit;
279
+ if (memlimit_min > sysconf_memlimit)
280
+ memlimit_min = sysconf_memlimit;
281
+
282
+ /* Only use the specified fraction of the available memory. */
283
+ if ((maxmemfrac > 0.5) || (maxmemfrac == 0.0))
284
+ maxmemfrac = 0.5;
285
+ memavail = maxmemfrac * memlimit_min;
286
+
287
+ /* Don't use more than the specified maximum. */
288
+ if ((maxmem > 0) && (memavail > maxmem))
289
+ memavail = maxmem;
290
+
291
+ /* But always allow at least 1 MiB. */
292
+ if (memavail < 1048576)
293
+ memavail = 1048576;
294
+
295
+ #ifdef DEBUG
296
+ fprintf(stderr, "Allowing up to %zu memory to be used\n", memavail);
297
+ #endif
298
+
299
+ /* Return limit via the provided pointer. */
300
+ *memlimit = memavail;
301
+ return (0);
302
+ }
data/ext/memlimit.h ADDED
@@ -0,0 +1,42 @@
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 _MEMLIMIT_H_
30
+ #define _MEMLIMIT_H_
31
+
32
+ #include <stddef.h>
33
+
34
+ /**
35
+ * memtouse(maxmem, maxmemfrac, memlimit):
36
+ * Examine the system and return via memlimit the amount of RAM which should
37
+ * be used -- the specified fraction of the available RAM, but no more than
38
+ * maxmem, and no less than 1MiB.
39
+ */
40
+ int memtouse(size_t, double, size_t *);
41
+
42
+ #endif /* !_MEMLIMIT_H_ */
data/ext/ruby_ext.c ADDED
@@ -0,0 +1,239 @@
1
+ #include <ruby.h>
2
+ #include <stdio.h>
3
+ #include "scryptenc.h"
4
+
5
+ VALUE mScrypty;
6
+
7
+ VALUE eScryptyError;
8
+ VALUE eMemoryLimitError;
9
+ VALUE eClockTimeError;
10
+ VALUE eDerivedKeyError;
11
+ VALUE eSaltError;
12
+ VALUE eOpenSSLError;
13
+ /* Use NoMemoryError */
14
+ VALUE eInvalidBlockError;
15
+ VALUE eUnrecognizedFormatError;
16
+ VALUE eNotEnoughMemoryError;
17
+ VALUE eTooMuchTimeError;
18
+ VALUE eIncorrectPasswordError;
19
+ VALUE eWriteError;
20
+ VALUE eReadError;
21
+
22
+ /**
23
+ * Return codes from scrypt(enc|dec)_(buf|file):
24
+ * 0 success
25
+ * 1 getrlimit or sysctl(hw.usermem) failed
26
+ * 2 clock_getres or clock_gettime failed
27
+ * 3 error computing derived key
28
+ * 4 could not read salt from /dev/urandom
29
+ * 5 error in OpenSSL
30
+ * 6 malloc failed
31
+ * 7 data is not a valid scrypt-encrypted block
32
+ * 8 unrecognized scrypt format
33
+ * 9 decrypting file would take too much memory
34
+ * 10 decrypting file would take too long
35
+ * 11 password is incorrect
36
+ * 12 error writing output file
37
+ * 13 error reading input file
38
+ */
39
+ static void
40
+ raise_scrypty_error(errorcode)
41
+ int errorcode;
42
+ {
43
+ switch (errorcode) {
44
+ case 1:
45
+ rb_raise(eMemoryLimitError, "couldn't get memory limit");
46
+ break;
47
+ case 2:
48
+ rb_raise(eClockTimeError, "couldn't determine CPU speed");
49
+ break;
50
+ case 3:
51
+ rb_raise(eDerivedKeyError, "couldn't compute derived key");
52
+ break;
53
+ case 4:
54
+ rb_raise(eSaltError, "couldn't read salt from /dev/urandom");
55
+ break;
56
+ case 5:
57
+ rb_raise(eOpenSSLError, "OpenSSL error");
58
+ break;
59
+ case 6:
60
+ rb_raise(rb_eNoMemError, "couldn't allocate memory");
61
+ break;
62
+ case 7:
63
+ rb_raise(eInvalidBlockError, "data is not a valid scrypt-encrypted block");
64
+ break;
65
+ case 8:
66
+ rb_raise(eUnrecognizedFormatError, "unrecognized scrypt format");
67
+ break;
68
+ case 9:
69
+ rb_raise(eNotEnoughMemoryError, "decrypting would take too much memory");
70
+ break;
71
+ case 10:
72
+ rb_raise(eTooMuchTimeError, "decrypting would take too long");
73
+ break;
74
+ case 11:
75
+ rb_raise(eIncorrectPasswordError, "password is incorrect");
76
+ break;
77
+ case 12:
78
+ rb_raise(eWriteError, "error writing output file");
79
+ break;
80
+ case 13:
81
+ rb_raise(eReadError, "error reading input file");
82
+ break;
83
+ }
84
+ }
85
+
86
+ VALUE
87
+ scrypty_encrypt(rb_obj, rb_data, rb_password, rb_maxmem, rb_maxmemfrac, rb_maxtime)
88
+ VALUE rb_obj;
89
+ VALUE rb_data;
90
+ VALUE rb_password;
91
+ VALUE rb_maxmem;
92
+ VALUE rb_maxmemfrac;
93
+ VALUE rb_maxtime;
94
+ {
95
+ VALUE rb_out;
96
+ char *data, *password, *out;
97
+ size_t data_len, password_len, out_len, maxmem;
98
+ double maxmemfrac, maxtime;
99
+ int errorcode;
100
+
101
+ if (TYPE(rb_data) == T_STRING) {
102
+ data = RSTRING_PTR(rb_data);
103
+ data_len = (size_t) RSTRING_LEN(rb_data);
104
+ }
105
+ else {
106
+ rb_raise(rb_eTypeError, "first argument (data) must be a String");
107
+ }
108
+
109
+ if (TYPE(rb_password) == T_STRING) {
110
+ password = RSTRING_PTR(rb_password);
111
+ password_len = (size_t) RSTRING_LEN(rb_password);
112
+ }
113
+ else {
114
+ rb_raise(rb_eTypeError, "second argument (password) must be a String");
115
+ }
116
+
117
+ if (TYPE(rb_maxmem) == T_FIXNUM) {
118
+ maxmem = FIX2INT(rb_maxmem);
119
+ }
120
+ else {
121
+ rb_raise(rb_eTypeError, "third argument (maxmem) must be a Fixnum");
122
+ }
123
+
124
+ if (FIXNUM_P(rb_maxmemfrac) || TYPE(rb_maxmemfrac) == T_FLOAT) {
125
+ maxmemfrac = NUM2DBL(rb_maxmemfrac);
126
+ }
127
+ else {
128
+ rb_raise(rb_eTypeError, "fourth argument (maxmemfrac) must be a Fixnum or Float");
129
+ }
130
+
131
+ if (FIXNUM_P(rb_maxtime) || TYPE(rb_maxtime) == T_FLOAT) {
132
+ maxtime = NUM2DBL(rb_maxtime);
133
+ }
134
+ else {
135
+ rb_raise(rb_eTypeError, "fifth argument (maxtime) must be a Fixnum or Float");
136
+ }
137
+
138
+ out_len = data_len + 128;
139
+ rb_out = rb_str_new(NULL, out_len);
140
+ out = RSTRING_PTR(rb_out);
141
+
142
+ errorcode = scryptenc_buf((const uint8_t *) data, data_len,
143
+ (uint8_t *) out, (const uint8_t *) password, password_len,
144
+ maxmem, maxmemfrac, maxtime);
145
+ if (errorcode) {
146
+ raise_scrypt_error(errorcode);
147
+ }
148
+ rb_str_set_len(rb_out, out_len);
149
+
150
+ return rb_out;
151
+ }
152
+
153
+ VALUE
154
+ scrypty_decrypt(rb_obj, rb_data, rb_password, rb_maxmem, rb_maxmemfrac, rb_maxtime)
155
+ VALUE rb_obj;
156
+ VALUE rb_data;
157
+ VALUE rb_password;
158
+ VALUE rb_maxmem;
159
+ VALUE rb_maxmemfrac;
160
+ VALUE rb_maxtime;
161
+ {
162
+ VALUE rb_out;
163
+ char *data, *password, *out;
164
+ size_t data_len, password_len, out_len, maxmem;
165
+ double maxmemfrac, maxtime;
166
+ int errorcode;
167
+
168
+ if (TYPE(rb_data) == T_STRING) {
169
+ data = RSTRING_PTR(rb_data);
170
+ data_len = (size_t) RSTRING_LEN(rb_data);
171
+ }
172
+ else {
173
+ rb_raise(rb_eTypeError, "first argument (data) must be a String");
174
+ }
175
+
176
+ if (TYPE(rb_password) == T_STRING) {
177
+ password = RSTRING_PTR(rb_password);
178
+ password_len = (size_t) RSTRING_LEN(rb_password);
179
+ }
180
+ else {
181
+ rb_raise(rb_eTypeError, "second argument (password) must be a String");
182
+ }
183
+
184
+ if (TYPE(rb_maxmem) == T_FIXNUM) {
185
+ maxmem = FIX2INT(rb_maxmem);
186
+ }
187
+ else {
188
+ rb_raise(rb_eTypeError, "third argument (maxmem) must be a Fixnum");
189
+ }
190
+
191
+ if (FIXNUM_P(rb_maxmemfrac) || TYPE(rb_maxmemfrac) == T_FLOAT) {
192
+ maxmemfrac = NUM2DBL(rb_maxmemfrac);
193
+ }
194
+ else {
195
+ rb_raise(rb_eTypeError, "fourth argument (maxmemfrac) must be a Fixnum or Float");
196
+ }
197
+
198
+ if (FIXNUM_P(rb_maxtime) || TYPE(rb_maxtime) == T_FLOAT) {
199
+ maxtime = NUM2DBL(rb_maxtime);
200
+ }
201
+ else {
202
+ rb_raise(rb_eTypeError, "fifth argument (maxtime) must be a Fixnum or Float");
203
+ }
204
+
205
+ rb_out = rb_str_new(NULL, data_len);
206
+ out = RSTRING_PTR(rb_out);
207
+
208
+ errorcode = scryptdec_buf((const uint8_t *) data, data_len,
209
+ (uint8_t *) out, &out_len, (const uint8_t *) password, password_len,
210
+ maxmem, maxmemfrac, maxtime);
211
+ if (errorcode) {
212
+ raise_scrypty_error(errorcode);
213
+ }
214
+ rb_str_set_len(rb_out, out_len);
215
+
216
+ return rb_out;
217
+ }
218
+
219
+ void
220
+ Init_scrypty_ext(void)
221
+ {
222
+ mScrypty = rb_define_module("Scrypty");
223
+ rb_define_singleton_method(mScrypty, "encrypt", scrypty_encrypt, 5);
224
+ rb_define_singleton_method(mScrypty, "decrypt", scrypty_decrypt, 5);
225
+
226
+ eScryptyError = rb_define_class_under(mScrypty, "Exception", rb_eException);
227
+ eMemoryLimitError = rb_define_class_under(mScrypty, "MemoryLimitError", eScryptyError);
228
+ eClockTimeError = rb_define_class_under(mScrypty, "ClockTimeError", eScryptyError);
229
+ eDerivedKeyError = rb_define_class_under(mScrypty, "DerivedKeyError", eScryptyError);
230
+ eSaltError = rb_define_class_under(mScrypty, "SaltError", eScryptyError);
231
+ eOpenSSLError = rb_define_class_under(mScrypty, "OpenSSLError", eScryptyError);
232
+ eInvalidBlockError = rb_define_class_under(mScrypty, "InvalidBlockError", eScryptyError);
233
+ eUnrecognizedFormatError = rb_define_class_under(mScrypty, "UnrecognizedFormatError", eScryptyError);
234
+ eNotEnoughMemoryError = rb_define_class_under(mScrypty, "NotEnoughMemoryError", eScryptyError);
235
+ eTooMuchTimeError = rb_define_class_under(mScrypty, "TooMuchTimeError", eScryptyError);
236
+ eIncorrectPasswordError = rb_define_class_under(mScrypty, "IncorrectPasswordError", eScryptyError);
237
+ eWriteError = rb_define_class_under(mScrypty, "WriteError", eScryptyError);
238
+ eReadError = rb_define_class_under(mScrypty, "ReadError", eScryptyError);
239
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef _SCRYPT_PLATFORM_H_
2
+ #define _SCRYPT_PLATFORM_H_
3
+
4
+ #include "extconf.h"
5
+
6
+ #endif /* !_SCRYPT_PLATFORM_H_ */