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 |