Complete sodium_pad/unpad() and add a couple tests

This commit is contained in:
Frank Denis 2017-08-17 20:54:20 +02:00
parent b9ed93fcb8
commit d5574a69fa
2 changed files with 41 additions and 7 deletions

View File

@ -664,25 +664,26 @@ sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf,
{ {
const unsigned char *tail; const unsigned char *tail;
unsigned char acc = 0U; unsigned char acc = 0U;
unsigned char barrier_mask;
unsigned char c; unsigned char c;
unsigned char valid = 0U; unsigned char valid = 0U;
volatile size_t pad_len = 0U; volatile size_t pad_len = 0U;
size_t i; size_t i;
size_t is_barrier;
if (padded_buflen < blocksize || blocksize <= 0U) { if (padded_buflen < blocksize || blocksize <= 0U) {
return -1; return -1;
} }
tail = &buf[padded_buflen - 1U]; tail = &buf[padded_buflen - 1U];
for (i = 0U; i < blocksize; i++) { for (i = 0U; i < blocksize; i++) {
c = tail[-i]; c = tail[-i];
is_barrier =
(( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U;
acc |= c; acc |= c;
barrier_mask = pad_len |= (i & - is_barrier);
( (~(acc - 1U)) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8; valid |= (unsigned char) is_barrier;
pad_len |= i & barrier_mask;
valid |= barrier_mask;
} }
*unpadded_buflen_p = padded_buflen - 1U - pad_len; *unpadded_buflen_p = padded_buflen - 1U - pad_len;
return (int) (valid & 1U) - 1; return (int) (valid - 1U);
} }

View File

@ -17,11 +17,15 @@ main(void)
char *b64_; char *b64_;
const char *b64_end; const char *b64_end;
unsigned char *bin; unsigned char *bin;
unsigned char *bin_padded;
const char *hex; const char *hex;
const char *hex_end; const char *hex_end;
size_t b64_len; size_t b64_len;
size_t bin_len; size_t bin_len, bin_len2;
size_t hex_len; size_t hex_len;
size_t bin_padded_len;
size_t bin_padded_maxlen;
size_t blocksize;
unsigned int i; unsigned int i;
unsigned int j; unsigned int j;
@ -281,5 +285,34 @@ main(void)
printf("%s\n", printf("%s\n",
sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); 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; return 0;
} }