Gain FIPS awareness

This commit is contained in:
Robbie Harwood 2018-11-12 15:38:14 -05:00
parent d401b30b5f
commit 83e3cdfc7d
4 changed files with 220 additions and 55 deletions

135
Become-FIPS-aware.patch Normal file
View File

@ -0,0 +1,135 @@
From d49cdc4f701d072b59d57d14bc9c19e9fba42396 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 9 Nov 2018 15:12:21 -0500
Subject: [PATCH] Become FIPS-aware
A lot of the FIPS error conditions from OpenSSL are incredibly
mysterious (at best, things return NULL unexpectedly; at worst,
internal assertions are tripped; most of the time, you just get
ENOMEM). In order to cope with this, we need to have some level of
awareness of what we can and can't safely call.
This will slow down some calls slightly (FIPS_mode() takes multiple
locks), but not for any crypto we care about - AES is fine, for
instance.
(cherry picked from commit ee05742839df659d2136b37f91d0a888de2b5e26)
(cherry picked from commit b38ed4d97152f1dce126235935d30e549ead77b3)
---
src/lib/crypto/openssl/enc_provider/camellia.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/des.c | 9 +++++++++
src/lib/crypto/openssl/enc_provider/rc4.c | 3 +++
src/lib/crypto/openssl/hash_provider/hash_evp.c | 4 ++++
src/lib/crypto/openssl/hmac.c | 6 +++++-
5 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index 2da691329..f79679a0b 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -304,6 +304,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
struct iov_cursor cursor;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
if (output->length < CAMELLIA_BLOCK_SIZE)
return KRB5_BAD_MSIZE;
@@ -331,6 +334,9 @@ static krb5_error_code
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
krb5_data *state)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
state->length = 16;
state->data = (void *) malloc(16);
if (state->data == NULL)
diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c
index a662db512..7d17d287e 100644
--- a/src/lib/crypto/openssl/enc_provider/des.c
+++ b/src/lib/crypto/openssl/enc_provider/des.c
@@ -85,6 +85,9 @@ k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -182,6 +188,9 @@ k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
DES_key_schedule sched;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index 7f3c086ed..ef8205535 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -125,6 +125,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
{
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
/* Create a state structure with an uninitialized context. */
arcstate = calloc(1, sizeof(*arcstate));
if (arcstate == NULL)
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
index 957ed8d9c..8c1fd7f59 100644
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
@@ -64,12 +64,16 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
static krb5_error_code
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md4(), data, num_data, output);
}
static krb5_error_code
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md5(), data, num_data, output);
}
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index b2db6ec02..d94d9ac94 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -103,7 +103,11 @@ map_digest(const struct krb5_hash_provider *hash)
return EVP_sha256();
else if (!strncmp(hash->hash_name, "SHA-384",7))
return EVP_sha384();
- else if (!strncmp(hash->hash_name, "MD5", 3))
+
+ if (FIPS_mode())
+ return NULL;
+
+ if (!strncmp(hash->hash_name, "MD5", 3))
return EVP_md5();
else if (!strncmp(hash->hash_name, "MD4", 3))
return EVP_md4();

View File

@ -1,4 +1,4 @@
From 9fb4942026ba77ae51a9fa3623c62a07328e3bd5 Mon Sep 17 00:00:00 2001
From 5d925544465008f1695b3595531443aa78613365 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 5 Nov 2018 13:49:52 -0500
Subject: [PATCH] Fix spurious errors from kcmio_unix_socket_write

View File

@ -1,23 +1,32 @@
From 9bb35cc29293de37ef92bf151a601884e602eb39 Mon Sep 17 00:00:00 2001
From 461739cdd608724020362bf0de07f76844bbfe10 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 31 Jul 2018 13:47:26 -0400
Subject: [PATCH] In FIPS mode, add plaintext fallback for RC4 usages and taint
(cherry picked from commit a327e3bf5b992ac829c7b2d3317fb7d93b1c88ef)
---
src/lib/krad/attr.c | 38 ++++++++++++++++++++++++++++----------
src/lib/krad/attr.c | 45 +++++++++++++++++++++++++++++-----------
src/lib/krad/attrset.c | 5 +++--
src/lib/krad/internal.h | 13 +++++++++++--
src/lib/krad/packet.c | 18 +++++++++---------
src/lib/krad/remote.c | 10 ++++++++--
src/lib/krad/internal.h | 13 ++++++++++--
src/lib/krad/packet.c | 22 +++++++++++---------
src/lib/krad/remote.c | 10 +++++++--
src/lib/krad/t_attr.c | 3 ++-
src/lib/krad/t_attrset.c | 4 +++-
7 files changed, 64 insertions(+), 27 deletions(-)
7 files changed, 72 insertions(+), 30 deletions(-)
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
index 9c13d9d75..3a2d0243b 100644
index 9c13d9d75..275327e67 100644
--- a/src/lib/krad/attr.c
+++ b/src/lib/krad/attr.c
@@ -38,7 +38,8 @@
@@ -30,6 +30,7 @@
#include <k5-int.h>
#include "internal.h"
+#include <openssl/crypto.h>
#include <string.h>
/* RFC 2865 */
@@ -38,7 +39,8 @@
typedef krb5_error_code
(*attribute_transform_fn)(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
@ -27,7 +36,7 @@ index 9c13d9d75..3a2d0243b 100644
typedef struct {
const char *name;
@@ -51,12 +52,14 @@ typedef struct {
@@ -51,12 +53,14 @@ typedef struct {
static krb5_error_code
user_password_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
@ -44,7 +53,7 @@ index 9c13d9d75..3a2d0243b 100644
static const attribute_record attributes[UCHAR_MAX] = {
{"User-Name", 1, MAX_ATTRSIZE, NULL, NULL},
@@ -128,7 +131,8 @@ static const attribute_record attributes[UCHAR_MAX] = {
@@ -128,7 +132,8 @@ static const attribute_record attributes[UCHAR_MAX] = {
static krb5_error_code
user_password_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
@ -54,21 +63,24 @@ index 9c13d9d75..3a2d0243b 100644
{
const unsigned char *indx;
krb5_error_code retval;
@@ -156,7 +160,12 @@ user_password_encode(krb5_context ctx, const char *secret,
@@ -154,8 +159,14 @@ user_password_encode(krb5_context ctx, const char *secret,
for (blck = 0, indx = auth; blck * BLOCKSIZE < len; blck++) {
memcpy(tmp.data + seclen, indx, BLOCKSIZE);
retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
&sum);
- if (retval != 0) {
+ if (retval == ENOMEM) {
+ /* I'm Linux, so we know this is a FIPS failure. Taint so we
+ * don't send it later. */
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
- &sum);
+ if (FIPS_mode()) {
+ /* Skip encryption here. Taint so that we won't pass it out of
+ * the machine by accident. */
+ *is_fips = TRUE;
+ sum.contents = calloc(1, BLOCKSIZE);
+ } else if (retval != 0) {
+ } else
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
+ &sum);
if (retval != 0) {
zap(tmp.data, tmp.length);
zap(outbuf, len);
krb5_free_data_contents(ctx, &tmp);
@@ -180,7 +189,8 @@ user_password_encode(krb5_context ctx, const char *secret,
@@ -180,7 +191,8 @@ user_password_encode(krb5_context ctx, const char *secret,
static krb5_error_code
user_password_decode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
@ -78,21 +90,24 @@ index 9c13d9d75..3a2d0243b 100644
{
const unsigned char *indx;
krb5_error_code retval;
@@ -206,7 +216,12 @@ user_password_decode(krb5_context ctx, const char *secret,
@@ -204,8 +216,14 @@ user_password_decode(krb5_context ctx, const char *secret,
for (blck = 0, indx = auth; blck * BLOCKSIZE < in->length; blck++) {
memcpy(tmp.data + seclen, indx, BLOCKSIZE);
retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
&tmp, &sum);
- if (retval != 0) {
+ if (retval == ENOMEM) {
+ /* I'm Linux, so we know this is a FIPS failure. Assume the
+ * other side is running locally and move on. */
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
- &tmp, &sum);
+ if (FIPS_mode()) {
+ /* Skip encryption here. Taint so that we won't pass it out of
+ * the machine by accident. */
+ *is_fips = TRUE;
+ sum.contents = calloc(1, BLOCKSIZE);
+ } else if (retval != 0) {
+ } else
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
+ &tmp, &sum);
if (retval != 0) {
zap(tmp.data, tmp.length);
zap(outbuf, in->length);
krb5_free_data_contents(ctx, &tmp);
@@ -248,7 +263,7 @@ krb5_error_code
@@ -248,7 +266,7 @@ krb5_error_code
kr_attr_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, krad_attr type,
const krb5_data *in, unsigned char outbuf[MAX_ATTRSIZE],
@ -101,7 +116,7 @@ index 9c13d9d75..3a2d0243b 100644
{
krb5_error_code retval;
@@ -265,7 +280,8 @@ kr_attr_encode(krb5_context ctx, const char *secret,
@@ -265,7 +283,8 @@ kr_attr_encode(krb5_context ctx, const char *secret,
return 0;
}
@ -111,7 +126,7 @@ index 9c13d9d75..3a2d0243b 100644
}
krb5_error_code
@@ -274,6 +290,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
@@ -274,6 +293,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
{
krb5_error_code retval;
@ -119,7 +134,7 @@ index 9c13d9d75..3a2d0243b 100644
retval = kr_attr_valid(type, in);
if (retval != 0)
@@ -288,7 +305,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
@@ -288,7 +308,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
return 0;
}
@ -191,10 +206,18 @@ index 996a89372..a53ce31ce 100644
/* Decode attributes from a buffer. */
krb5_error_code
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
index c597174b6..2fbf0ee1e 100644
index c597174b6..794ac84c4 100644
--- a/src/lib/krad/packet.c
+++ b/src/lib/krad/packet.c
@@ -53,12 +53,6 @@ typedef unsigned char uchar;
@@ -32,6 +32,7 @@
#include <string.h>
#include <arpa/inet.h>
+#include <openssl/crypto.h>
typedef unsigned char uchar;
@@ -53,12 +54,6 @@ typedef unsigned char uchar;
#define pkt_auth(p) ((uchar *)offset(&(p)->pkt, OFFSET_AUTH))
#define pkt_attr(p) ((unsigned char *)offset(&(p)->pkt, OFFSET_ATTR))
@ -207,20 +230,23 @@ index c597174b6..2fbf0ee1e 100644
typedef struct {
uchar x[(UCHAR_MAX + 1) / 8];
} idmap;
@@ -190,7 +184,11 @@ auth_generate_response(krb5_context ctx, const char *secret,
retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
&hash);
free(data.data);
- if (retval != 0)
+ if (retval == ENOMEM) {
+ /* We're on Linux, so this is a FIPS failure, and this checksum
+ * does very little security-wise anyway, so don't taint. */
+ hash.contents = calloc(1, AUTH_FIELD_SIZE);
+ } else if (retval != 0)
return retval;
@@ -187,8 +182,13 @@ auth_generate_response(krb5_context ctx, const char *secret,
memcpy(data.data + response->pkt.length, secret, strlen(secret));
memcpy(rauth, hash.contents, AUTH_FIELD_SIZE);
@@ -276,7 +274,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
/* Hash it. */
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
- &hash);
+ if (FIPS_mode()) {
+ /* This checksum does very little security-wise anyway, so don't
+ * taint. */
+ hash.contents = calloc(1, AUTH_FIELD_SIZE);
+ } else
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
+ &hash);
free(data.data);
if (retval != 0)
return retval;
@@ -276,7 +276,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
/* Encode the attributes. */
retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
@ -229,7 +255,7 @@ index c597174b6..2fbf0ee1e 100644
if (retval != 0)
goto error;
@@ -314,7 +312,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
@@ -314,7 +314,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
/* Encode the attributes. */
retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
@ -238,7 +264,7 @@ index c597174b6..2fbf0ee1e 100644
if (retval != 0)
goto error;
@@ -451,6 +449,8 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
@@ -451,6 +451,8 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
const krb5_data *
krad_packet_encode(const krad_packet *pkt)
{

View File

@ -18,7 +18,7 @@ Summary: The Kerberos network authentication system
Name: krb5
Version: 1.17
# for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces)
Release: 1.beta1.1%{?dist}
Release: 1.beta1.2%{?dist}
# lookaside-cached sources; two downloads and a build artifact
Source0: https://web.mit.edu/kerberos/dist/krb5/1.16/krb5-%{version}%{prerelease}.tar.gz
@ -60,8 +60,9 @@ Patch33: krb5-1.13-dirsrv-accountlock.patch
Patch34: krb5-1.9-debuginfo.patch
Patch35: krb5-1.11-run_user_0.patch
Patch36: krb5-1.11-kpasswdtest.patch
Patch86: In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch
Patch87: Fix-spurious-errors-from-kcmio_unix_socket_write.patch
Patch88: Become-FIPS-aware.patch
Patch89: In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch
License: MIT
URL: http://web.mit.edu/kerberos/www/
@ -709,11 +710,14 @@ exit 0
%{_libdir}/libkadm5srv_mit.so.*
%changelog
* Thu Nov 08 2018 Robbie Harwood <rharwood@redhat.com> - 1.17-1
* Mon Nov 12 2018 Robbie Harwood <rharwood@redhat.com> - 1.17-1.beta1.2
- Gain FIPS awareness
* Thu Nov 08 2018 Robbie Harwood <rharwood@redhat.com> - 1.17-1.beta1.1
- Fix spurious errors from kcmio_unix_socket_write
- Resolves: #1645912
* Thu Nov 01 2018 Robbie Harwood <rharwood@redhat.com> - 1.17-0.beta2.1
* Thu Nov 01 2018 Robbie Harwood <rharwood@redhat.com> - 1.17-0.beta1.1
- New upstream beta release
* Wed Oct 24 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-25