diff options
author | Nick Mathewson <nickm@torproject.org> | 2016-06-17 13:53:57 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2016-06-17 13:53:57 -0400 |
commit | 48b25e6811bb822542ea898e30aebc75e185f29d (patch) | |
tree | 4dfd97599024d2df35f4f56471a40bf6e518c3d7 /src/common | |
parent | 94762e37b950f3ce1696c78dd4f7a89b6d05f1ac (diff) | |
parent | f4f9a9be40877cbd3d4311ba696a07d316760095 (diff) | |
download | tor-48b25e6811bb822542ea898e30aebc75e185f29d.tar.gz tor-48b25e6811bb822542ea898e30aebc75e185f29d.zip |
Merge branch 'bug18280_029_03_nm_squashed'
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/util_format.c | 36 | ||||
-rw-r--r-- | src/common/util_format.h | 1 |
2 files changed, 25 insertions, 12 deletions
diff --git a/src/common/util_format.c b/src/common/util_format.c index 2dea187e40..f343a9d921 100644 --- a/src/common/util_format.c +++ b/src/common/util_format.c @@ -21,33 +21,46 @@ #include <string.h> #include <stdlib.h> -/** Implements base32 encoding as in RFC 4648. Limitation: Requires - * that srclen*8 is a multiple of 5. - */ + +/* Return the base32 encoded size in bytes using the source length srclen. + * The NUL terminated byte is added as well since every base32 encoding + * requires enough space for it. */ +size_t +base32_encoded_size(size_t srclen) +{ + size_t enclen; + enclen = CEIL_DIV(srclen*8, 5) + 1; + tor_assert(enclen < INT_MAX && enclen > srclen); + return enclen; +} + +/** Implements base32 encoding as in RFC 4648. */ void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen) { unsigned int i, v, u; - size_t nbits = srclen * 8, bit; + size_t nbits = srclen * 8; + size_t bit; tor_assert(srclen < SIZE_T_CEILING/8); - tor_assert((nbits%5) == 0); /* We need an even multiple of 5 bits. */ - tor_assert((nbits/5)+1 <= destlen); /* We need enough space. */ + /* 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); for (i=0,bit=0; bit < nbits; ++i, bit+=5) { /* set v to the 16-bit value starting at src[bits/8], 0-padded. */ v = ((uint8_t)src[bit/8]) << 8; - if (bit+5<nbits) v += (uint8_t)src[(bit/8)+1]; - /* set u to the 5-bit value at the bit'th bit of src. */ + if (bit+5<nbits) + v += (uint8_t)src[(bit/8)+1]; + /* set u to the 5-bit value at the bit'th bit of buf. */ u = (v >> (11-(bit%8))) & 0x1F; dest[i] = BASE32_CHARS[u]; } dest[i] = '\0'; } -/** Implements base32 decoding as in RFC 4648. Limitation: Requires - * that srclen*5 is a multiple of 8. Returns 0 if successful, -1 otherwise. +/** Implements base32 decoding as in RFC 4648. + * Returns 0 if successful, -1 otherwise. */ int base32_decode(char *dest, size_t destlen, const char *src, size_t srclen) @@ -57,10 +70,9 @@ base32_decode(char *dest, size_t destlen, const char *src, size_t srclen) unsigned int i; size_t nbits, j, bit; char *tmp; - nbits = srclen * 5; + nbits = ((srclen * 5) / 8) * 8; tor_assert(srclen < SIZE_T_CEILING / 5); - tor_assert((nbits%8) == 0); /* We need an even multiple of 8 bits. */ tor_assert((nbits/8) <= destlen); /* We need enough space. */ tor_assert(destlen < SIZE_T_CEILING); diff --git a/src/common/util_format.h b/src/common/util_format.h index a748a4f3cf..20ac711d10 100644 --- a/src/common/util_format.h +++ b/src/common/util_format.h @@ -24,6 +24,7 @@ int base64_decode_nopad(uint8_t *dest, size_t destlen, #define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base32_decode(char *dest, size_t destlen, const char *src, size_t srclen); +size_t base32_encoded_size(size_t srclen); int hex_decode_digit(char c); void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen); |