hash: allow non-security MD5 use in FIPS mode
gnutls running in the FIPS140-2 mode does not allow MD5 to be initialized, which breaks chronyd using MD5 to calculate reference ID of IPv6 addresses. Specify a new hash algorithm for non-security MD5 use and temporarily switch to the lax mode when initializing the hash function.
This commit is contained in:
parent
f363998517
commit
36441fabde
8 changed files with 28 additions and 3 deletions
1
hash.h
1
hash.h
|
@ -44,6 +44,7 @@ typedef enum {
|
||||||
HSH_SHA3_512 = 9,
|
HSH_SHA3_512 = 9,
|
||||||
HSH_TIGER = 10,
|
HSH_TIGER = 10,
|
||||||
HSH_WHIRLPOOL = 11,
|
HSH_WHIRLPOOL = 11,
|
||||||
|
HSH_MD5_NONCRYPTO = 10000, /* For NTPv4 reference ID */
|
||||||
} HSH_Algorithm;
|
} HSH_Algorithm;
|
||||||
|
|
||||||
extern int HSH_GetHashId(HSH_Algorithm algorithm);
|
extern int HSH_GetHashId(HSH_Algorithm algorithm);
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct hash {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct hash hashes[] = {
|
static struct hash hashes[] = {
|
||||||
|
{ HSH_MD5_NONCRYPTO, GNUTLS_DIG_MD5, NULL },
|
||||||
{ HSH_MD5, GNUTLS_DIG_MD5, NULL },
|
{ HSH_MD5, GNUTLS_DIG_MD5, NULL },
|
||||||
{ HSH_SHA1, GNUTLS_DIG_SHA1, NULL },
|
{ HSH_SHA1, GNUTLS_DIG_SHA1, NULL },
|
||||||
{ HSH_SHA256, GNUTLS_DIG_SHA256, NULL },
|
{ HSH_SHA256, GNUTLS_DIG_SHA256, NULL },
|
||||||
|
@ -77,7 +78,14 @@ HSH_GetHashId(HSH_Algorithm algorithm)
|
||||||
if (hashes[id].handle)
|
if (hashes[id].handle)
|
||||||
return id;
|
return id;
|
||||||
|
|
||||||
|
if (algorithm == HSH_MD5_NONCRYPTO)
|
||||||
|
GNUTLS_FIPS140_SET_LAX_MODE();
|
||||||
|
|
||||||
r = gnutls_hash_init(&hashes[id].handle, hashes[id].type);
|
r = gnutls_hash_init(&hashes[id].handle, hashes[id].type);
|
||||||
|
|
||||||
|
if (algorithm == HSH_MD5_NONCRYPTO)
|
||||||
|
GNUTLS_FIPS140_SET_STRICT_MODE();
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
DEBUG_LOG("Could not initialise %s : %s", "hash", gnutls_strerror(r));
|
DEBUG_LOG("Could not initialise %s : %s", "hash", gnutls_strerror(r));
|
||||||
hashes[id].handle = NULL;
|
hashes[id].handle = NULL;
|
||||||
|
|
|
@ -39,7 +39,7 @@ int
|
||||||
HSH_GetHashId(HSH_Algorithm algorithm)
|
HSH_GetHashId(HSH_Algorithm algorithm)
|
||||||
{
|
{
|
||||||
/* only MD5 is supported */
|
/* only MD5 is supported */
|
||||||
if (algorithm != HSH_MD5)
|
if (algorithm != HSH_MD5 && algorithm != HSH_MD5_NONCRYPTO)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -59,6 +59,9 @@ HSH_GetHashId(HSH_Algorithm algorithm)
|
||||||
{
|
{
|
||||||
int id, nid;
|
int id, nid;
|
||||||
|
|
||||||
|
if (algorithm == HSH_MD5_NONCRYPTO)
|
||||||
|
algorithm = HSH_MD5;
|
||||||
|
|
||||||
for (id = 0; hashes[id].algorithm != 0; id++) {
|
for (id = 0; hashes[id].algorithm != 0; id++) {
|
||||||
if (hashes[id].algorithm == algorithm)
|
if (hashes[id].algorithm == algorithm)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -56,6 +56,9 @@ HSH_GetHashId(HSH_Algorithm algorithm)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (algorithm == HSH_MD5_NONCRYPTO)
|
||||||
|
algorithm = HSH_MD5;
|
||||||
|
|
||||||
for (i = 0; hashes[i].algorithm != 0; i++) {
|
for (i = 0; hashes[i].algorithm != 0; i++) {
|
||||||
if (hashes[i].algorithm == algorithm)
|
if (hashes[i].algorithm == algorithm)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -71,6 +71,9 @@ HSH_GetHashId(HSH_Algorithm algorithm)
|
||||||
{
|
{
|
||||||
int i, h;
|
int i, h;
|
||||||
|
|
||||||
|
if (algorithm == HSH_MD5_NONCRYPTO)
|
||||||
|
algorithm = HSH_MD5;
|
||||||
|
|
||||||
for (i = 0; hashes[i].algorithm != 0; i++) {
|
for (i = 0; hashes[i].algorithm != 0; i++) {
|
||||||
if (hashes[i].algorithm == algorithm)
|
if (hashes[i].algorithm == algorithm)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -38,6 +38,7 @@ test_unit(void)
|
||||||
unsigned char data2[] = "12345678910";
|
unsigned char data2[] = "12345678910";
|
||||||
unsigned char out[MAX_HASH_LENGTH];
|
unsigned char out[MAX_HASH_LENGTH];
|
||||||
struct hash_test tests[] = {
|
struct hash_test tests[] = {
|
||||||
|
{ "MD5-NC", "\xfc\x24\x97\x1b\x52\x66\xdc\x46\xef\xe0\xe8\x08\x46\x89\xb6\x88", 16 },
|
||||||
{ "MD5", "\xfc\x24\x97\x1b\x52\x66\xdc\x46\xef\xe0\xe8\x08\x46\x89\xb6\x88", 16 },
|
{ "MD5", "\xfc\x24\x97\x1b\x52\x66\xdc\x46\xef\xe0\xe8\x08\x46\x89\xb6\x88", 16 },
|
||||||
{ "SHA1", "\xd8\x85\xb3\x86\xce\xea\x93\xeb\x92\xcd\x7b\x94\xb9\x8d\xc2\x8e"
|
{ "SHA1", "\xd8\x85\xb3\x86\xce\xea\x93\xeb\x92\xcd\x7b\x94\xb9\x8d\xc2\x8e"
|
||||||
"\x3e\x31\x13\xdd", 20},
|
"\x3e\x31\x13\xdd", 20},
|
||||||
|
@ -77,9 +78,15 @@ test_unit(void)
|
||||||
|
|
||||||
for (i = 0; tests[i].name[0] != '\0'; i++) {
|
for (i = 0; tests[i].name[0] != '\0'; i++) {
|
||||||
algorithm = UTI_HashNameToAlgorithm(tests[i].name);
|
algorithm = UTI_HashNameToAlgorithm(tests[i].name);
|
||||||
TEST_CHECK(algorithm != 0);
|
if (strcmp(tests[i].name, "MD5-NC") == 0) {
|
||||||
|
TEST_CHECK(algorithm == 0);
|
||||||
|
algorithm = HSH_MD5_NONCRYPTO;
|
||||||
|
} else {
|
||||||
|
TEST_CHECK(algorithm != 0);
|
||||||
|
}
|
||||||
hash_id = HSH_GetHashId(algorithm);
|
hash_id = HSH_GetHashId(algorithm);
|
||||||
if (hash_id < 0) {
|
if (hash_id < 0) {
|
||||||
|
TEST_CHECK(algorithm != HSH_MD5_NONCRYPTO);
|
||||||
TEST_CHECK(algorithm != HSH_MD5);
|
TEST_CHECK(algorithm != HSH_MD5);
|
||||||
#ifdef FEAT_SECHASH
|
#ifdef FEAT_SECHASH
|
||||||
TEST_CHECK(algorithm != HSH_SHA1);
|
TEST_CHECK(algorithm != HSH_SHA1);
|
||||||
|
|
2
util.c
2
util.c
|
@ -400,7 +400,7 @@ UTI_IPToRefid(const IPAddr *ip)
|
||||||
return ip->addr.in4;
|
return ip->addr.in4;
|
||||||
case IPADDR_INET6:
|
case IPADDR_INET6:
|
||||||
if (MD5_hash < 0)
|
if (MD5_hash < 0)
|
||||||
MD5_hash = HSH_GetHashId(HSH_MD5);
|
MD5_hash = HSH_GetHashId(HSH_MD5_NONCRYPTO);
|
||||||
|
|
||||||
if (MD5_hash < 0 ||
|
if (MD5_hash < 0 ||
|
||||||
HSH_Hash(MD5_hash, (const unsigned char *)ip->addr.in6, sizeof (ip->addr.in6),
|
HSH_Hash(MD5_hash, (const unsigned char *)ip->addr.in6, sizeof (ip->addr.in6),
|
||||||
|
|
Loading…
Reference in a new issue