libbb/yescrypt: actually, largest allowed salt is 86 chars, support that
No binary (build failed)
—
(log yok)
| @@ -152,13 +152,13 @@ static const uint8_t *decode64( | |
| uint8_t *dst, size_t *dstlen, | |
| const uint8_t *src) | |
| { | |
| - | size_t dstpos = 0; |
| + | unsigned dstpos = 0; |
| dbg_dec64("src:'%s'", src); | |
| for (;;) { | |
| uint32_t c, value = 0; | |
| int bits = 0; | |
| - | while (*src && *src != '$') { |
| + | while (*src != '\0' && *src != '$') { |
| c = a2i64(*src); | |
| if (c > 63) { /* bad ascii64 char, stop decoding at it */ | |
| break; | |
| @@ -174,9 +174,11 @@ static const uint8_t *decode64( | |
| break; | |
| /* else: we got last, partial bit block - store it */ | |
| store: | |
| - | dbg_dec64(" storing bits:%d v:%08x", bits, (int)SWAP_BE32(value)); //BE to see lsb first |
| - | while (dstpos < *dstlen) { |
| - | if ((!*src || *src == '$') && value == 0 && bits < 8) { |
| + | dbg_dec64(" storing bits:%d dstpos:%u v:%08x", bits, dstpos, (int)SWAP_BE32(value)); //BE to see lsb first |
| + | for (;;) { |
| + | if ((*src == '\0' || *src == '$') |
| + | && value == 0 && bits < 8 |
| + | ) { |
| /* Example: mkpasswd PWD '$y$j9T$123': | |
| * the "123" is bits:18 value:03,51,00 | |
| * is considered to be 2 bytes, not 3! | |
| @@ -190,17 +192,18 @@ static const uint8_t *decode64( | |
| */ | |
| goto end; | |
| } | |
| - | dstpos++; |
| + | if (dstpos >= *dstlen) { |
| + | dbg_dec64(" ERR: bits:%d dstpos:%u dst[] is too small", bits, dstpos); |
| + | goto fail; |
| + | } |
| *dst++ = value; | |
| + | dstpos++; |
| value >>= 8; | |
| bits -= 8; | |
| if (bits <= 0) /* can get negative, if we e.g. had 6 bits */ | |
| - | goto next; |
| + | break; |
| } | |
| - | dbg_dec64(" ERR: bits:%d dst[] is too small", bits); |
| - | goto fail; |
| - | next: |
| - | if (!*src || *src == '$') |
| + | if (*src == '\0' || *src == '$') |
| break; | |
| } | |
| end: | |
| @@ -376,6 +379,7 @@ char *yescrypt_r( | |
| saltend = decode64(yctx->salt, &yctx->saltlen, src); | |
| if (!saltend || (*saltend != '\0' && *saltend != '$')) | |
| goto fail; /* salt[] is too small, or bad char during decode */ | |
| + | dbg_dec64("salt is %d ascii64 chars -> %d bytes (in binary)", (int)(saltend - src), (int)yctx->saltlen); |
| prefixlen = saltend - setting; | |
| need = prefixlen + 1 + YESCRYPT_HASH_LEN + 1; | |
| @@ -139,7 +139,7 @@ | |
| #define YESCRYPT_GATHER_8 0x018 //gg=11 | |
| #define YESCRYPT_SIMPLE_1 0x000 //ss=00 | |
| #define YESCRYPT_SIMPLE_2 0x020 //ss=01 | |
| - | #define YESCRYPT_SIMPLE_4 0x040 //ss=11 |
| + | #define YESCRYPT_SIMPLE_4 0x040 //ss=10 |
| #define YESCRYPT_SIMPLE_8 0x060 //ss=11 | |
| #define YESCRYPT_SBOX_6K 0x000 //sbox=0000 | |
| #define YESCRYPT_SBOX_12K 0x080 //sbox=0001 | |
| @@ -97,9 +97,13 @@ testing 'cryptpw yescrypt with 4-char salt "...."' \ | |
| 'cryptpw -m yescrypt qweRTY123@-+ j9T\$....' \ | |
| '$y$j9T$....$wOnauYL2/NEtr6YQi9pi8AtV7L57sEbVOAnWJIcP9q2\n' \ | |
| '' '' | |
| - | testing 'cryptpw yescrypt with 84-char salt (max size)' \ |
| - | 'cryptpw -m yescrypt qweRTY123@-+ j9T\$123456789012345678901234567890123456789012345678901234567890123456789012345678901234' \ |
| - | '$y$j9T$123456789012345678901234567890123456789012345678901234567890123456789012345678901234$ubrUuPCpI97LIMlVMt/A0Mhs/kBK2UBJYcQSxEZSlz4\n' \ |
| + | # 84 chars = 21 4-char blocks which decode into 21*3 = 63 bytes. |
| + | # The last byte of the maximum allowed salt size has to come from an incomplete |
| + | # char block. E.g. "z/" encodes byte 0x7f. "z1" is 0xff. |
| + | # Anything larger (e.g. "z2") is an error (it encodes 0x13f). |
| + | testing 'cryptpw yescrypt with 86-char salt (max size)' \ |
| + | 'cryptpw -m yescrypt qweRTY123@-+ j9T\$123456789012345678901234567890123456789012345678901234567890123456789012345678901234z/' \ |
| + | '$y$j9T$123456789012345678901234567890123456789012345678901234567890123456789012345678901234z/$Exxe8IoPXiddFsqj7iqCanRf8FyquAoB0/uceLmLjG.\n' \ |
| '' '' | |
| testing 'cryptpw yescrypt implicit' \ | |
| 'cryptpw qweRTY123@-+ \$y\$j9T\$123456789012345678901234' \ | |