| OLD | NEW |
| (Empty) |
| 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 } | |
| OLD | NEW |