Clean up a few things.

1. Drop support for no minor. This variant doesn't exist anymore.

2. Pull up the actual minor processing code into the switch that
parses it.

3. atoi is actually simpler than strtonum in this case, but check the
input beforehand so we don't get unexpected results.

4. Slightly more consistent style between various parse and check and
increment operations on salt.

Index: bcrypt.c
===================================================================
RCS file: /cvs/src/lib/libc/crypt/bcrypt.c,v
retrieving revision 1.39
diff -u -p -r1.39 bcrypt.c
--- bcrypt.c    19 Apr 2014 15:19:20 -0000      1.39
+++ bcrypt.c    1 May 2014 03:28:36 -0000
@@ -94,45 +94,44 @@ bcrypt_hashpass(const char *key, const c
        u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
        u_int8_t csalt[BCRYPT_MAXSALT];
        u_int32_t cdata[BCRYPT_BLOCKS];
-       char arounds[3];
 
-       /* Discard "$" identifier */
-       if (*salt != '$')
+       /* Check and discard "$" identifier */
+       if (salt[0] != '$')
                return -1;
-       salt++;
+       salt += 1;
 
-       if (*salt != BCRYPT_VERSION)
+       if (salt[0] != BCRYPT_VERSION)
                return -1;
 
        /* Check for minor versions */
-       if (salt[1] != '$') {
-                switch (salt[1]) {
-                case 'a':      /* 'ab' should not yield the same as 'abab' */
-                case 'b':      /* cap input length at 72 bytes */
-                        minor = salt[1];
-                        salt++;
-                        if (salt[1] != '$')
-                                return -1;
-                        break;
-                default:
-                        return -1;
-                }
-       } else
-                minor = 0;
-
-       /* Discard version + "$" identifier */
-       salt += 2;
-
+       switch ((minor = salt[1])) {
+       case 'a':
+               key_len = (u_int8_t)(strlen(key) + 1);
+               break;
+       case 'b':
+               /* strlen() returns a size_t, but the function calls
+                * below result in implicit casts to a narrower integer
+                * type, so cap key_len at the actual maximum supported
+                * length here to avoid integer wraparound */
+               key_len = strlen(key);
+               if (key_len > 72)
+                       key_len = 72;
+               key_len++; /* include the NUL */
+               break;
+       default:
+                return -1;
+       }
        if (salt[2] != '$')
-               /* Out of sync with passwd entry */
                return -1;
+       /* Discard version + "$" identifier */
+       salt += 3;
 
-       memcpy(arounds, salt, sizeof(arounds));
-       if (arounds[sizeof(arounds) - 1] != '$')
+       /* Check and parse num rounds */
+       if (!isdigit((unsigned char)salt[0]) ||
+           !isdigit((unsigned char)salt[1]) || salt[2] != '$')
                return -1;
-       arounds[sizeof(arounds) - 1] = 0;
-       logr = strtonum(arounds, BCRYPT_MINLOGROUNDS, 31, NULL);
-       if (logr == 0)
+       logr = atoi(salt);
+       if (logr < BCRYPT_MINLOGROUNDS || logr > 31)
                return -1;
        /* Computer power doesn't increase linearly, 2^x should be fine */
        rounds = 1U << logr;
@@ -147,18 +146,6 @@ bcrypt_hashpass(const char *key, const c
        if (decode_base64(csalt, BCRYPT_MAXSALT, salt))
                return -1;
        salt_len = BCRYPT_MAXSALT;
-       if (minor <= 'a')
-               key_len = (u_int8_t)(strlen(key) + (minor >= 'a' ? 1 : 0));
-       else {
-               /* strlen() returns a size_t, but the function calls
-                * below result in implicit casts to a narrower integer
-                * type, so cap key_len at the actual maximum supported
-                * length here to avoid integer wraparound */
-               key_len = strlen(key);
-               if (key_len > 72)
-                       key_len = 72;
-               key_len++; /* include the NUL */
-       }
 
        /* Setting up S-Boxes and Subkeys */
        Blowfish_initstate(&state);
@@ -192,8 +179,7 @@ bcrypt_hashpass(const char *key, const c
        i = 0;
        encrypted[i++] = '$';
        encrypted[i++] = BCRYPT_VERSION;
-       if (minor)
-               encrypted[i++] = minor;
+       encrypted[i++] = minor;
        encrypted[i++] = '$';
 
        snprintf(encrypted + i, 4, "%2.2u$", logr);

Reply via email to