|
4 | 4 | * cracking removed. |
5 | 5 | * |
6 | 6 | * Written by Solar Designer <solar at openwall.com> in 1998-2002 and |
| 7 | + * placed in the public domain. Quick self-test added in 2011 and also |
7 | 8 | * placed in the public domain. |
8 | 9 | * |
9 | 10 | * There's absolutely no warranty. |
|
44 | 45 | #define __CONST |
45 | 46 | #endif |
46 | 47 |
|
| 48 | +/* |
| 49 | + * Please keep this enabled. We really don't want incompatible hashes to be |
| 50 | + * produced. The performance cost of this quick self-test is around 0.6% at |
| 51 | + * the "$2a$08" setting. |
| 52 | + */ |
| 53 | +#define BF_SELF_TEST |
| 54 | + |
47 | 55 | #ifdef __i386__ |
48 | 56 | #define BF_ASM 1 |
49 | 57 | #define BF_SCALE 1 |
@@ -569,8 +577,9 @@ static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial, |
569 | 577 | } |
570 | 578 | } |
571 | 579 |
|
572 | | -char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, |
573 | | - char *output, int size) |
| 580 | +static char *BF_crypt(__CONST char *key, __CONST char *setting, |
| 581 | + char *output, int size, |
| 582 | + BF_word min) |
574 | 583 | { |
575 | 584 | #if BF_ASM |
576 | 585 | extern void _BF_body_r(BF_ctx *ctx); |
@@ -607,7 +616,7 @@ char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, |
607 | 616 | } |
608 | 617 |
|
609 | 618 | count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); |
610 | | - if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { |
| 619 | + if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) { |
611 | 620 | clean(data.binary.salt, sizeof(data.binary.salt)); |
612 | 621 | __set_errno(EINVAL); |
613 | 622 | return NULL; |
@@ -714,14 +723,59 @@ char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, |
714 | 723 | BF_encode(&output[7 + 22], data.binary.output, 23); |
715 | 724 | output[7 + 22 + 31] = '\0'; |
716 | 725 |
|
| 726 | +#ifndef BF_SELF_TEST |
717 | 727 | /* Overwrite the most obvious sensitive data we have on the stack. Note |
718 | 728 | * that this does not guarantee there's no sensitive data left on the |
719 | 729 | * stack and/or in registers; I'm not aware of portable code that does. */ |
720 | 730 | clean(&data, sizeof(data)); |
| 731 | +#endif |
721 | 732 |
|
722 | 733 | return output; |
723 | 734 | } |
724 | 735 |
|
| 736 | +char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, |
| 737 | + char *output, int size) |
| 738 | +{ |
| 739 | +#ifdef BF_SELF_TEST |
| 740 | + __CONST char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8"; |
| 741 | + __CONST char *test_2a = |
| 742 | + "$2a$00$abcdefghijklmnopqrstuui1D709vfamulimlGcq0qq3UvuUasvEa" |
| 743 | + "\0" |
| 744 | + "canary"; |
| 745 | + __CONST char *test_2x = |
| 746 | + "$2x$00$abcdefghijklmnopqrstuuVUrPmXD6q/nVSSp7pNDhCR9071IfIRe" |
| 747 | + "\0" |
| 748 | + "canary"; |
| 749 | + __CONST char *test_hash, *p; |
| 750 | + int ok; |
| 751 | + char buf[7 + 22 + 31 + 1 + 6 + 1]; |
| 752 | + |
| 753 | + output = BF_crypt(key, setting, output, size, 16); |
| 754 | + |
| 755 | +/* Do a quick self-test. This also happens to overwrite BF_crypt()'s data. */ |
| 756 | + test_hash = (setting[2] == 'x') ? test_2x : test_2a; |
| 757 | + memcpy(buf, test_hash, sizeof(buf)); |
| 758 | + memset(buf, -1, sizeof(buf) - (6 + 1)); /* keep "canary" only */ |
| 759 | + p = BF_crypt(test_key, test_hash, buf, sizeof(buf) - 6, 1); |
| 760 | + |
| 761 | + ok = (p == buf && !memcmp(p, test_hash, sizeof(buf))); |
| 762 | + |
| 763 | +/* This could reveal what hash type we were using last. Unfortunately, we |
| 764 | + * can't reliably clean the test_hash pointer. */ |
| 765 | + clean(&buf, sizeof(buf)); |
| 766 | + |
| 767 | + if (ok) |
| 768 | + return output; |
| 769 | + |
| 770 | +/* Should not happen */ |
| 771 | + __set_errno(EINVAL); /* pretend we don't support this hash type */ |
| 772 | + return NULL; |
| 773 | +#else |
| 774 | +#warning Self-test is disabled, please enable |
| 775 | + return BF_crypt(key, setting, output, size, 16); |
| 776 | +#endif |
| 777 | +} |
| 778 | + |
725 | 779 | char *_crypt_gensalt_blowfish_rn(unsigned long count, |
726 | 780 | __CONST char *input, int size, char *output, int output_size) |
727 | 781 | { |
|
0 commit comments