libsodium/test/default/auth.c
Ilya Maykov 6bece9c8c4 Relax most __attribute__ ((nonnull)) to allow 0-length inputs to be NULL.
Justifications:
- crypto_(auth|hash|generichash|onetimeauth|shorthash)*:
  it's legal to hash or HMAC a 0-length message
- crypto_box*: it's legal to encrypt a 0-length message
- crypto_sign*: it's legal to sign a 0-length message
- utils:
  comparing two 0-length byte arrays is legal
  memzero on a 0-length byte array is a no-op
  converting an empty hex string to binary results in an empty binary string
  converting an empty binary string to hex results in an empty hex string
  converting an empty b64 string to binary results in an empty binary string
  converting an empty binary string to b64 results in an empty b64 string
  sodium_add / sodium_sub on zero-length arrays is a no-op

For the functions declared in utils.h, I moved the logic into private functions that
have the __attribute__ ((nonnull)) check, but they are only called when the
corresponding length argument is non-0. I didn't do this for the hash/box/sign
functions since it would have been a lot more work and quite a large refactor.

Only memset() may have issues with a zero length.

Fix tests, use guard page instead of NULL because of Wasm
2019-04-26 15:36:58 +02:00

142 lines
5.0 KiB
C

#define TEST_NAME "auth"
#include "cmptest.h"
/* "Test Case 2" from RFC 4231 */
static unsigned char key[32] = "Jefe";
static unsigned char c[] = "what do ya want for nothing?";
/* Hacker manifesto */
static unsigned char key2[] =
"Another one got caught today, it's all over the papers. \"Teenager "
"Arrested in Computer Crime Scandal\", \"Hacker Arrested after Bank "
"Tampering\"... Damn kids. They're all alike.";
static unsigned char a[crypto_auth_BYTES];
static unsigned char a2[crypto_auth_hmacsha512_BYTES];
static unsigned char a3[crypto_auth_hmacsha512_BYTES];
int
main(void)
{
crypto_auth_hmacsha512_state st;
crypto_auth_hmacsha256_state st256;
crypto_auth_hmacsha512256_state st512_256;
size_t i;
assert(crypto_auth_hmacsha512_statebytes() ==
sizeof(crypto_auth_hmacsha512_state));
crypto_auth(a, c, sizeof c - 1U, key);
for (i = 0; i < sizeof a; ++i) {
printf(",0x%02x", (unsigned int) a[i]);
if (i % 8 == 7)
printf("\n");
}
printf("\n");
crypto_auth_hmacsha512_init(&st, key, sizeof key);
crypto_auth_hmacsha512_update(&st, c, 1U);
crypto_auth_hmacsha512_update(&st, c, sizeof c - 2U);
crypto_auth_hmacsha512_final(&st, a2);
for (i = 0; i < sizeof a2; ++i) {
printf(",0x%02x", (unsigned int) a2[i]);
if (i % 8 == 7)
printf("\n");
}
printf("\n");
crypto_auth_hmacsha512_init(&st, key2, sizeof key2);
crypto_auth_hmacsha512_update(&st, c, 1U);
crypto_auth_hmacsha512_update(&st, c, sizeof c - 2U);
crypto_auth_hmacsha512_final(&st, a2);
for (i = 0; i < sizeof a2; ++i) {
printf(",0x%02x", (unsigned int) a2[i]);
if (i % 8 == 7)
printf("\n");
}
memset(a2, 0, sizeof a2);
crypto_auth_hmacsha256_init(&st256, key2, sizeof key2);
crypto_auth_hmacsha256_update(&st256, guard_page, 0U);
crypto_auth_hmacsha256_update(&st256, c, 1U);
crypto_auth_hmacsha256_update(&st256, c, sizeof c - 2U);
crypto_auth_hmacsha256_final(&st256, a2);
for (i = 0; i < sizeof a2; ++i) {
printf(",0x%02x", (unsigned int) a2[i]);
if (i % 8 == 7)
printf("\n");
}
/* Empty message tests: HMAC-SHA512 */
memset(a2, 0, sizeof a2);
crypto_auth_hmacsha512_init(&st, key, sizeof key);
crypto_auth_hmacsha512_final(&st, a2);
memset(a3, 0, sizeof a3);
crypto_auth_hmacsha512_init(&st, key, sizeof key);
crypto_auth_hmacsha512_update(&st, a2, 0U);
crypto_auth_hmacsha512_final(&st, a3);
assert(sodium_memcmp(a2, a3, sizeof a2) == 0);
memset(a3, 0, sizeof a3);
crypto_auth_hmacsha512_init(&st, key, sizeof key);
crypto_auth_hmacsha512_update(&st, guard_page, 0U);
crypto_auth_hmacsha512_final(&st, a3);
assert(sodium_memcmp(a2, a3, sizeof a2) == 0);
/* Empty message tests: HMAC-SHA512-256 */
memset(a2, 0, sizeof a2);
crypto_auth_hmacsha512256_init(&st512_256, key, sizeof key);
crypto_auth_hmacsha512256_final(&st512_256, a2);
memset(a3, 0, sizeof a3);
crypto_auth_hmacsha512256_init(&st512_256, key, sizeof key);
crypto_auth_hmacsha512256_update(&st512_256, a2, 0U);
crypto_auth_hmacsha512256_final(&st512_256, a3);
assert(sodium_memcmp(a2, a3, sizeof a2) == 0);
memset(a3, 0, sizeof a3);
crypto_auth_hmacsha512256_init(&st512_256, key, sizeof key);
crypto_auth_hmacsha512256_update(&st512_256, guard_page, 0U);
crypto_auth_hmacsha512256_final(&st512_256, a3);
assert(sodium_memcmp(a2, a3, sizeof a2) == 0);
/* Empty message tests: HMAC-SHA256 */
memset(a2, 0, sizeof a2);
crypto_auth_hmacsha256_init(&st256, key, sizeof key);
crypto_auth_hmacsha256_final(&st256, a2);
memset(a3, 0, sizeof a3);
crypto_auth_hmacsha256_init(&st256, key, sizeof key);
crypto_auth_hmacsha256_update(&st256, a2, 0U);
crypto_auth_hmacsha256_final(&st256, a3);
assert(sodium_memcmp(a2, a3, sizeof a2) == 0);
memset(a3, 0, sizeof a3);
crypto_auth_hmacsha256_init(&st256, key, sizeof key);
crypto_auth_hmacsha256_update(&st256, guard_page, 0U);
crypto_auth_hmacsha256_final(&st256, a3);
assert(sodium_memcmp(a2, a3, sizeof a2) == 0);
/* --- */
assert(crypto_auth_bytes() > 0U);
assert(crypto_auth_keybytes() > 0U);
assert(strcmp(crypto_auth_primitive(), "hmacsha512256") == 0);
assert(crypto_auth_hmacsha256_bytes() > 0U);
assert(crypto_auth_hmacsha256_keybytes() > 0U);
assert(crypto_auth_hmacsha512_bytes() > 0U);
assert(crypto_auth_hmacsha512_keybytes() > 0U);
assert(crypto_auth_hmacsha512256_bytes() == crypto_auth_bytes());
assert(crypto_auth_hmacsha512256_keybytes() == crypto_auth_keybytes());
assert(crypto_auth_hmacsha512256_statebytes() >=
crypto_auth_hmacsha512256_keybytes());
assert(crypto_auth_hmacsha256_statebytes() ==
sizeof(crypto_auth_hmacsha256_state));
assert(crypto_auth_hmacsha512_statebytes() ==
sizeof(crypto_auth_hmacsha512_state));
return 0;
}