[git commit] libbb/yescrypt: use common ascii64 encoding routine
Denys Vlasenko
vda.linux at googlemail.com
Sun Jul 6 20:43:28 UTC 2025
commit: https://git.busybox.net/busybox/commit/?id=53de6e6150ea5538930e1963eb87ada153093ea0
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master
function old new delta
num2str64_lsb_first 33 46 +13
yescrypt_r 1235 1133 -102
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 13/-102) Total: -89 bytes
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
include/libbb.h | 1 +
libbb/yescrypt/alg-yescrypt-common.c | 98 +++++++++++++-----------------------
libbb/yescrypt/alg-yescrypt.h | 4 +-
3 files changed, 37 insertions(+), 66 deletions(-)
diff --git a/include/libbb.h b/include/libbb.h
index 1c23d2f66..b761b1091 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2191,6 +2191,7 @@ void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC;
int FAST_FUNC i2a64(int i);
int FAST_FUNC a2i64(char c);
+char* FAST_FUNC num2str64_lsb_first(char *s, unsigned v, int n);
typedef struct md5_ctx_t {
uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
diff --git a/libbb/yescrypt/alg-yescrypt-common.c b/libbb/yescrypt/alg-yescrypt-common.c
index 435eaecca..5bdf1893e 100644
--- a/libbb/yescrypt/alg-yescrypt-common.c
+++ b/libbb/yescrypt/alg-yescrypt-common.c
@@ -19,8 +19,8 @@
*/
/* Not inlining:
- * decode64 fuinctions are only used to read
- * yescrypt_params_t field, and convert salt ti binary -
+ * de/encode64 functions are only used to read
+ * yescrypt_params_t field, and convert salt to binary -
* both of these are negligible compared to main hashing operation
*/
static NOINLINE const uint8_t *decode64_uint32(
@@ -63,56 +63,6 @@ fail:
return NULL;
}
-static uint8_t *encode64_uint32_fixed(
- uint8_t *dst, size_t dstlen,
- uint32_t src, uint32_t srcbits)
-{
- uint32_t bits;
-
- for (bits = 0; bits < srcbits; bits += 6) {
- if (dstlen < 2)
- return NULL;
- *dst++ = i2a64(src);
- dstlen--;
- src >>= 6;
- }
-
- if (src || dstlen < 1)
- return NULL;
-
- *dst = 0; /* NUL terminate just in case */
-
- return dst;
-}
-
-static uint8_t *encode64(
- uint8_t *dst, size_t dstlen,
- const uint8_t *src, size_t srclen)
-{
- size_t i;
-
- for (i = 0; i < srclen; ) {
- uint8_t *dnext;
- uint32_t value = 0, bits = 0;
- do {
- value |= (uint32_t)src[i++] << bits;
- bits += 8;
- } while (bits < 24 && i < srclen);
- dnext = encode64_uint32_fixed(dst, dstlen, value, bits);
- if (!dnext)
- return NULL;
- dstlen -= dnext - dst;
- dst = dnext;
- }
-
- if (dstlen < 1)
- return NULL;
-
- *dst = 0; /* NUL terminate just in case */
-
- return dst;
-}
-
static const uint8_t *decode64(
uint8_t *dst, size_t *dstlen,
const uint8_t *src, size_t srclen)
@@ -156,21 +106,43 @@ static const uint8_t *decode64(
*dstlen = dstpos;
return src;
}
-
fail:
*dstlen = 0;
return NULL;
}
-uint8_t *yescrypt_r(
+static char *encode64(
+ char *dst, size_t dstlen,
+ const uint8_t *src, size_t srclen)
+{
+ while (srclen) {
+ uint32_t value = 0, b = 0;
+ do {
+ value |= (uint32_t)(*src++ << b);
+ b += 8;
+ srclen--;
+ } while (srclen && b < 24);
+
+ b >>= 3; /* number of bits to number of bytes */
+ b++; /* 1, 2 or 3 bytes will become 2, 3 or 4 ascii64 chars */
+ dstlen -= b;
+ if ((ssize_t)dstlen <= 0)
+ return NULL;
+ dst = num2str64_lsb_first(dst, value, b);
+ }
+ *dst = '\0';
+ return dst;
+}
+
+char *yescrypt_r(
const uint8_t *passwd, size_t passwdlen,
const uint8_t *setting,
- uint8_t *buf, size_t buflen)
+ char *buf, size_t buflen)
{
yescrypt_ctx_t yctx[1];
unsigned char hashbin32[32];
+ char *dst;
const uint8_t *src, *saltstr, *saltend;
- uint8_t *dst;
size_t need, prefixlen, saltstrlen;
uint32_t flavor, N_log2;
@@ -241,11 +213,11 @@ uint8_t *yescrypt_r(
goto fail;
yctx->param.NROM = (uint64_t)1 << NROM_log2;
}
+ if (!src)
+ goto fail;
+ if (*src != '$')
+ goto fail;
}
- if (!src)
- goto fail;
- if (*src != '$')
- goto fail;
saltstr = src + 1;
src = (uint8_t *)strchrnul((char *)saltstr, '$');
@@ -268,16 +240,14 @@ uint8_t *yescrypt_r(
dst = mempcpy(buf, setting, prefixlen);
*dst++ = '$';
dst = encode64(dst, buflen - (dst - buf), hashbin32, sizeof(hashbin32));
- if (!dst || dst >= buf + buflen)
+ if (!dst)
goto fail;
-
- *dst = 0; /* NUL termination */
ret:
free_region(yctx->local);
explicit_bzero(yctx, sizeof(yctx));
explicit_bzero(hashbin32, sizeof(hashbin32));
return buf;
-fail:
+ fail:
buf = NULL;
goto ret;
}
diff --git a/libbb/yescrypt/alg-yescrypt.h b/libbb/yescrypt/alg-yescrypt.h
index 5b442c2c9..996af333f 100644
--- a/libbb/yescrypt/alg-yescrypt.h
+++ b/libbb/yescrypt/alg-yescrypt.h
@@ -151,8 +151,8 @@ typedef struct {
*
* MT-safe as long as local and buf are local to the thread.
*/
-extern uint8_t *yescrypt_r(
+extern char *yescrypt_r(
const uint8_t *passwd, size_t passwdlen,
const uint8_t *setting,
- uint8_t *buf, size_t buflen
+ char *buf, size_t buflen
);
More information about the busybox-cvs
mailing list