scrypty 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/scryptenc.c ADDED
@@ -0,0 +1,606 @@
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 <errno.h>
32
+ #include <fcntl.h>
33
+ #include <stdint.h>
34
+ #include <stdio.h>
35
+ #include <string.h>
36
+ #include <unistd.h>
37
+
38
+ #include <openssl/aes.h>
39
+
40
+ #include "crypto_aesctr.h"
41
+ #include "crypto_scrypt.h"
42
+ #include "memlimit.h"
43
+ #include "scryptenc_cpuperf.h"
44
+ #include "sha256.h"
45
+ #include "sysendian.h"
46
+
47
+ #include "scryptenc.h"
48
+
49
+ #define ENCBLOCK 65536
50
+
51
+ static int pickparams(size_t, double, double,
52
+ int *, uint32_t *, uint32_t *);
53
+ static int checkparams(size_t, double, double, int, uint32_t, uint32_t);
54
+ static int getsalt(uint8_t[32]);
55
+
56
+ static int
57
+ pickparams(size_t maxmem, double maxmemfrac, double maxtime,
58
+ int * logN, uint32_t * r, uint32_t * p)
59
+ {
60
+ size_t memlimit;
61
+ double opps;
62
+ double opslimit;
63
+ double maxN, maxrp;
64
+ int rc;
65
+
66
+ /* Figure out how much memory to use. */
67
+ if (memtouse(maxmem, maxmemfrac, &memlimit))
68
+ return (1);
69
+
70
+ /* Figure out how fast the CPU is. */
71
+ if ((rc = scryptenc_cpuperf(&opps)) != 0)
72
+ return (rc);
73
+ opslimit = opps * maxtime;
74
+
75
+ /* Allow a minimum of 2^15 salsa20/8 cores. */
76
+ if (opslimit < 32768)
77
+ opslimit = 32768;
78
+
79
+ /* Fix r = 8 for now. */
80
+ *r = 8;
81
+
82
+ /*
83
+ * The memory limit requires that 128Nr <= memlimit, while the CPU
84
+ * limit requires that 4Nrp <= opslimit. If opslimit < memlimit/32,
85
+ * opslimit imposes the stronger limit on N.
86
+ */
87
+ #ifdef DEBUG
88
+ fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n",
89
+ memlimit, opslimit);
90
+ #endif
91
+ if (opslimit < memlimit/32) {
92
+ /* Set p = 1 and choose N based on the CPU limit. */
93
+ *p = 1;
94
+ maxN = opslimit / (*r * 4);
95
+ for (*logN = 1; *logN < 63; *logN += 1) {
96
+ if ((uint64_t)(1) << *logN > maxN / 2)
97
+ break;
98
+ }
99
+ } else {
100
+ /* Set N based on the memory limit. */
101
+ maxN = memlimit / (*r * 128);
102
+ for (*logN = 1; *logN < 63; *logN += 1) {
103
+ if ((uint64_t)(1) << *logN > maxN / 2)
104
+ break;
105
+ }
106
+
107
+ /* Choose p based on the CPU limit. */
108
+ maxrp = (opslimit / 4) / ((uint64_t)(1) << *logN);
109
+ if (maxrp > 0x3fffffff)
110
+ maxrp = 0x3fffffff;
111
+ *p = (uint32_t)(maxrp) / *r;
112
+ }
113
+
114
+ #ifdef DEBUG
115
+ fprintf(stderr, "N = %zu r = %d p = %d\n",
116
+ (size_t)(1) << *logN, (int)(*r), (int)(*p));
117
+ #endif
118
+
119
+ /* Success! */
120
+ return (0);
121
+ }
122
+
123
+ static int
124
+ checkparams(size_t maxmem, double maxmemfrac, double maxtime,
125
+ int logN, uint32_t r, uint32_t p)
126
+ {
127
+ size_t memlimit;
128
+ double opps;
129
+ double opslimit;
130
+ uint64_t N;
131
+ int rc;
132
+
133
+ /* Figure out the maximum amount of memory we can use. */
134
+ if (memtouse(maxmem, maxmemfrac, &memlimit))
135
+ return (1);
136
+
137
+ /* Figure out how fast the CPU is. */
138
+ if ((rc = scryptenc_cpuperf(&opps)) != 0)
139
+ return (rc);
140
+ opslimit = opps * maxtime;
141
+
142
+ /* Sanity-check values. */
143
+ if ((logN < 1) || (logN > 63))
144
+ return (7);
145
+ if ((uint64_t)(r) * (uint64_t)(p) >= 0x40000000)
146
+ return (7);
147
+
148
+ /* Check limits. */
149
+ N = (uint64_t)(1) << logN;
150
+ if ((memlimit / N) / r < 128)
151
+ return (9);
152
+ if ((opslimit / N) / (r * p) < 4)
153
+ return (10);
154
+
155
+ /* Success! */
156
+ return (0);
157
+ }
158
+
159
+ static int
160
+ getsalt(uint8_t salt[32])
161
+ {
162
+ int fd;
163
+ ssize_t lenread;
164
+ uint8_t * buf = salt;
165
+ size_t buflen = 32;
166
+
167
+ /* Open /dev/urandom. */
168
+ if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
169
+ goto err0;
170
+
171
+ /* Read bytes until we have filled the buffer. */
172
+ while (buflen > 0) {
173
+ if ((lenread = read(fd, buf, buflen)) == -1)
174
+ goto err1;
175
+
176
+ /* The random device should never EOF. */
177
+ if (lenread == 0)
178
+ goto err1;
179
+
180
+ /* We're partly done. */
181
+ buf += lenread;
182
+ buflen -= lenread;
183
+ }
184
+
185
+ /* Close the device. */
186
+ while (close(fd) == -1) {
187
+ if (errno != EINTR)
188
+ goto err0;
189
+ }
190
+
191
+ /* Success! */
192
+ return (0);
193
+
194
+ err1:
195
+ close(fd);
196
+ err0:
197
+ /* Failure! */
198
+ return (4);
199
+ }
200
+
201
+ static int
202
+ scryptenc_setup(uint8_t header[96], uint8_t dk[64],
203
+ const uint8_t * passwd, size_t passwdlen,
204
+ size_t maxmem, double maxmemfrac, double maxtime)
205
+ {
206
+ uint8_t salt[32];
207
+ uint8_t hbuf[32];
208
+ int logN;
209
+ uint64_t N;
210
+ uint32_t r;
211
+ uint32_t p;
212
+ SHA256_CTX ctx;
213
+ uint8_t * key_hmac = &dk[32];
214
+ HMAC_SHA256_CTX hctx;
215
+ int rc;
216
+
217
+ /* Pick values for N, r, p. */
218
+ if ((rc = pickparams(maxmem, maxmemfrac, maxtime,
219
+ &logN, &r, &p)) != 0)
220
+ return (rc);
221
+ N = (uint64_t)(1) << logN;
222
+
223
+ /* Get some salt. */
224
+ if ((rc = getsalt(salt)) != 0)
225
+ return (rc);
226
+
227
+ /* Generate the derived keys. */
228
+ if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
229
+ return (3);
230
+
231
+ /* Construct the file header. */
232
+ memcpy(header, "scrypt", 6);
233
+ header[6] = 0;
234
+ header[7] = logN;
235
+ be32enc(&header[8], r);
236
+ be32enc(&header[12], p);
237
+ memcpy(&header[16], salt, 32);
238
+
239
+ /* Add header checksum. */
240
+ SHA256_Init(&ctx);
241
+ SHA256_Update(&ctx, header, 48);
242
+ SHA256_Final(hbuf, &ctx);
243
+ memcpy(&header[48], hbuf, 16);
244
+
245
+ /* Add header signature (used for verifying password). */
246
+ HMAC_SHA256_Init(&hctx, key_hmac, 32);
247
+ HMAC_SHA256_Update(&hctx, header, 64);
248
+ HMAC_SHA256_Final(hbuf, &hctx);
249
+ memcpy(&header[64], hbuf, 32);
250
+
251
+ /* Success! */
252
+ return (0);
253
+ }
254
+
255
+ static int
256
+ scryptdec_setup(const uint8_t header[96], uint8_t dk[64],
257
+ const uint8_t * passwd, size_t passwdlen,
258
+ size_t maxmem, double maxmemfrac, double maxtime)
259
+ {
260
+ uint8_t salt[32];
261
+ uint8_t hbuf[32];
262
+ int logN;
263
+ uint32_t r;
264
+ uint32_t p;
265
+ uint64_t N;
266
+ SHA256_CTX ctx;
267
+ uint8_t * key_hmac = &dk[32];
268
+ HMAC_SHA256_CTX hctx;
269
+ int rc;
270
+
271
+ /* Parse N, r, p, salt. */
272
+ logN = header[7];
273
+ r = be32dec(&header[8]);
274
+ p = be32dec(&header[12]);
275
+ memcpy(salt, &header[16], 32);
276
+
277
+ /* Verify header checksum. */
278
+ SHA256_Init(&ctx);
279
+ SHA256_Update(&ctx, header, 48);
280
+ SHA256_Final(hbuf, &ctx);
281
+ if (memcmp(&header[48], hbuf, 16))
282
+ return (7);
283
+
284
+ /*
285
+ * Check whether the provided parameters are valid and whether the
286
+ * key derivation function can be computed within the allowed memory
287
+ * and CPU time.
288
+ */
289
+ if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p)) != 0)
290
+ return (rc);
291
+
292
+ /* Compute the derived keys. */
293
+ N = (uint64_t)(1) << logN;
294
+ if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
295
+ return (3);
296
+
297
+ /* Check header signature (i.e., verify password). */
298
+ HMAC_SHA256_Init(&hctx, key_hmac, 32);
299
+ HMAC_SHA256_Update(&hctx, header, 64);
300
+ HMAC_SHA256_Final(hbuf, &hctx);
301
+ if (memcmp(hbuf, &header[64], 32))
302
+ return (11);
303
+
304
+ /* Success! */
305
+ return (0);
306
+ }
307
+
308
+ /**
309
+ * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
310
+ * maxmem, maxmemfrac, maxtime):
311
+ * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
312
+ * bytes to outbuf.
313
+ */
314
+ int
315
+ scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
316
+ const uint8_t * passwd, size_t passwdlen,
317
+ size_t maxmem, double maxmemfrac, double maxtime)
318
+ {
319
+ uint8_t dk[64];
320
+ uint8_t hbuf[32];
321
+ uint8_t header[96];
322
+ uint8_t * key_enc = dk;
323
+ uint8_t * key_hmac = &dk[32];
324
+ int rc;
325
+ HMAC_SHA256_CTX hctx;
326
+ AES_KEY key_enc_exp;
327
+ struct crypto_aesctr * AES;
328
+
329
+ /* Generate the header and derived key. */
330
+ if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
331
+ maxmem, maxmemfrac, maxtime)) != 0)
332
+ return (rc);
333
+
334
+ /* Copy header into output buffer. */
335
+ memcpy(outbuf, header, 96);
336
+
337
+ /* Encrypt data. */
338
+ if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp))
339
+ return (5);
340
+ if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL)
341
+ return (6);
342
+ crypto_aesctr_stream(AES, inbuf, &outbuf[96], inbuflen);
343
+ crypto_aesctr_free(AES);
344
+
345
+ /* Add signature. */
346
+ HMAC_SHA256_Init(&hctx, key_hmac, 32);
347
+ HMAC_SHA256_Update(&hctx, outbuf, 96 + inbuflen);
348
+ HMAC_SHA256_Final(hbuf, &hctx);
349
+ memcpy(&outbuf[96 + inbuflen], hbuf, 32);
350
+
351
+ /* Zero sensitive data. */
352
+ memset(dk, 0, 64);
353
+ memset(&key_enc_exp, 0, sizeof(AES_KEY));
354
+
355
+ /* Success! */
356
+ return (0);
357
+ }
358
+
359
+ /**
360
+ * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
361
+ * maxmem, maxmemfrac, maxtime):
362
+ * Decrypt inbuflen bytes fro inbuf, writing the result into outbuf and the
363
+ * decrypted data length to outlen. The allocated length of outbuf must
364
+ * be at least inbuflen.
365
+ */
366
+ int
367
+ scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
368
+ size_t * outlen, const uint8_t * passwd, size_t passwdlen,
369
+ size_t maxmem, double maxmemfrac, double maxtime)
370
+ {
371
+ uint8_t hbuf[32];
372
+ uint8_t dk[64];
373
+ uint8_t * key_enc = dk;
374
+ uint8_t * key_hmac = &dk[32];
375
+ int rc;
376
+ HMAC_SHA256_CTX hctx;
377
+ AES_KEY key_enc_exp;
378
+ struct crypto_aesctr * AES;
379
+
380
+ /*
381
+ * All versions of the scrypt format will start with "scrypt" and
382
+ * have at least 7 bytes of header.
383
+ */
384
+ if ((inbuflen < 7) || (memcmp(inbuf, "scrypt", 6) != 0))
385
+ return (7);
386
+
387
+ /* Check the format. */
388
+ if (inbuf[6] != 0)
389
+ return (8);
390
+
391
+ /* We must have at least 128 bytes. */
392
+ if (inbuflen < 128)
393
+ return (7);
394
+
395
+ /* Parse the header and generate derived keys. */
396
+ if ((rc = scryptdec_setup(inbuf, dk, passwd, passwdlen,
397
+ maxmem, maxmemfrac, maxtime)) != 0)
398
+ return (rc);
399
+
400
+ /* Decrypt data. */
401
+ if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp))
402
+ return (5);
403
+ if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL)
404
+ return (6);
405
+ crypto_aesctr_stream(AES, &inbuf[96], outbuf, inbuflen - 128);
406
+ crypto_aesctr_free(AES);
407
+ *outlen = inbuflen - 128;
408
+
409
+ /* Verify signature. */
410
+ HMAC_SHA256_Init(&hctx, key_hmac, 32);
411
+ HMAC_SHA256_Update(&hctx, inbuf, inbuflen - 32);
412
+ HMAC_SHA256_Final(hbuf, &hctx);
413
+ if (memcmp(hbuf, &inbuf[inbuflen - 32], 32))
414
+ return (7);
415
+
416
+ /* Zero sensitive data. */
417
+ memset(dk, 0, 64);
418
+ memset(&key_enc_exp, 0, sizeof(AES_KEY));
419
+
420
+ /* Success! */
421
+ return (0);
422
+ }
423
+
424
+ /**
425
+ * scryptenc_file(infile, outfile, passwd, passwdlen,
426
+ * maxmem, maxmemfrac, maxtime):
427
+ * Read a stream from infile and encrypt it, writing the resulting stream to
428
+ * outfile.
429
+ */
430
+ int
431
+ scryptenc_file(FILE * infile, FILE * outfile,
432
+ const uint8_t * passwd, size_t passwdlen,
433
+ size_t maxmem, double maxmemfrac, double maxtime)
434
+ {
435
+ uint8_t buf[ENCBLOCK];
436
+ uint8_t dk[64];
437
+ uint8_t hbuf[32];
438
+ uint8_t header[96];
439
+ uint8_t * key_enc = dk;
440
+ uint8_t * key_hmac = &dk[32];
441
+ size_t readlen;
442
+ HMAC_SHA256_CTX hctx;
443
+ AES_KEY key_enc_exp;
444
+ struct crypto_aesctr * AES;
445
+ int rc;
446
+
447
+ /* Generate the header and derived key. */
448
+ if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
449
+ maxmem, maxmemfrac, maxtime)) != 0)
450
+ return (rc);
451
+
452
+ /* Hash and write the header. */
453
+ HMAC_SHA256_Init(&hctx, key_hmac, 32);
454
+ HMAC_SHA256_Update(&hctx, header, 96);
455
+ if (fwrite(header, 96, 1, outfile) != 1)
456
+ return (12);
457
+
458
+ /*
459
+ * Read blocks of data, encrypt them, and write them out; hash the
460
+ * data as it is produced.
461
+ */
462
+ if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp))
463
+ return (5);
464
+ if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL)
465
+ return (6);
466
+ do {
467
+ if ((readlen = fread(buf, 1, ENCBLOCK, infile)) == 0)
468
+ break;
469
+ crypto_aesctr_stream(AES, buf, buf, readlen);
470
+ HMAC_SHA256_Update(&hctx, buf, readlen);
471
+ if (fwrite(buf, 1, readlen, outfile) < readlen)
472
+ return (12);
473
+ } while (1);
474
+ crypto_aesctr_free(AES);
475
+
476
+ /* Did we exit the loop due to a read error? */
477
+ if (ferror(infile))
478
+ return (13);
479
+
480
+ /* Compute the final HMAC and output it. */
481
+ HMAC_SHA256_Final(hbuf, &hctx);
482
+ if (fwrite(hbuf, 32, 1, outfile) != 1)
483
+ return (12);
484
+
485
+ /* Zero sensitive data. */
486
+ memset(dk, 0, 64);
487
+ memset(&key_enc_exp, 0, sizeof(AES_KEY));
488
+
489
+ /* Success! */
490
+ return (0);
491
+ }
492
+
493
+ /**
494
+ * scryptdec_file(infile, outfile, passwd, passwdlen,
495
+ * maxmem, maxmemfrac, maxtime):
496
+ * Read a stream from infile and decrypt it, writing the resulting stream to
497
+ * outfile.
498
+ */
499
+ int
500
+ scryptdec_file(FILE * infile, FILE * outfile,
501
+ const uint8_t * passwd, size_t passwdlen,
502
+ size_t maxmem, double maxmemfrac, double maxtime)
503
+ {
504
+ uint8_t buf[ENCBLOCK + 32];
505
+ uint8_t header[96];
506
+ uint8_t hbuf[32];
507
+ uint8_t dk[64];
508
+ uint8_t * key_enc = dk;
509
+ uint8_t * key_hmac = &dk[32];
510
+ size_t buflen = 0;
511
+ size_t readlen;
512
+ HMAC_SHA256_CTX hctx;
513
+ AES_KEY key_enc_exp;
514
+ struct crypto_aesctr * AES;
515
+ int rc;
516
+
517
+ /*
518
+ * Read the first 7 bytes of the file; all future version of scrypt
519
+ * are guaranteed to have at least 7 bytes of header.
520
+ */
521
+ if (fread(header, 7, 1, infile) < 1) {
522
+ if (ferror(infile))
523
+ return (13);
524
+ else
525
+ return (7);
526
+ }
527
+
528
+ /* Do we have the right magic? */
529
+ if (memcmp(header, "scrypt", 6))
530
+ return (7);
531
+ if (header[6] != 0)
532
+ return (8);
533
+
534
+ /*
535
+ * Read another 89 bytes of the file; version 0 of the srypt file
536
+ * format has a 96-byte header.
537
+ */
538
+ if (fread(&header[7], 89, 1, infile) < 1) {
539
+ if (ferror(infile))
540
+ return (13);
541
+ else
542
+ return (7);
543
+ }
544
+
545
+ /* Parse the header and generate derived keys. */
546
+ if ((rc = scryptdec_setup(header, dk, passwd, passwdlen,
547
+ maxmem, maxmemfrac, maxtime)) != 0)
548
+ return (rc);
549
+
550
+ /* Start hashing with the header. */
551
+ HMAC_SHA256_Init(&hctx, key_hmac, 32);
552
+ HMAC_SHA256_Update(&hctx, header, 96);
553
+
554
+ /*
555
+ * We don't know how long the encrypted data block is (we can't know,
556
+ * since data can be streamed into 'scrypt enc') so we need to read
557
+ * data and decrypt all of it except the final 32 bytes, then check
558
+ * if that final 32 bytes is the correct signature.
559
+ */
560
+ if (AES_set_encrypt_key(key_enc, 256, &key_enc_exp))
561
+ return (5);
562
+ if ((AES = crypto_aesctr_init(&key_enc_exp, 0)) == NULL)
563
+ return (6);
564
+ do {
565
+ /* Read data until we have more than 32 bytes of it. */
566
+ if ((readlen = fread(&buf[buflen], 1,
567
+ ENCBLOCK + 32 - buflen, infile)) == 0)
568
+ break;
569
+ buflen += readlen;
570
+ if (buflen <= 32)
571
+ continue;
572
+
573
+ /*
574
+ * Decrypt, hash, and output everything except the last 32
575
+ * bytes out of what we have in our buffer.
576
+ */
577
+ HMAC_SHA256_Update(&hctx, buf, buflen - 32);
578
+ crypto_aesctr_stream(AES, buf, buf, buflen - 32);
579
+ if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32)
580
+ return (12);
581
+
582
+ /* Move the last 32 bytes to the start of the buffer. */
583
+ memmove(buf, &buf[buflen - 32], 32);
584
+ buflen = 32;
585
+ } while (1);
586
+ crypto_aesctr_free(AES);
587
+
588
+ /* Did we exit the loop due to a read error? */
589
+ if (ferror(infile))
590
+ return (13);
591
+
592
+ /* Did we read enough data that we *might* have a valid signature? */
593
+ if (buflen < 32)
594
+ return (7);
595
+
596
+ /* Verify signature. */
597
+ HMAC_SHA256_Final(hbuf, &hctx);
598
+ if (memcmp(hbuf, buf, 32))
599
+ return (7);
600
+
601
+ /* Zero sensitive data. */
602
+ memset(dk, 0, 64);
603
+ memset(&key_enc_exp, 0, sizeof(AES_KEY));
604
+
605
+ return (0);
606
+ }
data/ext/scryptenc.h ADDED
@@ -0,0 +1,112 @@
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_H_
30
+ #define _SCRYPTENC_H_
31
+
32
+ #include <stdint.h>
33
+ #include <stdio.h>
34
+
35
+ /**
36
+ * The parameters maxmem, maxmemfrac, and maxtime used by all of these
37
+ * functions are defined as follows:
38
+ * maxmem - maximum number of bytes of storage to use for V array (which is
39
+ * by far the largest consumer of memory). If this value is set to 0, no
40
+ * maximum will be enforced; any other value less than 1 MiB will be
41
+ * treated as 1 MiB.
42
+ * maxmemfrac - maximum fraction of available storage to use for the V array,
43
+ * where "available storage" is defined as the minimum out of the
44
+ * RLIMIT_AS, RLIMIT_DATA. and RLIMIT_RSS resource limits (if any are
45
+ * set). If this value is set to 0 or more than 0.5 it will be treated
46
+ * as 0.5; and this value will never cause a limit of less than 1 MiB to
47
+ * be enforced.
48
+ * maxtime - maximum amount of CPU time to spend computing the derived keys,
49
+ * in seconds. This limit is only approximately enforced; the CPU
50
+ * performance is estimated and parameter limits are chosen accordingly.
51
+ * For the encryption functions, the parameters to the scrypt key derivation
52
+ * function are chosen to make the key as strong as possible subject to the
53
+ * specified limits; for the decryption functions, the parameters used are
54
+ * compared to the computed limits and an error is returned if decrypting
55
+ * the data would take too much memory or CPU time.
56
+ */
57
+ /**
58
+ * Return codes from scrypt(enc|dec)_(buf|file):
59
+ * 0 success
60
+ * 1 getrlimit or sysctl(hw.usermem) failed
61
+ * 2 clock_getres or clock_gettime failed
62
+ * 3 error computing derived key
63
+ * 4 could not read salt from /dev/urandom
64
+ * 5 error in OpenSSL
65
+ * 6 malloc failed
66
+ * 7 data is not a valid scrypt-encrypted block
67
+ * 8 unrecognized scrypt format
68
+ * 9 decrypting file would take too much memory
69
+ * 10 decrypting file would take too long
70
+ * 11 password is incorrect
71
+ * 12 error writing output file
72
+ * 13 error reading input file
73
+ */
74
+
75
+ /**
76
+ * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
77
+ * maxmem, maxmemfrac, maxtime):
78
+ * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
79
+ * bytes to outbuf.
80
+ */
81
+ int scryptenc_buf(const uint8_t *, size_t, uint8_t *,
82
+ const uint8_t *, size_t, size_t, double, double);
83
+
84
+ /**
85
+ * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
86
+ * maxmem, maxmemfrac, maxtime):
87
+ * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
88
+ * decrypted data length to outlen. The allocated length of outbuf must
89
+ * be at least inbuflen.
90
+ */
91
+ int scryptdec_buf(const uint8_t *, size_t, uint8_t *, size_t *,
92
+ const uint8_t *, size_t, size_t, double, double);
93
+
94
+ /**
95
+ * scryptenc_file(infile, outfile, passwd, passwdlen,
96
+ * maxmem, maxmemfrac, maxtime):
97
+ * Read a stream from infile and encrypt it, writing the resulting stream to
98
+ * outfile.
99
+ */
100
+ int scryptenc_file(FILE *, FILE *, const uint8_t *, size_t,
101
+ size_t, double, double);
102
+
103
+ /**
104
+ * scryptdec_file(infile, outfile, passwd, passwdlen,
105
+ * maxmem, maxmemfrac, maxtime):
106
+ * Read a stream from infile and decrypt it, writing the resulting stream to
107
+ * outfile.
108
+ */
109
+ int scryptdec_file(FILE *, FILE *, const uint8_t *, size_t,
110
+ size_t, double, double);
111
+
112
+ #endif /* !_SCRYPTENC_H_ */