From d5574a69faf88339c27165892d368d5cbe95bdd1 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 17 Aug 2017 20:54:20 +0200 Subject: [PATCH] Complete sodium_pad/unpad() and add a couple tests --- src/libsodium/sodium/utils.c | 13 +++++++------ test/default/sodium_utils.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/libsodium/sodium/utils.c b/src/libsodium/sodium/utils.c index 66b1b1c0..8f5a932a 100644 --- a/src/libsodium/sodium/utils.c +++ b/src/libsodium/sodium/utils.c @@ -664,25 +664,26 @@ sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf, { const unsigned char *tail; unsigned char acc = 0U; - unsigned char barrier_mask; unsigned char c; unsigned char valid = 0U; volatile size_t pad_len = 0U; size_t i; + size_t is_barrier; if (padded_buflen < blocksize || blocksize <= 0U) { return -1; } tail = &buf[padded_buflen - 1U]; + for (i = 0U; i < blocksize; i++) { c = tail[-i]; + is_barrier = + (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U; acc |= c; - barrier_mask = - ( (~(acc - 1U)) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8; - pad_len |= i & barrier_mask; - valid |= barrier_mask; + pad_len |= (i & - is_barrier); + valid |= (unsigned char) is_barrier; } *unpadded_buflen_p = padded_buflen - 1U - pad_len; - return (int) (valid & 1U) - 1; + return (int) (valid - 1U); } diff --git a/test/default/sodium_utils.c b/test/default/sodium_utils.c index 09c22544..8d6c16ab 100644 --- a/test/default/sodium_utils.c +++ b/test/default/sodium_utils.c @@ -17,11 +17,15 @@ main(void) char *b64_; const char *b64_end; unsigned char *bin; + unsigned char *bin_padded; const char *hex; const char *hex_end; size_t b64_len; - size_t bin_len; + size_t bin_len, bin_len2; size_t hex_len; + size_t bin_padded_len; + size_t bin_padded_maxlen; + size_t blocksize; unsigned int i; unsigned int j; @@ -281,5 +285,34 @@ main(void) printf("%s\n", sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + for (i = 0; i < 2000U; i++) { + bin_len = randombytes_uniform(200U); + bin = sodium_malloc(bin_len); + randombytes_buf(bin, bin_len); + blocksize = 1U + randombytes_uniform(100U); + bin_padded_maxlen = bin_len + (blocksize - bin_len % blocksize); + bin_padded = sodium_malloc(bin_padded_maxlen); + + memcpy(bin_padded, bin, bin_len); + assert(sodium_pad(&bin_padded_len, bin_padded, bin_len, + blocksize, bin_padded_maxlen - 1U) == -1); + assert(sodium_pad(&bin_padded_len, bin_padded, bin_len, + blocksize, bin_padded_maxlen + 1U) == 0); + assert(sodium_pad(&bin_padded_len, bin_padded, bin_len, + blocksize, bin_padded_maxlen) == 0); + assert(bin_padded_len == bin_padded_maxlen); + + assert(sodium_unpad(&bin_len2, bin_padded, bin_padded_len, + 0U) == -1); + assert(sodium_unpad(&bin_len2, bin_padded, bin_padded_len, + bin_padded_len + 1U) == -1); + assert(sodium_unpad(&bin_len2, bin_padded, bin_padded_len, + blocksize) == 0); + assert(bin_len2 == bin_len); + + sodium_free(bin_padded); + sodium_free(bin); + } + return 0; }