diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-04-07 09:48:18 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-04-07 09:48:18 -0400 |
commit | 2c86380bdec15272652607025a6fb46eb54aeef8 (patch) | |
tree | a296182ac5801d790b13e4e73bbdbcc6f20c3d33 /src | |
parent | 30b13fd82e243713c6a0d7bfbfc97d5faf8ee9c8 (diff) | |
parent | 681812ea40423f46c45f05d096ca01f346ff3fd9 (diff) | |
download | tor-2c86380bdec15272652607025a6fb46eb54aeef8.tar.gz tor-2c86380bdec15272652607025a6fb46eb54aeef8.zip |
Merge remote-tracking branch 'argonblue/baseXXlen'
Diffstat (limited to 'src')
-rw-r--r-- | src/common/util.h | 6 | ||||
-rw-r--r-- | src/common/util_format.c | 26 | ||||
-rw-r--r-- | src/common/util_format.h | 20 | ||||
-rw-r--r-- | src/or/shared_random.h | 9 |
4 files changed, 39 insertions, 22 deletions
diff --git a/src/common/util.h b/src/common/util.h index cfe47f07f2..18eb57f1bc 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -163,9 +163,9 @@ int64_t clamp_double_to_int64(double number); void simplify_fraction64(uint64_t *numer, uint64_t *denom); /* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b> - * and positive <b>b</b>. Works on integer types only. Not defined if a+b can - * overflow. */ -#define CEIL_DIV(a,b) (((a)+(b)-1)/(b)) + * and positive <b>b</b>. Works on integer types only. Not defined if a+(b-1) + * can overflow. */ +#define CEIL_DIV(a,b) (((a)+((b)-1))/(b)) /* Return <b>v</b> if it's between <b>min</b> and <b>max</b>. Otherwise * return <b>min</b> if <b>v</b> is smaller than <b>min</b>, or <b>max</b> if diff --git a/src/common/util_format.c b/src/common/util_format.c index 51b299b1ba..80844af5b3 100644 --- a/src/common/util_format.c +++ b/src/common/util_format.c @@ -28,7 +28,8 @@ size_t base32_encoded_size(size_t srclen) { size_t enclen; - enclen = CEIL_DIV(srclen*8, 5) + 1; + tor_assert(srclen < SIZE_T_CEILING / 8); + enclen = BASE32_NOPAD_BUFSIZE(srclen); tor_assert(enclen < INT_MAX && enclen > srclen); return enclen; } @@ -41,7 +42,6 @@ base32_encode(char *dest, size_t destlen, const char *src, size_t srclen) size_t nbits = srclen * 8; size_t bit; - tor_assert(srclen < SIZE_T_CEILING/8); /* We need enough space for the encoded data and the extra NUL byte. */ tor_assert(base32_encoded_size(srclen) <= destlen); tor_assert(destlen < SIZE_T_CEILING); @@ -133,6 +133,8 @@ base32_decode(char *dest, size_t destlen, const char *src, size_t srclen) /** Return the Base64 encoded size of <b>srclen</b> bytes of data in * bytes. * + * Does <b>NOT</b> count the terminating NUL. + * * If <b>flags</b>&BASE64_ENCODE_MULTILINE is true, return the size * of the encoded output as multiline output (64 character, `\n' terminated * lines). @@ -141,19 +143,16 @@ size_t base64_encode_size(size_t srclen, int flags) { size_t enclen; + + /* Use INT_MAX for overflow checking because base64_encode() returns int. */ tor_assert(srclen < INT_MAX); + tor_assert(CEIL_DIV(srclen, 3) < INT_MAX / 4); - if (srclen == 0) - return 0; + enclen = BASE64_LEN(srclen); + if (flags & BASE64_ENCODE_MULTILINE) + enclen += CEIL_DIV(enclen, BASE64_OPENSSL_LINELEN); - enclen = ((srclen - 1) / 3) * 4 + 4; - if (flags & BASE64_ENCODE_MULTILINE) { - size_t remainder = enclen % BASE64_OPENSSL_LINELEN; - enclen += enclen / BASE64_OPENSSL_LINELEN; - if (remainder) - enclen++; - } - tor_assert(enclen < INT_MAX && enclen > srclen); + tor_assert(enclen < INT_MAX && (enclen == 0 || enclen > srclen)); return enclen; } @@ -475,7 +474,8 @@ base16_encode(char *dest, size_t destlen, const char *src, size_t srclen) const char *end; char *cp; - tor_assert(destlen >= srclen*2+1); + tor_assert(srclen < SIZE_T_CEILING / 2 - 1); + tor_assert(destlen >= BASE16_BUFSIZE(srclen)); tor_assert(destlen < SIZE_T_CEILING); /* Make sure we leave no uninitialized data in the destination buffer. */ diff --git a/src/common/util_format.h b/src/common/util_format.h index 5fd82d6d99..c92805246f 100644 --- a/src/common/util_format.h +++ b/src/common/util_format.h @@ -10,6 +10,26 @@ #include "testsupport.h" #include "torint.h" +/** @{ */ +/** These macros don't check for overflow. Use them only for constant inputs + * (like array declarations). The *_LEN macros are the raw encoding lengths + * (without terminating NUL), while the *_BUFSIZE macros count the terminating + * NUL. */ +#define BASE64_LEN(n) (CEIL_DIV((n), 3) * 4) +#define BASE32_LEN(n) (CEIL_DIV((n), 5) * 8) +#define BASE16_LEN(n) ((n) * 2) + +#define BASE64_BUFSIZE(n) (BASE64_LEN(n) + 1) +#define BASE32_BUFSIZE(n) (BASE32_LEN(n) + 1) +#define BASE16_BUFSIZE(n) (BASE16_LEN(n) + 1) + +#define BASE64_NOPAD_LEN(n) (CEIL_DIV((n) * 4, 3) +#define BASE32_NOPAD_LEN(n) (CEIL_DIV((n) * 8, 5) + +#define BASE64_NOPAD_BUFSIZE(n) (BASE64_NOPAD_LEN(n) + 1)) +#define BASE32_NOPAD_BUFSIZE(n) (BASE32_NOPAD_LEN(n) + 1)) +/** @} */ + #define BASE64_ENCODE_MULTILINE 1 size_t base64_encode_size(size_t srclen, int flags); int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen, diff --git a/src/or/shared_random.h b/src/or/shared_random.h index ae390c469e..1f027c70e0 100644 --- a/src/or/shared_random.h +++ b/src/or/shared_random.h @@ -36,17 +36,14 @@ /* Length of base64 encoded commit NOT including the NUL terminated byte. * Formula is taken from base64_encode_size. This adds up to 56 bytes. */ -#define SR_COMMIT_BASE64_LEN \ - (((SR_COMMIT_LEN - 1) / 3) * 4 + 4) +#define SR_COMMIT_BASE64_LEN (BASE64_LEN(SR_COMMIT_LEN)) /* Length of base64 encoded reveal NOT including the NUL terminated byte. * Formula is taken from base64_encode_size. This adds up to 56 bytes. */ -#define SR_REVEAL_BASE64_LEN \ - (((SR_REVEAL_LEN - 1) / 3) * 4 + 4) +#define SR_REVEAL_BASE64_LEN (BASE64_LEN(SR_REVEAL_LEN)) /* Length of base64 encoded shared random value. It's 32 bytes long so 44 * bytes from the base64_encode_size formula. That includes the '=' * character at the end. */ -#define SR_SRV_VALUE_BASE64_LEN \ - (((DIGEST256_LEN - 1) / 3) * 4 + 4) +#define SR_SRV_VALUE_BASE64_LEN (BASE64_LEN(DIGEST256_LEN)) /* Assert if commit valid flag is not set. */ #define ASSERT_COMMIT_VALID(c) tor_assert((c)->valid) |