scrypty 0.0.1
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.
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/ext/crypto_aesctr.c +124 -0
- data/ext/crypto_aesctr.h +59 -0
- data/ext/crypto_scrypt-nosse.c.orig +338 -0
- data/ext/crypto_scrypt-ref.c +284 -0
- data/ext/crypto_scrypt-sse.c.orig +366 -0
- data/ext/crypto_scrypt.h +46 -0
- data/ext/extconf.rb +32 -0
- data/ext/memlimit.c +302 -0
- data/ext/memlimit.h +42 -0
- data/ext/ruby_ext.c +239 -0
- data/ext/scrypt_platform.h +6 -0
- data/ext/scryptenc.c +606 -0
- data/ext/scryptenc.h +112 -0
- data/ext/scryptenc_cpuperf.c +185 -0
- data/ext/scryptenc_cpuperf.h +39 -0
- data/ext/sha256.c +412 -0
- data/ext/sha256.h +62 -0
- data/ext/sysendian.h +140 -0
- data/lib/scrypty/version.rb +3 -0
- data/lib/scrypty.rb +2 -0
- data/scrypty.gemspec +20 -0
- metadata +73 -0
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
|
+
}
|