cmac: enumerate cipher algorithms
Identify the CMAC ciphers with an enum instead of string.
This commit is contained in:
parent
a8c8f2f309
commit
972c476c5a
8 changed files with 52 additions and 19 deletions
2
client.c
2
client.c
|
@ -2985,7 +2985,7 @@ process_cmd_keygen(char *line)
|
||||||
;
|
;
|
||||||
|
|
||||||
#ifdef HAVE_CMAC
|
#ifdef HAVE_CMAC
|
||||||
cmac_length = CMC_GetKeyLength(type);
|
cmac_length = CMC_GetKeyLength(UTI_CmacNameToAlgorithm(type));
|
||||||
#else
|
#else
|
||||||
cmac_length = 0;
|
cmac_length = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
11
cmac.h
11
cmac.h
|
@ -28,10 +28,17 @@
|
||||||
#ifndef GOT_CMAC_H
|
#ifndef GOT_CMAC_H
|
||||||
#define GOT_CMAC_H
|
#define GOT_CMAC_H
|
||||||
|
|
||||||
|
/* Avoid overlapping with the hash enumeration */
|
||||||
|
typedef enum {
|
||||||
|
CMC_INVALID = 0,
|
||||||
|
CMC_AES128 = 13,
|
||||||
|
CMC_AES256 = 14,
|
||||||
|
} CMC_Algorithm;
|
||||||
|
|
||||||
typedef struct CMC_Instance_Record *CMC_Instance;
|
typedef struct CMC_Instance_Record *CMC_Instance;
|
||||||
|
|
||||||
extern unsigned int CMC_GetKeyLength(const char *cipher);
|
extern unsigned int CMC_GetKeyLength(CMC_Algorithm algorithm);
|
||||||
extern CMC_Instance CMC_CreateInstance(const char *cipher, const unsigned char *key,
|
extern CMC_Instance CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key,
|
||||||
unsigned int length);
|
unsigned int length);
|
||||||
extern unsigned int CMC_Hash(CMC_Instance inst, const unsigned char *in, unsigned int in_len,
|
extern unsigned int CMC_Hash(CMC_Instance inst, const unsigned char *in, unsigned int in_len,
|
||||||
unsigned char *out, unsigned int out_len);
|
unsigned char *out, unsigned int out_len);
|
||||||
|
|
|
@ -45,11 +45,11 @@ struct CMC_Instance_Record {
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
CMC_GetKeyLength(const char *cipher)
|
CMC_GetKeyLength(CMC_Algorithm algorithm)
|
||||||
{
|
{
|
||||||
if (strcmp(cipher, "AES128") == 0)
|
if (algorithm == CMC_AES128)
|
||||||
return AES128_KEY_SIZE;
|
return AES128_KEY_SIZE;
|
||||||
else if (strcmp(cipher, "AES256") == 0)
|
else if (algorithm == CMC_AES256)
|
||||||
return AES256_KEY_SIZE;
|
return AES256_KEY_SIZE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,11 @@ CMC_GetKeyLength(const char *cipher)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
CMC_Instance
|
CMC_Instance
|
||||||
CMC_CreateInstance(const char *cipher, const unsigned char *key, unsigned int length)
|
CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key, unsigned int length)
|
||||||
{
|
{
|
||||||
CMC_Instance inst;
|
CMC_Instance inst;
|
||||||
|
|
||||||
if (length == 0 || length != CMC_GetKeyLength(cipher))
|
if (length == 0 || length != CMC_GetKeyLength(algorithm))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
inst = MallocNew(struct CMC_Instance_Record);
|
inst = MallocNew(struct CMC_Instance_Record);
|
||||||
|
|
16
keys.c
16
keys.c
|
@ -202,6 +202,7 @@ KEY_Reload(void)
|
||||||
char line[2048], *key_file, *key_value;
|
char line[2048], *key_file, *key_value;
|
||||||
const char *key_type;
|
const char *key_type;
|
||||||
HSH_Algorithm hash_algorithm;
|
HSH_Algorithm hash_algorithm;
|
||||||
|
CMC_Algorithm cmac_algorithm;
|
||||||
int hash_id;
|
int hash_id;
|
||||||
Key key;
|
Key key;
|
||||||
|
|
||||||
|
@ -239,8 +240,8 @@ KEY_Reload(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmac_key_length = CMC_GetKeyLength(key_type);
|
|
||||||
hash_algorithm = UTI_HashNameToAlgorithm(key_type);
|
hash_algorithm = UTI_HashNameToAlgorithm(key_type);
|
||||||
|
cmac_algorithm = UTI_CmacNameToAlgorithm(key_type);
|
||||||
|
|
||||||
if (hash_algorithm != 0) {
|
if (hash_algorithm != 0) {
|
||||||
hash_id = HSH_GetHashId(hash_algorithm);
|
hash_id = HSH_GetHashId(hash_algorithm);
|
||||||
|
@ -253,18 +254,23 @@ KEY_Reload(void)
|
||||||
memcpy(key.data.ntp_mac.value, key_value, key_length);
|
memcpy(key.data.ntp_mac.value, key_value, key_length);
|
||||||
key.data.ntp_mac.length = key_length;
|
key.data.ntp_mac.length = key_length;
|
||||||
key.data.ntp_mac.hash_id = hash_id;
|
key.data.ntp_mac.hash_id = hash_id;
|
||||||
} else if (cmac_key_length > 0) {
|
} else if (cmac_algorithm != 0) {
|
||||||
if (cmac_key_length != key_length) {
|
cmac_key_length = CMC_GetKeyLength(cmac_algorithm);
|
||||||
|
if (cmac_key_length == 0) {
|
||||||
|
LOG(LOGS_WARN, "Unsupported %s in key %"PRIu32, "cipher", key.id);
|
||||||
|
continue;
|
||||||
|
} else if (cmac_key_length != key_length) {
|
||||||
LOG(LOGS_WARN, "Invalid length of %s key %"PRIu32" (expected %u bits)",
|
LOG(LOGS_WARN, "Invalid length of %s key %"PRIu32" (expected %u bits)",
|
||||||
key_type, key.id, 8 * cmac_key_length);
|
key_type, key.id, 8 * cmac_key_length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
key.class = CMAC;
|
key.class = CMAC;
|
||||||
key.data.cmac = CMC_CreateInstance(key_type, (unsigned char *)key_value, key_length);
|
key.data.cmac = CMC_CreateInstance(cmac_algorithm, (unsigned char *)key_value,
|
||||||
|
key_length);
|
||||||
assert(key.data.cmac);
|
assert(key.data.cmac);
|
||||||
} else {
|
} else {
|
||||||
LOG(LOGS_WARN, "Unknown hash function or cipher in key %"PRIu32, key.id);
|
LOG(LOGS_WARN, "Invalid type in key %"PRIu32, key.id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
stubs.c
4
stubs.c
|
@ -432,13 +432,13 @@ NSD_SignAndSendPacket(uint32_t key_id, NTP_Packet *packet, NTP_PacketInfo *info,
|
||||||
#ifndef HAVE_CMAC
|
#ifndef HAVE_CMAC
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
CMC_GetKeyLength(const char *cipher)
|
CMC_GetKeyLength(CMC_Algorithm algorithm)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMC_Instance
|
CMC_Instance
|
||||||
CMC_CreateInstance(const char *cipher, const unsigned char *key, unsigned int length)
|
CMC_CreateInstance(CMC_Algorithm algorithm, const unsigned char *key, unsigned int length)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <sysincl.h>
|
#include <sysincl.h>
|
||||||
#include <cmac.h>
|
#include <cmac.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
#include <util.h>
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
#define MAX_KEY_LENGTH 64
|
#define MAX_KEY_LENGTH 64
|
||||||
|
@ -49,6 +50,7 @@ test_unit(void)
|
||||||
{ "", "", 0, "", 0 }
|
{ "", "", 0, "", 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CMC_Algorithm algorithm;
|
||||||
CMC_Instance inst;
|
CMC_Instance inst;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -57,21 +59,25 @@ test_unit(void)
|
||||||
TEST_REQUIRE(0);
|
TEST_REQUIRE(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TEST_CHECK(CMC_INVALID == 0);
|
||||||
|
|
||||||
for (i = 0; tests[i].name[0] != '\0'; i++) {
|
for (i = 0; tests[i].name[0] != '\0'; i++) {
|
||||||
TEST_CHECK(CMC_GetKeyLength(tests[i].name) == tests[i].key_length);
|
algorithm = UTI_CmacNameToAlgorithm(tests[i].name);
|
||||||
|
TEST_CHECK(algorithm != 0);
|
||||||
|
TEST_CHECK(CMC_GetKeyLength(algorithm) == tests[i].key_length);
|
||||||
|
|
||||||
DEBUG_LOG("testing %s", tests[i].name);
|
DEBUG_LOG("testing %s", tests[i].name);
|
||||||
|
|
||||||
for (j = 0; j <= 128; j++) {
|
for (j = 0; j <= 128; j++) {
|
||||||
if (j == tests[i].key_length)
|
if (j == tests[i].key_length)
|
||||||
continue;
|
continue;
|
||||||
TEST_CHECK(!CMC_CreateInstance(tests[i].name, tests[i].key, j));
|
TEST_CHECK(!CMC_CreateInstance(algorithm, tests[i].key, j));
|
||||||
}
|
}
|
||||||
|
|
||||||
inst = CMC_CreateInstance(tests[i].name, tests[i].key, tests[i].key_length);
|
inst = CMC_CreateInstance(algorithm, tests[i].key, tests[i].key_length);
|
||||||
TEST_CHECK(inst);
|
TEST_CHECK(inst);
|
||||||
|
|
||||||
TEST_CHECK(!CMC_CreateInstance("nosuchcipher", tests[i].key, tests[i].key_length));
|
TEST_CHECK(!CMC_CreateInstance(0, tests[i].key, tests[i].key_length));
|
||||||
|
|
||||||
for (j = 0; j <= sizeof (hash); j++) {
|
for (j = 0; j <= sizeof (hash); j++) {
|
||||||
memset(hash, 0, sizeof (hash));
|
memset(hash, 0, sizeof (hash));
|
||||||
|
|
12
util.c
12
util.c
|
@ -927,6 +927,18 @@ UTI_FloatHostToNetwork(double x)
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
CMC_Algorithm
|
||||||
|
UTI_CmacNameToAlgorithm(const char *name)
|
||||||
|
{
|
||||||
|
if (strcmp(name, "AES128") == 0)
|
||||||
|
return CMC_AES128;
|
||||||
|
else if (strcmp(name, "AES256") == 0)
|
||||||
|
return CMC_AES256;
|
||||||
|
return CMC_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
HSH_Algorithm
|
HSH_Algorithm
|
||||||
UTI_HashNameToAlgorithm(const char *name)
|
UTI_HashNameToAlgorithm(const char *name)
|
||||||
{
|
{
|
||||||
|
|
2
util.h
2
util.h
|
@ -32,6 +32,7 @@
|
||||||
#include "addressing.h"
|
#include "addressing.h"
|
||||||
#include "ntp.h"
|
#include "ntp.h"
|
||||||
#include "candm.h"
|
#include "candm.h"
|
||||||
|
#include "cmac.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
/* Zero a timespec */
|
/* Zero a timespec */
|
||||||
|
@ -165,6 +166,7 @@ extern void UTI_TimespecHostToNetwork(const struct timespec *src, Timespec *dest
|
||||||
extern double UTI_FloatNetworkToHost(Float x);
|
extern double UTI_FloatNetworkToHost(Float x);
|
||||||
extern Float UTI_FloatHostToNetwork(double x);
|
extern Float UTI_FloatHostToNetwork(double x);
|
||||||
|
|
||||||
|
extern CMC_Algorithm UTI_CmacNameToAlgorithm(const char *name);
|
||||||
extern HSH_Algorithm UTI_HashNameToAlgorithm(const char *name);
|
extern HSH_Algorithm UTI_HashNameToAlgorithm(const char *name);
|
||||||
|
|
||||||
/* Set FD_CLOEXEC on descriptor */
|
/* Set FD_CLOEXEC on descriptor */
|
||||||
|
|
Loading…
Reference in a new issue