bcrypt 3.1.11-java → 3.1.15-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +18 -11
- data/CHANGELOG +76 -59
- data/Gemfile.lock +16 -23
- data/README.md +68 -77
- data/Rakefile +2 -23
- data/appveyor.yml +50 -0
- data/bcrypt.gemspec +1 -3
- data/ext/jruby/bcrypt_jruby/BCrypt.java +524 -351
- data/ext/mri/bcrypt_ext.c +3 -3
- data/ext/mri/crypt.h +12 -1
- data/ext/mri/crypt_blowfish.c +269 -152
- data/ext/mri/crypt_blowfish.h +27 -0
- data/ext/mri/crypt_gensalt.c +27 -14
- data/ext/mri/crypt_gensalt.h +30 -0
- data/ext/mri/extconf.rb +6 -0
- data/ext/mri/ow-crypt.h +25 -17
- data/ext/mri/wrapper.c +338 -46
- data/ext/mri/x86.S +203 -0
- data/lib/bcrypt.rb +1 -6
- data/lib/bcrypt/engine.rb +7 -5
- data/lib/bcrypt/password.rb +3 -3
- data/spec/bcrypt/engine_spec.rb +77 -2
- data/spec/bcrypt/password_spec.rb +2 -2
- metadata +31 -56
data/ext/mri/bcrypt_ext.c
CHANGED
@@ -19,7 +19,7 @@ static VALUE bc_salt(VALUE self, VALUE prefix, VALUE count, VALUE input) {
|
|
19
19
|
if(!salt) return Qnil;
|
20
20
|
|
21
21
|
str_salt = rb_str_new2(salt);
|
22
|
-
|
22
|
+
free(salt);
|
23
23
|
|
24
24
|
return str_salt;
|
25
25
|
}
|
@@ -43,9 +43,9 @@ static VALUE bc_crypt(VALUE self, VALUE key, VALUE setting) {
|
|
43
43
|
&data,
|
44
44
|
&size);
|
45
45
|
|
46
|
-
if(!value) return Qnil;
|
46
|
+
if(!value || !data) return Qnil;
|
47
47
|
|
48
|
-
out =
|
48
|
+
out = rb_str_new2(value);
|
49
49
|
|
50
50
|
xfree(data);
|
51
51
|
|
data/ext/mri/crypt.h
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
/*
|
2
|
-
* Written by Solar Designer
|
2
|
+
* Written by Solar Designer <solar at openwall.com> in 2000-2002.
|
3
|
+
* No copyright is claimed, and the software is hereby placed in the public
|
4
|
+
* domain. In case this attempt to disclaim copyright and place the software
|
5
|
+
* in the public domain is deemed null and void, then the software is
|
6
|
+
* Copyright (c) 2000-2002 Solar Designer and it is hereby released to the
|
7
|
+
* general public under the following terms:
|
8
|
+
*
|
9
|
+
* Redistribution and use in source and binary forms, with or without
|
10
|
+
* modification, are permitted.
|
11
|
+
*
|
12
|
+
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
13
|
+
*
|
3
14
|
* See crypt_blowfish.c for more information.
|
4
15
|
*/
|
5
16
|
|
data/ext/mri/crypt_blowfish.c
CHANGED
@@ -1,26 +1,38 @@
|
|
1
1
|
/*
|
2
|
+
* The crypt_blowfish homepage is:
|
3
|
+
*
|
4
|
+
* http://www.openwall.com/crypt/
|
5
|
+
*
|
2
6
|
* This code comes from John the Ripper password cracker, with reentrant
|
3
7
|
* and crypt(3) interfaces added, but optimizations specific to password
|
4
8
|
* cracking removed.
|
5
9
|
*
|
6
|
-
* Written by Solar Designer <solar at openwall.com> in 1998-
|
7
|
-
*
|
8
|
-
*
|
10
|
+
* Written by Solar Designer <solar at openwall.com> in 1998-2014.
|
11
|
+
* No copyright is claimed, and the software is hereby placed in the public
|
12
|
+
* domain. In case this attempt to disclaim copyright and place the software
|
13
|
+
* in the public domain is deemed null and void, then the software is
|
14
|
+
* Copyright (c) 1998-2014 Solar Designer and it is hereby released to the
|
15
|
+
* general public under the following terms:
|
16
|
+
*
|
17
|
+
* Redistribution and use in source and binary forms, with or without
|
18
|
+
* modification, are permitted.
|
9
19
|
*
|
10
|
-
* There's
|
20
|
+
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
11
21
|
*
|
12
22
|
* It is my intent that you should be able to use this on your system,
|
13
|
-
* as
|
23
|
+
* as part of a software package, or anywhere else to improve security,
|
14
24
|
* ensure compatibility, or for any other purpose. I would appreciate
|
15
25
|
* it if you give credit where it is due and keep your modifications in
|
16
26
|
* the public domain as well, but I don't require that in order to let
|
17
27
|
* you place this code and any modifications you make under a license
|
18
28
|
* of your choice.
|
19
29
|
*
|
20
|
-
* This implementation is compatible with OpenBSD bcrypt.c
|
21
|
-
* by Niels Provos <provos at citi.umich.edu>, and uses
|
22
|
-
* ideas. The password hashing algorithm was designed by David
|
23
|
-
* <dm at lcs.mit.edu>.
|
30
|
+
* This implementation is fully compatible with OpenBSD's bcrypt.c for prefix
|
31
|
+
* "$2b$", originally by Niels Provos <provos at citi.umich.edu>, and it uses
|
32
|
+
* some of his ideas. The password hashing algorithm was designed by David
|
33
|
+
* Mazieres <dm at lcs.mit.edu>. For information on the level of
|
34
|
+
* compatibility for bcrypt hash prefixes other than "$2b$", please refer to
|
35
|
+
* the comments in BF_set_key() below and to the included crypt(3) man page.
|
24
36
|
*
|
25
37
|
* There's a paper on the algorithm that explains its design decisions:
|
26
38
|
*
|
@@ -38,21 +50,13 @@
|
|
38
50
|
#define __set_errno(val) errno = (val)
|
39
51
|
#endif
|
40
52
|
|
41
|
-
|
42
|
-
#
|
43
|
-
#define __CONST __const
|
44
|
-
#else
|
45
|
-
#define __CONST
|
46
|
-
#endif
|
53
|
+
/* Just to make sure the prototypes match the actual definitions */
|
54
|
+
#include "crypt_blowfish.h"
|
47
55
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
*/
|
53
|
-
#define BF_SELF_TEST
|
54
|
-
|
55
|
-
#if defined(__x86_64__) || defined(__alpha__) || defined(__hppa__)
|
56
|
+
#ifdef __i386__
|
57
|
+
#define BF_ASM 1
|
58
|
+
#define BF_SCALE 1
|
59
|
+
#elif defined(__x86_64__) || defined(__alpha__) || defined(__hppa__)
|
56
60
|
#define BF_ASM 0
|
57
61
|
#define BF_SCALE 1
|
58
62
|
#else
|
@@ -357,7 +361,7 @@ static BF_ctx BF_init_state = {
|
|
357
361
|
}
|
358
362
|
};
|
359
363
|
|
360
|
-
static unsigned char BF_itoa64[64 + 1] =
|
364
|
+
static const unsigned char BF_itoa64[64 + 1] =
|
361
365
|
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
362
366
|
|
363
367
|
static unsigned char BF_atoi64[0x60] = {
|
@@ -369,14 +373,6 @@ static unsigned char BF_atoi64[0x60] = {
|
|
369
373
|
43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
|
370
374
|
};
|
371
375
|
|
372
|
-
/*
|
373
|
-
* This may be optimized out if built with function inlining and no BF_ASM.
|
374
|
-
*/
|
375
|
-
static void clean(void *data, int size)
|
376
|
-
{
|
377
|
-
memset(data, 0, size);
|
378
|
-
}
|
379
|
-
|
380
376
|
#define BF_safe_atoi64(dst, src) \
|
381
377
|
{ \
|
382
378
|
tmp = (unsigned char)(src); \
|
@@ -386,14 +382,13 @@ static void clean(void *data, int size)
|
|
386
382
|
(dst) = tmp; \
|
387
383
|
}
|
388
384
|
|
389
|
-
static int BF_decode(BF_word *dst,
|
385
|
+
static int BF_decode(BF_word *dst, const char *src, int size)
|
390
386
|
{
|
391
387
|
unsigned char *dptr = (unsigned char *)dst;
|
392
388
|
unsigned char *end = dptr + size;
|
393
|
-
unsigned char *sptr = (unsigned char *)src;
|
394
|
-
unsigned int tmp, c1, c2, c3, c4;
|
395
|
-
|
389
|
+
const unsigned char *sptr = (const unsigned char *)src;
|
396
390
|
do {
|
391
|
+
unsigned int tmp, c1, c2, c3, c4;
|
397
392
|
BF_safe_atoi64(c1, *sptr++);
|
398
393
|
BF_safe_atoi64(c2, *sptr++);
|
399
394
|
*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
|
@@ -406,18 +401,16 @@ static int BF_decode(BF_word *dst, __CONST char *src, int size)
|
|
406
401
|
BF_safe_atoi64(c4, *sptr++);
|
407
402
|
*dptr++ = ((c3 & 0x03) << 6) | c4;
|
408
403
|
} while (dptr < end);
|
409
|
-
|
410
404
|
return 0;
|
411
405
|
}
|
412
406
|
|
413
|
-
static void BF_encode(char *dst,
|
407
|
+
static void BF_encode(char *dst, const BF_word *src, int size)
|
414
408
|
{
|
415
|
-
unsigned char *sptr = (unsigned char *)src;
|
416
|
-
unsigned char *end = sptr + size;
|
409
|
+
const unsigned char *sptr = (const unsigned char *)src;
|
410
|
+
const unsigned char *end = sptr + size;
|
417
411
|
unsigned char *dptr = (unsigned char *)dst;
|
418
|
-
unsigned int c1, c2;
|
419
|
-
|
420
412
|
do {
|
413
|
+
unsigned int c1, c2;
|
421
414
|
c1 = *sptr++;
|
422
415
|
*dptr++ = BF_itoa64[c1 >> 2];
|
423
416
|
c1 = (c1 & 0x03) << 4;
|
@@ -446,10 +439,9 @@ static void BF_swap(BF_word *x, int count)
|
|
446
439
|
{
|
447
440
|
static int endianness_check = 1;
|
448
441
|
char *is_little_endian = (char *)&endianness_check;
|
449
|
-
BF_word tmp;
|
450
|
-
|
451
442
|
if (*is_little_endian)
|
452
443
|
do {
|
444
|
+
BF_word tmp;
|
453
445
|
tmp = *x;
|
454
446
|
tmp = (tmp << 16) | (tmp >> 16);
|
455
447
|
*x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
|
@@ -521,6 +513,10 @@ static void BF_swap(BF_word *x, int count)
|
|
521
513
|
R = L; \
|
522
514
|
L = tmp4 ^ data.ctx.P[BF_N + 1];
|
523
515
|
|
516
|
+
#if BF_ASM == 1
|
517
|
+
#define BF_body() \
|
518
|
+
_BF_body_r(&data.ctx);
|
519
|
+
#else
|
524
520
|
#define BF_body() \
|
525
521
|
L = R = 0; \
|
526
522
|
ptr = data.ctx.P; \
|
@@ -538,35 +534,121 @@ static void BF_swap(BF_word *x, int count)
|
|
538
534
|
*(ptr - 2) = L; \
|
539
535
|
*(ptr - 1) = R; \
|
540
536
|
} while (ptr < &data.ctx.S[3][0xFF]);
|
537
|
+
#endif
|
541
538
|
|
542
|
-
static void BF_set_key(
|
543
|
-
|
539
|
+
static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
|
540
|
+
unsigned char flags)
|
544
541
|
{
|
545
|
-
|
546
|
-
int i, j;
|
547
|
-
BF_word tmp;
|
542
|
+
const char *ptr = key;
|
543
|
+
unsigned int bug, i, j;
|
544
|
+
BF_word safety, sign, diff, tmp[2];
|
545
|
+
|
546
|
+
/*
|
547
|
+
* There was a sign extension bug in older revisions of this function. While
|
548
|
+
* we would have liked to simply fix the bug and move on, we have to provide
|
549
|
+
* a backwards compatibility feature (essentially the bug) for some systems and
|
550
|
+
* a safety measure for some others. The latter is needed because for certain
|
551
|
+
* multiple inputs to the buggy algorithm there exist easily found inputs to
|
552
|
+
* the correct algorithm that produce the same hash. Thus, we optionally
|
553
|
+
* deviate from the correct algorithm just enough to avoid such collisions.
|
554
|
+
* While the bug itself affected the majority of passwords containing
|
555
|
+
* characters with the 8th bit set (although only a percentage of those in a
|
556
|
+
* collision-producing way), the anti-collision safety measure affects
|
557
|
+
* only a subset of passwords containing the '\xff' character (not even all of
|
558
|
+
* those passwords, just some of them). This character is not found in valid
|
559
|
+
* UTF-8 sequences and is rarely used in popular 8-bit character encodings.
|
560
|
+
* Thus, the safety measure is unlikely to cause much annoyance, and is a
|
561
|
+
* reasonable tradeoff to use when authenticating against existing hashes that
|
562
|
+
* are not reliably known to have been computed with the correct algorithm.
|
563
|
+
*
|
564
|
+
* We use an approach that tries to minimize side-channel leaks of password
|
565
|
+
* information - that is, we mostly use fixed-cost bitwise operations instead
|
566
|
+
* of branches or table lookups. (One conditional branch based on password
|
567
|
+
* length remains. It is not part of the bug aftermath, though, and is
|
568
|
+
* difficult and possibly unreasonable to avoid given the use of C strings by
|
569
|
+
* the caller, which results in similar timing leaks anyway.)
|
570
|
+
*
|
571
|
+
* For actual implementation, we set an array index in the variable "bug"
|
572
|
+
* (0 means no bug, 1 means sign extension bug emulation) and a flag in the
|
573
|
+
* variable "safety" (bit 16 is set when the safety measure is requested).
|
574
|
+
* Valid combinations of settings are:
|
575
|
+
*
|
576
|
+
* Prefix "$2a$": bug = 0, safety = 0x10000
|
577
|
+
* Prefix "$2b$": bug = 0, safety = 0
|
578
|
+
* Prefix "$2x$": bug = 1, safety = 0
|
579
|
+
* Prefix "$2y$": bug = 0, safety = 0
|
580
|
+
*/
|
581
|
+
bug = (unsigned int)flags & 1;
|
582
|
+
safety = ((BF_word)flags & 2) << 15;
|
583
|
+
|
584
|
+
sign = diff = 0;
|
548
585
|
|
549
586
|
for (i = 0; i < BF_N + 2; i++) {
|
550
|
-
tmp = 0;
|
587
|
+
tmp[0] = tmp[1] = 0;
|
551
588
|
for (j = 0; j < 4; j++) {
|
552
|
-
tmp <<= 8;
|
553
|
-
|
554
|
-
|
589
|
+
tmp[0] <<= 8;
|
590
|
+
tmp[0] |= (unsigned char)*ptr; /* correct */
|
591
|
+
tmp[1] <<= 8;
|
592
|
+
tmp[1] |= (BF_word_signed)(signed char)*ptr; /* bug */
|
593
|
+
/*
|
594
|
+
* Sign extension in the first char has no effect - nothing to overwrite yet,
|
595
|
+
* and those extra 24 bits will be fully shifted out of the 32-bit word. For
|
596
|
+
* chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign
|
597
|
+
* extension in tmp[1] occurs. Once this flag is set, it remains set.
|
598
|
+
*/
|
599
|
+
if (j)
|
600
|
+
sign |= tmp[1] & 0x80;
|
601
|
+
if (!*ptr)
|
602
|
+
ptr = key;
|
555
603
|
else
|
556
|
-
|
557
|
-
|
558
|
-
if (!*ptr) ptr = key; else ptr++;
|
604
|
+
ptr++;
|
559
605
|
}
|
606
|
+
diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */
|
560
607
|
|
561
|
-
expanded[i] = tmp;
|
562
|
-
initial[i] = BF_init_state.P[i] ^ tmp;
|
608
|
+
expanded[i] = tmp[bug];
|
609
|
+
initial[i] = BF_init_state.P[i] ^ tmp[bug];
|
563
610
|
}
|
611
|
+
|
612
|
+
/*
|
613
|
+
* At this point, "diff" is zero iff the correct and buggy algorithms produced
|
614
|
+
* exactly the same result. If so and if "sign" is non-zero, which indicates
|
615
|
+
* that there was a non-benign sign extension, this means that we have a
|
616
|
+
* collision between the correctly computed hash for this password and a set of
|
617
|
+
* passwords that could be supplied to the buggy algorithm. Our safety measure
|
618
|
+
* is meant to protect from such many-buggy to one-correct collisions, by
|
619
|
+
* deviating from the correct algorithm in such cases. Let's check for this.
|
620
|
+
*/
|
621
|
+
diff |= diff >> 16; /* still zero iff exact match */
|
622
|
+
diff &= 0xffff; /* ditto */
|
623
|
+
diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */
|
624
|
+
sign <<= 9; /* move the non-benign sign extension flag to bit 16 */
|
625
|
+
sign &= ~diff & safety; /* action needed? */
|
626
|
+
|
627
|
+
/*
|
628
|
+
* If we have determined that we need to deviate from the correct algorithm,
|
629
|
+
* flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but
|
630
|
+
* let's stick to it now. It came out of the approach we used above, and it's
|
631
|
+
* not any worse than any other choice we could make.)
|
632
|
+
*
|
633
|
+
* It is crucial that we don't do the same to the expanded key used in the main
|
634
|
+
* Eksblowfish loop. By doing it to only one of these two, we deviate from a
|
635
|
+
* state that could be directly specified by a password to the buggy algorithm
|
636
|
+
* (and to the fully correct one as well, but that's a side-effect).
|
637
|
+
*/
|
638
|
+
initial[0] ^= sign;
|
564
639
|
}
|
565
640
|
|
566
|
-
static
|
641
|
+
static const unsigned char flags_by_subtype[26] =
|
642
|
+
{2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
643
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
|
644
|
+
|
645
|
+
static char *BF_crypt(const char *key, const char *setting,
|
567
646
|
char *output, int size,
|
568
647
|
BF_word min)
|
569
648
|
{
|
649
|
+
#if BF_ASM == 1
|
650
|
+
extern void _BF_body_r(BF_ctx *ctx);
|
651
|
+
#endif
|
570
652
|
struct {
|
571
653
|
BF_ctx ctx;
|
572
654
|
BF_key expanded_key;
|
@@ -588,7 +670,8 @@ static char *BF_crypt(__CONST char *key, __CONST char *setting,
|
|
588
670
|
|
589
671
|
if (setting[0] != '$' ||
|
590
672
|
setting[1] != '2' ||
|
591
|
-
|
673
|
+
setting[2] < 'a' || setting[2] > 'z' ||
|
674
|
+
!flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a'] ||
|
592
675
|
setting[3] != '$' ||
|
593
676
|
setting[4] < '0' || setting[4] > '3' ||
|
594
677
|
setting[5] < '0' || setting[5] > '9' ||
|
@@ -600,13 +683,13 @@ static char *BF_crypt(__CONST char *key, __CONST char *setting,
|
|
600
683
|
|
601
684
|
count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
|
602
685
|
if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {
|
603
|
-
clean(data.binary.salt, sizeof(data.binary.salt));
|
604
686
|
__set_errno(EINVAL);
|
605
687
|
return NULL;
|
606
688
|
}
|
607
689
|
BF_swap(data.binary.salt, 4);
|
608
690
|
|
609
|
-
BF_set_key(key, data.expanded_key, data.ctx.P,
|
691
|
+
BF_set_key(key, data.expanded_key, data.ctx.P,
|
692
|
+
flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a']);
|
610
693
|
|
611
694
|
memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
|
612
695
|
|
@@ -636,51 +719,33 @@ static char *BF_crypt(__CONST char *key, __CONST char *setting,
|
|
636
719
|
} while (ptr < &data.ctx.S[3][0xFF]);
|
637
720
|
|
638
721
|
do {
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
data.ctx.P[2] ^= tmp3;
|
667
|
-
data.ctx.P[3] ^= tmp4;
|
668
|
-
data.ctx.P[4] ^= tmp1;
|
669
|
-
data.ctx.P[5] ^= tmp2;
|
670
|
-
data.ctx.P[6] ^= tmp3;
|
671
|
-
data.ctx.P[7] ^= tmp4;
|
672
|
-
data.ctx.P[8] ^= tmp1;
|
673
|
-
data.ctx.P[9] ^= tmp2;
|
674
|
-
data.ctx.P[10] ^= tmp3;
|
675
|
-
data.ctx.P[11] ^= tmp4;
|
676
|
-
data.ctx.P[12] ^= tmp1;
|
677
|
-
data.ctx.P[13] ^= tmp2;
|
678
|
-
data.ctx.P[14] ^= tmp3;
|
679
|
-
data.ctx.P[15] ^= tmp4;
|
680
|
-
data.ctx.P[16] ^= tmp1;
|
681
|
-
data.ctx.P[17] ^= tmp2;
|
682
|
-
|
683
|
-
BF_body();
|
722
|
+
int done;
|
723
|
+
|
724
|
+
for (i = 0; i < BF_N + 2; i += 2) {
|
725
|
+
data.ctx.P[i] ^= data.expanded_key[i];
|
726
|
+
data.ctx.P[i + 1] ^= data.expanded_key[i + 1];
|
727
|
+
}
|
728
|
+
|
729
|
+
done = 0;
|
730
|
+
do {
|
731
|
+
BF_body();
|
732
|
+
if (done)
|
733
|
+
break;
|
734
|
+
done = 1;
|
735
|
+
|
736
|
+
tmp1 = data.binary.salt[0];
|
737
|
+
tmp2 = data.binary.salt[1];
|
738
|
+
tmp3 = data.binary.salt[2];
|
739
|
+
tmp4 = data.binary.salt[3];
|
740
|
+
for (i = 0; i < BF_N; i += 4) {
|
741
|
+
data.ctx.P[i] ^= tmp1;
|
742
|
+
data.ctx.P[i + 1] ^= tmp2;
|
743
|
+
data.ctx.P[i + 2] ^= tmp3;
|
744
|
+
data.ctx.P[i + 3] ^= tmp4;
|
745
|
+
}
|
746
|
+
data.ctx.P[16] ^= tmp1;
|
747
|
+
data.ctx.P[17] ^= tmp2;
|
748
|
+
} while (1);
|
684
749
|
} while (--count);
|
685
750
|
|
686
751
|
for (i = 0; i < 6; i += 2) {
|
@@ -706,64 +771,116 @@ static char *BF_crypt(__CONST char *key, __CONST char *setting,
|
|
706
771
|
BF_encode(&output[7 + 22], data.binary.output, 23);
|
707
772
|
output[7 + 22 + 31] = '\0';
|
708
773
|
|
709
|
-
#ifndef BF_SELF_TEST
|
710
|
-
/* Overwrite the most obvious sensitive data we have on the stack. Note
|
711
|
-
* that this does not guarantee there's no sensitive data left on the
|
712
|
-
* stack and/or in registers; I'm not aware of portable code that does. */
|
713
|
-
clean(&data, sizeof(data));
|
714
|
-
#endif
|
715
|
-
|
716
774
|
return output;
|
717
775
|
}
|
718
776
|
|
719
|
-
|
777
|
+
int _crypt_output_magic(const char *setting, char *output, int size)
|
778
|
+
{
|
779
|
+
if (size < 3)
|
780
|
+
return -1;
|
781
|
+
|
782
|
+
output[0] = '*';
|
783
|
+
output[1] = '0';
|
784
|
+
output[2] = '\0';
|
785
|
+
|
786
|
+
if (setting[0] == '*' && setting[1] == '0')
|
787
|
+
output[1] = '1';
|
788
|
+
|
789
|
+
return 0;
|
790
|
+
}
|
791
|
+
|
792
|
+
/*
|
793
|
+
* Please preserve the runtime self-test. It serves two purposes at once:
|
794
|
+
*
|
795
|
+
* 1. We really can't afford the risk of producing incompatible hashes e.g.
|
796
|
+
* when there's something like gcc bug 26587 again, whereas an application or
|
797
|
+
* library integrating this code might not also integrate our external tests or
|
798
|
+
* it might not run them after every build. Even if it does, the miscompile
|
799
|
+
* might only occur on the production build, but not on a testing build (such
|
800
|
+
* as because of different optimization settings). It is painful to recover
|
801
|
+
* from incorrectly-computed hashes - merely fixing whatever broke is not
|
802
|
+
* enough. Thus, a proactive measure like this self-test is needed.
|
803
|
+
*
|
804
|
+
* 2. We don't want to leave sensitive data from our actual password hash
|
805
|
+
* computation on the stack or in registers. Previous revisions of the code
|
806
|
+
* would do explicit cleanups, but simply running the self-test after hash
|
807
|
+
* computation is more reliable.
|
808
|
+
*
|
809
|
+
* The performance cost of this quick self-test is around 0.6% at the "$2a$08"
|
810
|
+
* setting.
|
811
|
+
*/
|
812
|
+
char *_crypt_blowfish_rn(const char *key, const char *setting,
|
720
813
|
char *output, int size)
|
721
814
|
{
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
memcpy(buf, test_hash, sizeof(buf));
|
741
|
-
memset(buf, -1, sizeof(buf) - (6 + 1)); /* keep "canary" only */
|
742
|
-
p = BF_crypt(test_key, test_hash, buf, sizeof(buf) - 6, 1);
|
743
|
-
|
744
|
-
ok = (p == buf && !memcmp(p, test_hash, sizeof(buf)));
|
745
|
-
|
746
|
-
/* This could reveal what hash type we were using last. Unfortunately, we
|
747
|
-
* can't reliably clean the test_hash pointer. */
|
748
|
-
clean(&buf, sizeof(buf));
|
815
|
+
const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
|
816
|
+
const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
|
817
|
+
static const char * const test_hashes[2] =
|
818
|
+
{"i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55", /* 'a', 'b', 'y' */
|
819
|
+
"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55"}; /* 'x' */
|
820
|
+
const char *test_hash = test_hashes[0];
|
821
|
+
char *retval;
|
822
|
+
const char *p;
|
823
|
+
int save_errno, ok;
|
824
|
+
struct {
|
825
|
+
char s[7 + 22 + 1];
|
826
|
+
char o[7 + 22 + 31 + 1 + 1 + 1];
|
827
|
+
} buf;
|
828
|
+
|
829
|
+
/* Hash the supplied password */
|
830
|
+
_crypt_output_magic(setting, output, size);
|
831
|
+
retval = BF_crypt(key, setting, output, size, 16);
|
832
|
+
save_errno = errno;
|
749
833
|
|
834
|
+
/*
|
835
|
+
* Do a quick self-test. It is important that we make both calls to BF_crypt()
|
836
|
+
* from the same scope such that they likely use the same stack locations,
|
837
|
+
* which makes the second call overwrite the first call's sensitive data on the
|
838
|
+
* stack and makes it more likely that any alignment related issues would be
|
839
|
+
* detected by the self-test.
|
840
|
+
*/
|
841
|
+
memcpy(buf.s, test_setting, sizeof(buf.s));
|
842
|
+
if (retval) {
|
843
|
+
unsigned int flags = flags_by_subtype[
|
844
|
+
(unsigned int)(unsigned char)setting[2] - 'a'];
|
845
|
+
test_hash = test_hashes[flags & 1];
|
846
|
+
buf.s[2] = setting[2];
|
847
|
+
}
|
848
|
+
memset(buf.o, 0x55, sizeof(buf.o));
|
849
|
+
buf.o[sizeof(buf.o) - 1] = 0;
|
850
|
+
p = BF_crypt(test_key, buf.s, buf.o, sizeof(buf.o) - (1 + 1), 1);
|
851
|
+
|
852
|
+
ok = (p == buf.o &&
|
853
|
+
!memcmp(p, buf.s, 7 + 22) &&
|
854
|
+
!memcmp(p + (7 + 22), test_hash, 31 + 1 + 1 + 1));
|
855
|
+
|
856
|
+
{
|
857
|
+
const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
|
858
|
+
BF_key ae, ai, ye, yi;
|
859
|
+
BF_set_key(k, ae, ai, 2); /* $2a$ */
|
860
|
+
BF_set_key(k, ye, yi, 4); /* $2y$ */
|
861
|
+
ai[0] ^= 0x10000; /* undo the safety (for comparison) */
|
862
|
+
ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&
|
863
|
+
!memcmp(ae, ye, sizeof(ae)) &&
|
864
|
+
!memcmp(ai, yi, sizeof(ai));
|
865
|
+
}
|
866
|
+
|
867
|
+
__set_errno(save_errno);
|
750
868
|
if (ok)
|
751
|
-
return
|
869
|
+
return retval;
|
752
870
|
|
753
871
|
/* Should not happen */
|
872
|
+
_crypt_output_magic(setting, output, size);
|
754
873
|
__set_errno(EINVAL); /* pretend we don't support this hash type */
|
755
874
|
return NULL;
|
756
|
-
#else
|
757
|
-
#warning Self-test is disabled, please enable
|
758
|
-
return BF_crypt(key, setting, output, size, 16);
|
759
|
-
#endif
|
760
875
|
}
|
761
876
|
|
762
|
-
char *_crypt_gensalt_blowfish_rn(unsigned long count,
|
763
|
-
|
877
|
+
char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
|
878
|
+
const char *input, int size, char *output, int output_size)
|
764
879
|
{
|
765
880
|
if (size < 16 || output_size < 7 + 22 + 1 ||
|
766
|
-
(count && (count < 4 || count > 31))
|
881
|
+
(count && (count < 4 || count > 31)) ||
|
882
|
+
prefix[0] != '$' || prefix[1] != '2' ||
|
883
|
+
(prefix[2] != 'a' && prefix[2] != 'b' && prefix[2] != 'y')) {
|
767
884
|
if (output_size > 0) output[0] = '\0';
|
768
885
|
__set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
|
769
886
|
return NULL;
|
@@ -773,13 +890,13 @@ char *_crypt_gensalt_blowfish_rn(unsigned long count,
|
|
773
890
|
|
774
891
|
output[0] = '$';
|
775
892
|
output[1] = '2';
|
776
|
-
output[2] =
|
893
|
+
output[2] = prefix[2];
|
777
894
|
output[3] = '$';
|
778
895
|
output[4] = '0' + count / 10;
|
779
896
|
output[5] = '0' + count % 10;
|
780
897
|
output[6] = '$';
|
781
898
|
|
782
|
-
BF_encode(&output[7], (BF_word *)input, 16);
|
899
|
+
BF_encode(&output[7], (const BF_word *)input, 16);
|
783
900
|
output[7 + 22] = '\0';
|
784
901
|
|
785
902
|
return output;
|