cmac+hash: change parameter types

For consistency and safety, change the CMC and HSH functions to accept
signed lengths and handle negative values as errors. Also, change the
input data type to void * to not require casting in the caller.
This commit is contained in:
Miroslav Lichvar 2020-07-08 12:02:12 +02:00
parent de4ecc72d1
commit d93aa10bac
13 changed files with 64 additions and 53 deletions

8
cmac.h
View file

@ -37,11 +37,11 @@ typedef enum {
typedef struct CMC_Instance_Record *CMC_Instance;
extern unsigned int CMC_GetKeyLength(CMC_Algorithm algorithm);
extern int CMC_GetKeyLength(CMC_Algorithm algorithm);
extern CMC_Instance CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key,
unsigned int length);
extern unsigned int CMC_Hash(CMC_Instance inst, const unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int out_len);
int length);
extern int CMC_Hash(CMC_Instance inst, const void *in, int in_len,
unsigned char *out, int out_len);
extern void CMC_DestroyInstance(CMC_Instance inst);
#endif

View file

@ -44,7 +44,7 @@ struct CMC_Instance_Record {
/* ================================================== */
unsigned int
int
CMC_GetKeyLength(CMC_Algorithm algorithm)
{
if (algorithm == CMC_AES128)
@ -57,11 +57,11 @@ CMC_GetKeyLength(CMC_Algorithm algorithm)
/* ================================================== */
CMC_Instance
CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key, unsigned int length)
CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key, int length)
{
CMC_Instance inst;
if (length == 0 || length != CMC_GetKeyLength(algorithm))
if (length <= 0 || length != CMC_GetKeyLength(algorithm))
return NULL;
inst = MallocNew(struct CMC_Instance_Record);
@ -83,10 +83,12 @@ CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key, unsigned i
/* ================================================== */
unsigned int
CMC_Hash(CMC_Instance inst, const unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int out_len)
int
CMC_Hash(CMC_Instance inst, const void *in, int in_len, unsigned char *out, int out_len)
{
if (in_len < 0 || out_len < 0)
return 0;
if (out_len > CMAC128_DIGEST_SIZE)
out_len = CMAC128_DIGEST_SIZE;

6
hash.h
View file

@ -48,10 +48,8 @@ typedef enum {
extern int HSH_GetHashId(HSH_Algorithm algorithm);
extern unsigned int HSH_Hash(int id,
const unsigned char *in1, unsigned int in1_len,
const unsigned char *in2, unsigned int in2_len,
unsigned char *out, unsigned int out_len);
extern int HSH_Hash(int id, const void *in1, int in1_len, const void *in2, int in2_len,
unsigned char *out, int out_len);
extern void HSH_Finalise(void);

View file

@ -45,11 +45,13 @@ HSH_GetHashId(HSH_Algorithm algorithm)
return 0;
}
unsigned int
HSH_Hash(int id, const unsigned char *in1, unsigned int in1_len,
const unsigned char *in2, unsigned int in2_len,
unsigned char *out, unsigned int out_len)
int
HSH_Hash(int id, const void *in1, int in1_len, const void *in2, int in2_len,
unsigned char *out, int out_len)
{
if (in1_len < 0 || in2_len < 0 || out_len < 0)
return 0;
MD5Init(&ctx);
MD5Update(&ctx, in1, in1_len);
if (in2)

View file

@ -84,14 +84,16 @@ HSH_GetHashId(HSH_Algorithm algorithm)
return id;
}
unsigned int
HSH_Hash(int id, const unsigned char *in1, unsigned int in1_len,
const unsigned char *in2, unsigned int in2_len,
unsigned char *out, unsigned int out_len)
int
HSH_Hash(int id, const void *in1, int in1_len, const void *in2, int in2_len,
unsigned char *out, int out_len)
{
const struct nettle_hash *hash;
void *context;
if (in1_len < 0 || in2_len < 0 || out_len < 0)
return 0;
hash = hashes[id].nettle_hash;
context = hashes[id].context;

View file

@ -74,14 +74,16 @@ HSH_GetHashId(HSH_Algorithm algorithm)
return i;
}
unsigned int
HSH_Hash(int id, const unsigned char *in1, unsigned int in1_len,
const unsigned char *in2, unsigned int in2_len,
unsigned char *out, unsigned int out_len)
int
HSH_Hash(int id, const void *in1, int in1_len, const void *in2, int in2_len,
unsigned char *out, int out_len)
{
unsigned char buf[MAX_HASH_LENGTH];
unsigned int ret = 0;
if (in1_len < 0 || in2_len < 0 || out_len < 0)
return 0;
NSSLOWHASH_Begin(hashes[id].context);
NSSLOWHASH_Update(hashes[id].context, in1, in1_len);
if (in2)

View file

@ -89,15 +89,17 @@ HSH_GetHashId(HSH_Algorithm algorithm)
return find_hash(hashes[i].int_name);
}
unsigned int
HSH_Hash(int id, const unsigned char *in1, unsigned int in1_len,
const unsigned char *in2, unsigned int in2_len,
unsigned char *out, unsigned int out_len)
int
HSH_Hash(int id, const void *in1, int in1_len, const void *in2, int in2_len,
unsigned char *out, int out_len)
{
unsigned char buf[MAX_HASH_LENGTH];
unsigned long len;
int r;
if (in1_len < 0 || in2_len < 0 || out_len < 0)
return 0;
len = sizeof (buf);
if (in2)
r = hash_memory_multi(id, buf, &len,

9
keys.c
View file

@ -376,8 +376,7 @@ KEY_GetKeyInfo(uint32_t key_id, int *type, int *bits)
/* ================================================== */
static int
generate_auth(Key *key, const unsigned char *data, int data_len,
unsigned char *auth, int auth_len)
generate_auth(Key *key, const void *data, int data_len, unsigned char *auth, int auth_len)
{
switch (key->class) {
case NTP_MAC:
@ -393,7 +392,7 @@ generate_auth(Key *key, const unsigned char *data, int data_len,
/* ================================================== */
static int
check_auth(Key *key, const unsigned char *data, int data_len,
check_auth(Key *key, const void *data, int data_len,
const unsigned char *auth, int auth_len, int trunc_len)
{
unsigned char buf[MAX_HASH_LENGTH];
@ -407,7 +406,7 @@ check_auth(Key *key, const unsigned char *data, int data_len,
/* ================================================== */
int
KEY_GenerateAuth(uint32_t key_id, const unsigned char *data, int data_len,
KEY_GenerateAuth(uint32_t key_id, const void *data, int data_len,
unsigned char *auth, int auth_len)
{
Key *key;
@ -423,7 +422,7 @@ KEY_GenerateAuth(uint32_t key_id, const unsigned char *data, int data_len,
/* ================================================== */
int
KEY_CheckAuth(uint32_t key_id, const unsigned char *data, int data_len,
KEY_CheckAuth(uint32_t key_id, const void *data, int data_len,
const unsigned char *auth, int auth_len, int trunc_len)
{
Key *key;

6
keys.h
View file

@ -39,9 +39,9 @@ extern int KEY_GetAuthLength(uint32_t key_id);
extern int KEY_CheckKeyLength(uint32_t key_id);
extern int KEY_GetKeyInfo(uint32_t key_id, int *type, int *bits);
extern int KEY_GenerateAuth(uint32_t key_id, const unsigned char *data,
int data_len, unsigned char *auth, int auth_len);
extern int KEY_CheckAuth(uint32_t key_id, const unsigned char *data, int data_len,
extern int KEY_GenerateAuth(uint32_t key_id, const void *data, int data_len,
unsigned char *auth, int auth_len);
extern int KEY_CheckAuth(uint32_t key_id, const void *data, int data_len,
const unsigned char *auth, int auth_len, int trunc_len);
#endif /* GOT_KEYS_H */

View file

@ -60,7 +60,7 @@ generate_symmetric_auth(uint32_t key_id, NTP_Packet *packet, NTP_PacketInfo *inf
max_auth_len = (info->version == 4 ? NTP_MAX_V4_MAC_LENGTH : NTP_MAX_MAC_LENGTH) - 4;
max_auth_len = MIN(max_auth_len, sizeof (NTP_Packet) - info->length - 4);
auth_len = KEY_GenerateAuth(key_id, (unsigned char *)packet, info->length,
auth_len = KEY_GenerateAuth(key_id, packet, info->length,
(unsigned char *)packet + info->length + 4, max_auth_len);
if (!auth_len) {
DEBUG_LOG("Could not generate auth data with key %"PRIu32, key_id);
@ -86,7 +86,7 @@ check_symmetric_auth(NTP_Packet *packet, NTP_PacketInfo *info)
trunc_len = info->version == 4 && info->auth.mac.length <= NTP_MAX_V4_MAC_LENGTH ?
NTP_MAX_V4_MAC_LENGTH : NTP_MAX_MAC_LENGTH;
if (!KEY_CheckAuth(info->auth.mac.key_id, (void *)packet, info->auth.mac.start,
if (!KEY_CheckAuth(info->auth.mac.key_id, packet, info->auth.mac.start,
(unsigned char *)packet + info->auth.mac.start + 4,
info->auth.mac.length - 4, trunc_len - 4))
return 0;

View file

@ -438,21 +438,20 @@ NSD_SignAndSendPacket(uint32_t key_id, NTP_Packet *packet, NTP_PacketInfo *info,
#ifndef HAVE_CMAC
unsigned int
int
CMC_GetKeyLength(CMC_Algorithm algorithm)
{
return 0;
}
CMC_Instance
CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key, unsigned int length)
CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key, int length)
{
return NULL;
}
unsigned int
CMC_Hash(CMC_Instance inst, const unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int out_len)
int
CMC_Hash(CMC_Instance inst, const void *in, int in_len, unsigned char *out, int out_len)
{
return 0;
}

View file

@ -31,9 +31,9 @@
struct cmac_test {
const char *name;
const unsigned char key[MAX_KEY_LENGTH];
unsigned int key_length;
int key_length;
const unsigned char hash[MAX_HASH_LENGTH];
unsigned int hash_length;
int hash_length;
};
void
@ -52,8 +52,7 @@ test_unit(void)
CMC_Algorithm algorithm;
CMC_Instance inst;
unsigned int length;
int i, j;
int i, j, length;
#ifndef HAVE_CMAC
TEST_REQUIRE(0);
@ -68,7 +67,7 @@ test_unit(void)
DEBUG_LOG("testing %s", tests[i].name);
for (j = 0; j <= 128; j++) {
for (j = -1; j <= 128; j++) {
if (j == tests[i].key_length)
continue;
TEST_CHECK(!CMC_CreateInstance(algorithm, tests[i].key, j));
@ -79,6 +78,9 @@ test_unit(void)
TEST_CHECK(!CMC_CreateInstance(0, tests[i].key, tests[i].key_length));
TEST_CHECK(CMC_Hash(inst, data, -1, hash, sizeof (hash)) == 0);
TEST_CHECK(CMC_Hash(inst, data, sizeof (data) - 1, hash, -1) == 0);
for (j = 0; j <= sizeof (hash); j++) {
memset(hash, 0, sizeof (hash));
length = CMC_Hash(inst, data, sizeof (data) - 1, hash, j);

View file

@ -28,7 +28,7 @@
struct hash_test {
const char *name;
const unsigned char out[MAX_HASH_LENGTH];
unsigned int length;
int length;
};
void
@ -71,8 +71,7 @@ test_unit(void)
};
HSH_Algorithm algorithm;
unsigned int length;
int i, j, hash_id;
int i, j, hash_id, length;
TEST_CHECK(HSH_INVALID == 0);
@ -93,6 +92,10 @@ test_unit(void)
DEBUG_LOG("testing %s", tests[i].name);
TEST_CHECK(HSH_Hash(hash_id, data1, -1, NULL, 0, out, sizeof (out)) == 0);
TEST_CHECK(HSH_Hash(hash_id, data1, sizeof (data1) - 1, data2, -1, out, sizeof (out)) == 0);
TEST_CHECK(HSH_Hash(hash_id, data1, sizeof (data1) - 1, NULL, 0, out, -1) == 0);
for (j = 0; j <= sizeof (out); j++) {
TEST_CHECK(HSH_GetHashId(algorithm) == hash_id);
TEST_CHECK(HSH_GetHashId(0) < 0);