diff options
Diffstat (limited to 'src/common/base32hex.c')
-rw-r--r-- | src/common/base32hex.c | 102 |
1 files changed, 60 insertions, 42 deletions
diff --git a/src/common/base32hex.c b/src/common/base32hex.c index 456d79b..e1af3c7 100644 --- a/src/common/base32hex.c +++ b/src/common/base32hex.c @@ -14,7 +14,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <config.h> #include "base32hex.h" +#include "errcode.h" #include <stdlib.h> // malloc #include <stdint.h> // uint8_t @@ -80,9 +82,9 @@ const uint8_t base32hex_dec[256] = { }; int32_t base32hex_encode(const uint8_t *in, - const uint32_t in_len, - uint8_t *out, - const uint32_t out_len) + const uint32_t in_len, + uint8_t *out, + const uint32_t out_len) { uint8_t rest_len = in_len % 5; const uint8_t *data = in; @@ -91,9 +93,11 @@ int32_t base32hex_encode(const uint8_t *in, uint8_t num; // Checking inputs. - if (in == NULL || out == NULL || in_len > MAX_BIN_DATA_LEN || - out_len < ((in_len + 4) / 5) * 8) { - return -1; + if (in == NULL || out == NULL) { + return KNOT_EINVAL; + } + if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 4) / 5) * 8) { + return KNOT_ERANGE; } // Encoding loop takes 5 bytes and creates 8 characters. @@ -138,7 +142,7 @@ int32_t base32hex_encode(const uint8_t *in, // Processing of padding, if any. switch (rest_len) { // Input data has 4-byte last block => 1-char padding. - case 4: + case 4: // Computing 1. Base32hex character. num = *data >> 3; *text++ = base32hex_enc[num]; @@ -175,7 +179,7 @@ int32_t base32hex_encode(const uint8_t *in, break; // Input data has 3-byte last block => 3-char padding. - case 3: + case 3: // Computing 1. Base32hex character. num = *data >> 3; *text++ = base32hex_enc[num]; @@ -205,7 +209,7 @@ int32_t base32hex_encode(const uint8_t *in, break; // Input data has 2-byte last block => 4-char padding. - case 2: + case 2: // Computing 1. Base32hex character. num = *data >> 3; *text++ = base32hex_enc[num]; @@ -231,7 +235,7 @@ int32_t base32hex_encode(const uint8_t *in, break; // Input data has 1-byte last block => 6-char padding. - case 1: + case 1: // Computing 1. Base32hex character. num = *data >> 3; *text++ = base32hex_enc[num]; @@ -255,31 +259,36 @@ int32_t base32hex_encode(const uint8_t *in, } int32_t base32hex_encode_alloc(const uint8_t *in, - const uint32_t in_len, - uint8_t **out) + const uint32_t in_len, + uint8_t **out) { - uint32_t out_len = ((in_len + 4) / 5) * 8; - - // Checking inputs. + // Check input (output is longer). if (in_len > MAX_BIN_DATA_LEN) { - return -1; + return KNOT_ERANGE; } - // Allocating output buffer. - *out = malloc(out_len); + // Compute output buffer length. + uint32_t out_len = ((in_len + 4) / 5) * 8; + // Allocate output buffer. + *out = malloc(out_len); if (*out == NULL) { - return -1; + return KNOT_ENOMEM; } - // Encoding data. - return base32hex_encode(in, in_len, *out, out_len); + // Encode data. + int32_t ret = base32hex_encode(in, in_len, *out, out_len); + if (ret < 0) { + free(*out); + } + + return ret; } int32_t base32hex_decode(const uint8_t *in, - const uint32_t in_len, - uint8_t *out, - const uint32_t out_len) + const uint32_t in_len, + uint8_t *out, + const uint32_t out_len) { const uint8_t *data = in; const uint8_t *stop = in + in_len; @@ -288,9 +297,14 @@ int32_t base32hex_decode(const uint8_t *in, uint8_t c1, c2, c3, c4, c5, c6, c7, c8; // Checking inputs. - if (in == NULL || out == NULL || (in_len % 8) != 0 || - in_len > INT32_MAX || out_len < ((in_len + 7) / 8) * 5) { - return -1; + if (in == NULL || out == NULL) { + return KNOT_EINVAL; + } + if (in_len > INT32_MAX || out_len < ((in_len + 7) / 8) * 5) { + return KNOT_ERANGE; + } + if ((in_len % 8) != 0) { + return KNOT_BASE32HEX_ESIZE; } // Decoding loop takes 8 characters and creates 5 bytes. @@ -310,7 +324,7 @@ int32_t base32hex_decode(const uint8_t *in, if (c8 == PD) { pad_len = 1; } else { - return -2; + return KNOT_BASE32HEX_ECHAR; } } @@ -319,7 +333,7 @@ int32_t base32hex_decode(const uint8_t *in, if (c7 == PD && c6 == PD) { pad_len = 3; } else { - return -2; + return KNOT_BASE32HEX_ECHAR; } } @@ -328,7 +342,7 @@ int32_t base32hex_decode(const uint8_t *in, if (c6 == PD) { pad_len = 3; } else { - return -2; + return KNOT_BASE32HEX_ECHAR; } } @@ -337,7 +351,7 @@ int32_t base32hex_decode(const uint8_t *in, if (c5 == PD) { pad_len = 4; } else { - return -2; + return KNOT_BASE32HEX_ECHAR; } } @@ -346,7 +360,7 @@ int32_t base32hex_decode(const uint8_t *in, if (c4 == PD && c3 == PD) { pad_len = 6; } else { - return -2; + return KNOT_BASE32HEX_ECHAR; } } @@ -355,13 +369,13 @@ int32_t base32hex_decode(const uint8_t *in, if (c3 == PD) { pad_len = 6; } else { - return -2; + return KNOT_BASE32HEX_ECHAR; } } // 1. and 2. chars must not be padding. if (c2 >= PD || c1 >= PD) { - return -2; + return KNOT_BASE32HEX_ECHAR; } // Computing of output data based on padding length. @@ -403,19 +417,23 @@ int32_t base32hex_decode(const uint8_t *in, } int32_t base32hex_decode_alloc(const uint8_t *in, - const uint32_t in_len, - uint8_t **out) + const uint32_t in_len, + uint8_t **out) { + // Compute output buffer length. uint32_t out_len = ((in_len + 7) / 8) * 5; - // Allocating output buffer. + // Allocate output buffer. *out = malloc(out_len); - if (*out == NULL) { - return -1; + return KNOT_ENOMEM; } - // Decoding data. - return base32hex_decode(in, in_len, *out, out_len); -} + // Decode data. + int32_t ret = base32hex_decode(in, in_len, *out, out_len); + if (ret < 0) { + free(*out); + } + return ret; +} |