@@ -530,10 +530,10 @@ static void BF_swap(BF_word *x, int count)
530530 *(ptr - 1) = R; \
531531 } while (ptr < &data.ctx.S[3][0xFF]);
532532
533- static void BF_set_key (const char * key , BF_key expanded , BF_key initial ,
534- unsigned char flags )
533+ static void BF_set_key (const char * key , size_t key_len , BF_key expanded ,
534+ BF_key initial , unsigned char flags )
535535{
536- const char * ptr = key ;
536+ size_t key_pos = 0 ;
537537 unsigned int bug , i , j ;
538538 BF_word safety , sign , diff , tmp [2 ];
539539
@@ -559,8 +559,7 @@ static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
559559 * information - that is, we mostly use fixed-cost bitwise operations instead
560560 * of branches or table lookups. (One conditional branch based on password
561561 * length remains. It is not part of the bug aftermath, though, and is
562- * difficult and possibly unreasonable to avoid given the use of C strings by
563- * the caller, which results in similar timing leaks anyway.)
562+ * difficult and possibly unreasonable to avoid here.)
564563 *
565564 * For actual implementation, we set an array index in the variable "bug"
566565 * (0 means no bug, 1 means sign extension bug emulation) and a flag in the
@@ -577,13 +576,20 @@ static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
577576
578577 sign = diff = 0 ;
579578
579+ /*
580+ * bcrypt cycles over the password bytes plus a trailing NUL terminator.
581+ * The explicit length keeps embedded NUL bytes significant while
582+ * preserving the historical behavior for ordinary C strings.
583+ */
580584 for (i = 0 ; i < BF_N + 2 ; i ++ ) {
581585 tmp [0 ] = tmp [1 ] = 0 ;
582586 for (j = 0 ; j < 4 ; j ++ ) {
587+ unsigned char c = key_pos < key_len ? (unsigned char ) key [key_pos ] : 0 ;
588+
583589 tmp [0 ] <<= 8 ;
584- tmp [0 ] |= ( unsigned char ) * ptr ; /* correct */
590+ tmp [0 ] |= c ; /* correct */
585591 tmp [1 ] <<= 8 ;
586- tmp [1 ] |= (BF_word_signed )(signed char )* ptr ; /* bug */
592+ tmp [1 ] |= (BF_word_signed )(signed char )c ; /* bug */
587593/*
588594 * Sign extension in the first char has no effect - nothing to overwrite yet,
589595 * and those extra 24 bits will be fully shifted out of the 32-bit word. For
@@ -592,10 +598,9 @@ static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
592598 */
593599 if (j )
594600 sign |= tmp [1 ] & 0x80 ;
595- if (!* ptr )
596- ptr = key ;
597- else
598- ptr ++ ;
601+ key_pos ++ ;
602+ if (key_pos > key_len )
603+ key_pos = 0 ;
599604 }
600605 diff |= tmp [0 ] ^ tmp [1 ]; /* Non-zero on any differences */
601606
@@ -636,7 +641,7 @@ static const unsigned char flags_by_subtype[26] =
636641 {2 , 4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
637642 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 4 , 0 };
638643
639- static char * BF_crypt (const char * key , const char * setting ,
644+ static char * BF_crypt (const char * key , size_t key_len , const char * setting ,
640645 char * output , int size ,
641646 BF_word min )
642647{
@@ -679,7 +684,7 @@ static char *BF_crypt(const char *key, const char *setting,
679684 }
680685 BF_swap (data .binary .salt , 4 );
681686
682- BF_set_key (key , data .expanded_key , data .ctx .P ,
687+ BF_set_key (key , key_len , data .expanded_key , data .ctx .P ,
683688 flags_by_subtype [(unsigned int )(unsigned char )setting [2 ] - 'a' ]);
684689
685690 memcpy (data .ctx .S , BF_init_state .S , sizeof (data .ctx .S ));
@@ -800,10 +805,10 @@ static int _crypt_output_magic(const char *setting, char *output, int size)
800805 * The performance cost of this quick self-test is around 0.6% at the "$2a$08"
801806 * setting.
802807 */
803- char * php_crypt_blowfish_rn (const char * key , const char * setting ,
804- char * output , int size )
808+ char * php_crypt_blowfish_rn (const char * key , size_t key_len ,
809+ const char * setting , char * output , int size )
805810{
806- const char * test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8" ;
811+ static const char test_key [] = "8b \xd0\xc1\xd2\xcf\xcc\xd8" ;
807812 const char * test_setting = "$2a$00$abcdefghijklmnopqrstuu" ;
808813 static const char * const test_hashes [2 ] =
809814 {"i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55" , /* 'a', 'b', 'y' */
@@ -819,7 +824,7 @@ char *php_crypt_blowfish_rn(const char *key, const char *setting,
819824
820825/* Hash the supplied password */
821826 _crypt_output_magic (setting , output , size );
822- retval = BF_crypt (key , setting , output , size , 16 );
827+ retval = BF_crypt (key , key_len , setting , output , size , 16 );
823828 save_errno = errno ;
824829
825830/*
@@ -838,17 +843,17 @@ char *php_crypt_blowfish_rn(const char *key, const char *setting,
838843 }
839844 memset (buf .o , 0x55 , sizeof (buf .o ));
840845 buf .o [sizeof (buf .o ) - 1 ] = 0 ;
841- p = BF_crypt (test_key , buf .s , buf .o , sizeof (buf .o ) - (1 + 1 ), 1 );
846+ p = BF_crypt (test_key , sizeof ( test_key ) - 1 , buf .s , buf .o , sizeof (buf .o ) - (1 + 1 ), 1 );
842847
843848 ok = (p == buf .o &&
844849 !memcmp (p , buf .s , 7 + 22 ) &&
845850 !memcmp (p + (7 + 22 ), test_hash , 31 + 1 + 1 + 1 ));
846851
847852 {
848- const char * k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345" ;
853+ static const char k [] = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345" ;
849854 BF_key ae , ai , ye , yi ;
850- BF_set_key (k , ae , ai , 2 ); /* $2a$ */
851- BF_set_key (k , ye , yi , 4 ); /* $2y$ */
855+ BF_set_key (k , sizeof ( k ) - 1 , ae , ai , 2 ); /* $2a$ */
856+ BF_set_key (k , sizeof ( k ) - 1 , ye , yi , 4 ); /* $2y$ */
852857 ai [0 ] ^= 0x10000 ; /* undo the safety (for comparison) */
853858 ok = ok && ai [0 ] == 0xdb9c59bc && ye [17 ] == 0x33343500 &&
854859 !memcmp (ae , ye , sizeof (ae )) &&
0 commit comments