@@ -526,35 +526,47 @@ static long roundsForLogRounds(int log_rounds) {
526526 * @param safety bit 16 is set when the safety measure is requested
527527 * @return an array containing the binary hashed password
528528 */
529- private byte [] crypt_raw (byte password [], byte salt [], int log_rounds , boolean sign_ext_bug , int safety ) {
530- int rounds , i , j ;
529+ private byte [] crypt_raw (byte password [], byte salt [], int log_rounds , boolean sign_ext_bug , int safety ,
530+ boolean for_check ) {
531531 int cdata [] = bf_crypt_ciphertext .clone ();
532532 int clen = cdata .length ;
533- byte ret [];
534533
534+ long rounds ;
535535 if (log_rounds < 4 || log_rounds > 31 ) {
536- throw new IllegalArgumentException ("Bad number of rounds" );
536+ if (!for_check ) {
537+ throw new IllegalArgumentException ("Bad number of rounds" );
538+ }
539+ if (log_rounds != 0 ) {
540+ throw new IllegalArgumentException ("Bad number of rounds" );
541+ }
542+ rounds = 0 ;
543+ }
544+ else {
545+ rounds = roundsForLogRounds (log_rounds );
546+ if (rounds < 16 || rounds > Integer .MAX_VALUE ) {
547+ throw new IllegalArgumentException ("Bad number of rounds" );
548+ }
537549 }
538- rounds = 1 << log_rounds ;
550+
539551 if (salt .length != BCRYPT_SALT_LEN ) {
540552 throw new IllegalArgumentException ("Bad salt length" );
541553 }
542554
543555 init_key ();
544556 ekskey (salt , password , sign_ext_bug , safety );
545- for (i = 0 ; i < rounds ; i ++) {
557+ for (int i = 0 ; i < rounds ; i ++) {
546558 key (password , sign_ext_bug , safety );
547559 key (salt , false , safety );
548560 }
549561
550- for (i = 0 ; i < 64 ; i ++) {
551- for (j = 0 ; j < (clen >> 1 ); j ++) {
562+ for (int i = 0 ; i < 64 ; i ++) {
563+ for (int j = 0 ; j < (clen >> 1 ); j ++) {
552564 encipher (cdata , j << 1 );
553565 }
554566 }
555567
556- ret = new byte [clen * 4 ];
557- for (i = 0 , j = 0 ; i < clen ; i ++) {
568+ byte [] ret = new byte [clen * 4 ];
569+ for (int i = 0 , j = 0 ; i < clen ; i ++) {
558570 ret [j ++] = (byte ) ((cdata [i ] >> 24 ) & 0xff );
559571 ret [j ++] = (byte ) ((cdata [i ] >> 16 ) & 0xff );
560572 ret [j ++] = (byte ) ((cdata [i ] >> 8 ) & 0xff );
@@ -563,6 +575,10 @@ private byte[] crypt_raw(byte password[], byte salt[], int log_rounds, boolean s
563575 return ret ;
564576 }
565577
578+ private static String hashpwforcheck (byte [] passwordb , String salt ) {
579+ return hashpw (passwordb , salt , true );
580+ }
581+
566582 /**
567583 * Hash a password using the OpenBSD bcrypt scheme
568584 * @param password the password to hash
@@ -584,6 +600,10 @@ public static String hashpw(String password, String salt) {
584600 * @return the hashed password
585601 */
586602 public static String hashpw (byte passwordb [], String salt ) {
603+ return hashpw (passwordb , salt , false );
604+ }
605+
606+ private static String hashpw (byte passwordb [], String salt , boolean for_check ) {
587607 BCrypt B ;
588608 String real_salt ;
589609 byte saltb [], hashed [];
@@ -633,7 +653,7 @@ public static String hashpw(byte passwordb[], String salt) {
633653 }
634654
635655 B = new BCrypt ();
636- hashed = B .crypt_raw (passwordb , saltb , rounds , minor == 'x' , minor == 'a' ? 0x10000 : 0 );
656+ hashed = B .crypt_raw (passwordb , saltb , rounds , minor == 'x' , minor == 'a' ? 0x10000 : 0 , for_check );
637657
638658 rs .append ("$2" );
639659 if (minor >= 'a' ) {
@@ -740,7 +760,8 @@ public static String gensalt() {
740760 * @return true if the passwords match, false otherwise
741761 */
742762 public static boolean checkpw (String plaintext , String hashed ) {
743- return equalsNoEarlyReturn (hashed , hashpw (plaintext , hashed ));
763+ byte [] passwordb = plaintext .getBytes (StandardCharsets .UTF_8 );
764+ return equalsNoEarlyReturn (hashed , hashpwforcheck (passwordb , hashed ));
744765 }
745766
746767 /**
@@ -751,7 +772,7 @@ public static boolean checkpw(String plaintext, String hashed) {
751772 * @since 5.3
752773 */
753774 public static boolean checkpw (byte [] passwordb , String hashed ) {
754- return equalsNoEarlyReturn (hashed , hashpw (passwordb , hashed ));
775+ return equalsNoEarlyReturn (hashed , hashpwforcheck (passwordb , hashed ));
755776 }
756777
757778 static boolean equalsNoEarlyReturn (String a , String b ) {
0 commit comments