summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-04-07 09:48:18 -0400
committerNick Mathewson <nickm@torproject.org>2017-04-07 09:48:18 -0400
commit2c86380bdec15272652607025a6fb46eb54aeef8 (patch)
treea296182ac5801d790b13e4e73bbdbcc6f20c3d33
parent30b13fd82e243713c6a0d7bfbfc97d5faf8ee9c8 (diff)
parent681812ea40423f46c45f05d096ca01f346ff3fd9 (diff)
downloadtor-2c86380bdec15272652607025a6fb46eb54aeef8.tar.gz
tor-2c86380bdec15272652607025a6fb46eb54aeef8.zip
Merge remote-tracking branch 'argonblue/baseXXlen'
-rw-r--r--src/common/util.h6
-rw-r--r--src/common/util_format.c26
-rw-r--r--src/common/util_format.h20
-rw-r--r--src/or/shared_random.h9
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>&amp;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)