diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-07-08 03:36:17 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-07-08 03:47:48 +0200 |
| commit | 78bd8a44b75cf39ea17c8a586ba35776d835551f (patch) | |
| tree | 8ac165cc8166c4bfa12b5e13833f76296010f7d0 /libbb | |
| parent | d18ac080e4bb7d63e0ec0dea16bacc6ac455f390 (diff) | |
| download | busybox-w32-78bd8a44b75cf39ea17c8a586ba35776d835551f.tar.gz busybox-w32-78bd8a44b75cf39ea17c8a586ba35776d835551f.tar.bz2 busybox-w32-78bd8a44b75cf39ea17c8a586ba35776d835551f.zip | |
libbb/yescrypt: explain and shrink decode64_uint32()
function old new delta
decode64_uint32 177 141 -36
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/yescrypt/alg-yescrypt-common.c | 87 | ||||
| -rw-r--r-- | libbb/yescrypt/alg-yescrypt.h | 2 |
2 files changed, 79 insertions, 10 deletions
diff --git a/libbb/yescrypt/alg-yescrypt-common.c b/libbb/yescrypt/alg-yescrypt-common.c index e5d045058..c85b2a0b9 100644 --- a/libbb/yescrypt/alg-yescrypt-common.c +++ b/libbb/yescrypt/alg-yescrypt-common.c | |||
| @@ -27,41 +27,106 @@ static NOINLINE const uint8_t *decode64_uint32( | |||
| 27 | uint32_t *dst, | 27 | uint32_t *dst, |
| 28 | const uint8_t *src, uint32_t val) | 28 | const uint8_t *src, uint32_t val) |
| 29 | { | 29 | { |
| 30 | uint32_t start = 0, end = 47, chars = 1, bits = 0; | 30 | uint32_t start = 0, end = 47, bits = 0; |
| 31 | uint32_t c; | 31 | uint32_t c; |
| 32 | 32 | ||
| 33 | if (!src) /* prevous decode failed already? */ | 33 | if (!src) /* previous decode failed already? */ |
| 34 | goto fail; | 34 | goto fail; |
| 35 | 35 | ||
| 36 | c = a2i64(*src++); | 36 | c = a2i64(*src++); |
| 37 | if (c > 63) | 37 | if (c > 63) |
| 38 | goto fail; | 38 | goto fail; |
| 39 | 39 | ||
| 40 | // The encoding of number N: | ||
| 41 | // start = 0 end = 47 | ||
| 42 | // If N < 48, it is encoded verbatim, else | ||
| 43 | // N -= 48 | ||
| 44 | // start = end+1 = 48 | ||
| 45 | // end += (64-end)/2 = 55 | ||
| 46 | // If N < (end+1-start)<<6 = 8<<6, it is encoded as 48+(N>>6)|low6bits (that is, 48...55|<6bit>), else | ||
| 47 | // N -= 8<<6 | ||
| 48 | // start = end+1 = 56 | ||
| 49 | // end += (64-end)/2 = 59 | ||
| 50 | // If N < (end+1-start)<<2*6 = 4<<12, it is encoded as 56+(N>>2*6)|low12bits (that is, 56...59|<6bit>|<6bit>), else | ||
| 51 | // ...same for 60..61|<6bit>|<6bit>|<6bit> | ||
| 52 | // .......same for 62|<6bit>|<6bit>|<6bit>|<6bit> | ||
| 53 | // .......same for 63|<6bit>|<6bit>|<6bit>|<6bit>|<6bit> | ||
| 54 | dbg_dec64("c:%d val:0x%08x", (int)c, (unsigned)val); | ||
| 40 | while (c > end) { | 55 | while (c > end) { |
| 56 | dbg_dec64("c:%d > end:%d", (int)c, (int)end); | ||
| 41 | val += (end + 1 - start) << bits; | 57 | val += (end + 1 - start) << bits; |
| 58 | dbg_dec64("val+=0x%08x", (int)((end + 1 - start) << bits)); | ||
| 59 | dbg_dec64(" val:0x%08x", (unsigned)val); | ||
| 42 | start = end + 1; | 60 | start = end + 1; |
| 43 | end = start + (62 - end) / 2; | 61 | end += (64 - end) / 2; |
| 44 | chars++; | ||
| 45 | bits += 6; | 62 | bits += 6; |
| 63 | dbg_dec64("start=%d", (int)start); | ||
| 64 | dbg_dec64("end=%d", (int)end); | ||
| 65 | dbg_dec64("bits=%d", (int)bits); | ||
| 46 | } | 66 | } |
| 47 | 67 | ||
| 48 | val += (c - start) << bits; | 68 | val += (c - start) << bits; |
| 69 | dbg_dec64("final val+=0x%08x", (int)((c - start) << bits)); | ||
| 70 | dbg_dec64(" val:0x%08x", (unsigned)val); | ||
| 49 | 71 | ||
| 50 | while (--chars) { | 72 | while (bits != 0) { |
| 51 | c = a2i64(*src++); | 73 | c = a2i64(*src++); |
| 52 | if (c > 63) | 74 | if (c > 63) |
| 53 | goto fail; | 75 | goto fail; |
| 54 | bits -= 6; | 76 | bits -= 6; |
| 55 | val += c << bits; | 77 | val += c << bits; |
| 78 | dbg_dec64("low bits val+=0x%08x", (int)(c << bits)); | ||
| 79 | dbg_dec64(" val:0x%08x", (unsigned)val); | ||
| 56 | } | 80 | } |
| 81 | ret: | ||
| 57 | *dst = val; | 82 | *dst = val; |
| 58 | |||
| 59 | return src; | 83 | return src; |
| 84 | fail: | ||
| 85 | val = 0; | ||
| 86 | src = NULL; | ||
| 87 | goto ret; | ||
| 88 | } | ||
| 60 | 89 | ||
| 61 | fail: | 90 | #if TEST_DECODE64 |
| 62 | *dst = 0; | 91 | static void test_decode64_uint32(void) |
| 63 | return NULL; | 92 | { |
| 93 | const uint8_t *src, *end; | ||
| 94 | uint32_t u32; | ||
| 95 | int a = 48; | ||
| 96 | int b = 8<<6; // 0x0200 | ||
| 97 | int c = 4<<12; // 0x04000 | ||
| 98 | int d = 2<<18; // 0x080000 | ||
| 99 | int e = 1<<24; // 0x1000000 | ||
| 100 | |||
| 101 | src = (void*)"wzzz"; | ||
| 102 | end = decode64_uint32(&u32, src, 0); | ||
| 103 | if (u32 != 0x0003ffff+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32); | ||
| 104 | if (end != src + 4) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end); | ||
| 105 | src = (void*)"xzzz"; | ||
| 106 | end = decode64_uint32(&u32, src, 0); | ||
| 107 | if (u32 != 0x0007ffff+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32); | ||
| 108 | if (end != src + 4) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end); | ||
| 109 | // Note how the last representable "x---" encoding, 0x7ffff, is exactly d-1! | ||
| 110 | // And if we now increment it, we get: | ||
| 111 | src = (void*)"y...."; | ||
| 112 | end = decode64_uint32(&u32, src, 0); | ||
| 113 | if (u32 != 0x00000000+d+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32); | ||
| 114 | if (end != src + 5) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end); | ||
| 115 | src = (void*)"yzzzz"; | ||
| 116 | end = decode64_uint32(&u32, src, 0); | ||
| 117 | if (u32 != 0x00ffffff+d+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32); | ||
| 118 | if (end != src + 5) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end); | ||
| 119 | |||
| 120 | src = (void*)"zzzzzz"; | ||
| 121 | end = decode64_uint32(&u32, src, 0); | ||
| 122 | if (u32 != 0x3fffffff+e+d+c+b+a) bb_error_msg_and_die("Incorrect decode '%s':0x%08x", src, (unsigned)u32); | ||
| 123 | if (end != src + 6) bb_error_msg_and_die("Incorrect decode '%s': %p end:%p", src, src, end); | ||
| 124 | |||
| 125 | bb_error_msg("test_decode64_uint32() OK"); | ||
| 64 | } | 126 | } |
| 127 | #else | ||
| 128 | # define test_decode64_uint32() ((void)0) | ||
| 129 | #endif | ||
| 65 | 130 | ||
| 66 | #if 1 | 131 | #if 1 |
| 67 | static const uint8_t *decode64( | 132 | static const uint8_t *decode64( |
| @@ -70,7 +135,7 @@ static const uint8_t *decode64( | |||
| 70 | { | 135 | { |
| 71 | size_t dstpos = 0; | 136 | size_t dstpos = 0; |
| 72 | 137 | ||
| 73 | dbg_dec64("src:'%s' len:%d", src, (int)srclen); | 138 | dbg_dec64("src:'%s'", src); |
| 74 | for (;;) { | 139 | for (;;) { |
| 75 | uint32_t c, value = 0; | 140 | uint32_t c, value = 0; |
| 76 | int bits = 0; | 141 | int bits = 0; |
| @@ -215,6 +280,8 @@ char *yescrypt_r( | |||
| 215 | size_t need, prefixlen; | 280 | size_t need, prefixlen; |
| 216 | uint32_t u32; | 281 | uint32_t u32; |
| 217 | 282 | ||
| 283 | test_decode64_uint32(); | ||
| 284 | |||
| 218 | memset(yctx, 0, sizeof(yctx)); | 285 | memset(yctx, 0, sizeof(yctx)); |
| 219 | yctx->param.p = 1; | 286 | yctx->param.p = 1; |
| 220 | 287 | ||
diff --git a/libbb/yescrypt/alg-yescrypt.h b/libbb/yescrypt/alg-yescrypt.h index 4554e3de3..e558cfdc5 100644 --- a/libbb/yescrypt/alg-yescrypt.h +++ b/libbb/yescrypt/alg-yescrypt.h | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | * online backup system. | 28 | * online backup system. |
| 29 | */ | 29 | */ |
| 30 | #ifdef YESCRYPT_INTERNAL | 30 | #ifdef YESCRYPT_INTERNAL |
| 31 | |||
| 31 | # if 1 | 32 | # if 1 |
| 32 | # define dbg(...) ((void)0) | 33 | # define dbg(...) ((void)0) |
| 33 | # else | 34 | # else |
| @@ -39,6 +40,7 @@ | |||
| 39 | # define dbg_dec64(...) bb_error_msg(__VA_ARGS__) | 40 | # define dbg_dec64(...) bb_error_msg(__VA_ARGS__) |
| 40 | # endif | 41 | # endif |
| 41 | #endif | 42 | #endif |
| 43 | #define TEST_DECODE64 0 | ||
| 42 | 44 | ||
| 43 | /** | 45 | /** |
| 44 | * Type and possible values for the flags argument of yescrypt_kdf(), | 46 | * Type and possible values for the flags argument of yescrypt_kdf(), |
