[git commit] libbb/yescrypt: actually, largest allowed salt is 86 chars, support that
Denys Vlasenko
vda.linux at googlemail.com
Thu Jul 17 15:01:40 UTC 2025
commit: https://git.busybox.net/busybox/commit/?id=b823735b7eb6428e827cf463123d3caaa48804ff
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master
function old new delta
yescrypt_r 767 756 -11
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
libbb/yescrypt/alg-yescrypt-common.c | 26 +++++++++++++++-----------
libbb/yescrypt/alg-yescrypt.h | 2 +-
testsuite/cryptpw.tests | 10 +++++++---
3 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/libbb/yescrypt/alg-yescrypt-common.c b/libbb/yescrypt/alg-yescrypt-common.c
index 1c063b895..c51823787 100644
--- a/libbb/yescrypt/alg-yescrypt-common.c
+++ b/libbb/yescrypt/alg-yescrypt-common.c
@@ -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;
diff --git a/libbb/yescrypt/alg-yescrypt.h b/libbb/yescrypt/alg-yescrypt.h
index 0b93945af..5051efbb4 100644
--- a/libbb/yescrypt/alg-yescrypt.h
+++ b/libbb/yescrypt/alg-yescrypt.h
@@ -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
diff --git a/testsuite/cryptpw.tests b/testsuite/cryptpw.tests
index beac35efe..83bfde521 100755
--- a/testsuite/cryptpw.tests
+++ b/testsuite/cryptpw.tests
@@ -97,9 +97,13 @@ testing 'cryptpw yescrypt with 4-char salt "...."' \
'cryptpw -m yescrypt qweRTY123 at -+ j9T\$....' \
'$y$j9T$....$wOnauYL2/NEtr6YQi9pi8AtV7L57sEbVOAnWJIcP9q2\n' \
'' ''
-testing 'cryptpw yescrypt with 84-char salt (max size)' \
- 'cryptpw -m yescrypt qweRTY123 at -+ 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 at -+ j9T\$123456789012345678901234567890123456789012345678901234567890123456789012345678901234z/' \
+ '$y$j9T$123456789012345678901234567890123456789012345678901234567890123456789012345678901234z/$Exxe8IoPXiddFsqj7iqCanRf8FyquAoB0/uceLmLjG.\n' \
'' ''
testing 'cryptpw yescrypt implicit' \
'cryptpw qweRTY123 at -+ \$y\$j9T\$123456789012345678901234' \
More information about the busybox-cvs
mailing list