diff -aur squid-3.2.0.16-orig/helpers/basic_auth/NCSA/basic_ncsa_auth.cc squid-3.2.0.16/helpers/basic_auth/NCSA/basic_ncsa_auth.cc --- squid-3.2.0.16-orig/helpers/basic_auth/NCSA/basic_ncsa_auth.cc 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/basic_auth/NCSA/basic_ncsa_auth.cc 2012-06-19 18:49:12.889646542 -0400 @@ -42,6 +42,8 @@ #include #endif +extern int GetFIPSEnabled(void); + static hash_table *hash = NULL; static HASHFREE my_free; @@ -52,6 +54,41 @@ char *passwd; } user_data; +/* + * Return 1 if we are in fips mode and we should disallow MD5 for any + * network and authentication use + * Quick and dirty way to test functionality in fips mode: + * echo "1" > /tmp/fips_enabled + * sudo mount --bind /tmp/fips_enabled /proc/sys/crypto/fips_enabled + * and umount to disable fips again + */ +static int +my_GetFIPSEnabled(void) +{ +#ifdef LINUX + FILE *f; + char d; + size_t size; + + f = fopen("/proc/sys/crypto/fips_enabled", "r"); + if (!f) + return 0; + + size = fread(&d, 1, 1, f); + fclose(f); + if (size != 1) + return 0; + if (d != '1') + return 0; + + return 1; +#else + return 0; /* we only know about Linux fips mode */ +#endif +} + + + static void my_free(void *p) { @@ -139,21 +176,29 @@ u = (user_data *) hash_lookup(hash, user); if (u == NULL) { SEND_ERR("No such user"); + } #if HAVE_CRYPT - } else if (strlen(passwd) <= 8 && strcmp(u->passwd, (char *) crypt(passwd, u->passwd)) == 0) { - // Bug 3107: crypt() DES functionality silently truncates long passwords. - SEND_OK(""); - } else if (strlen(passwd) > 8 && strcmp(u->passwd, (char *) crypt(passwd, u->passwd)) == 0) { - // Bug 3107: crypt() DES functionality silently truncates long passwords. - SEND_ERR("Password too long. Only 8 characters accepted."); + /* using the real crypt() call with return NULL for non-allowed algos passed via the salt */ + else { + char *crypted = crypt(passwd, u->passwd); /* avoid strcmp() on NULL */ + if (crypted && strlen(passwd) <= 8 && strcmp(u->passwd, crypted) == 0) { + // Bug 3107: crypt() DES functionality silently truncates long passwords. + SEND_OK(""); + } else if (strlen(passwd) > 8 && strcmp(u->passwd, crypted) == 0) { + // Bug 3107: crypt() DES functionality silently truncates long passwords. + SEND_ERR("Password too long. Only 8 characters accepted."); + } +#endif + else if (!my_GetFIPSEnabled() && strcmp(u->passwd, (char *) crypt_md5(passwd, u->passwd)) == 0) { + SEND_OK(""); + } else if (!my_GetFIPSEnabled() && strcmp(u->passwd, (char *) md5sum(passwd)) == 0) { + SEND_OK(""); + } else { + SEND_ERR("Wrong password"); + } +#if HAVE_CRYPT + } #endif - } else if (strcmp(u->passwd, (char *) crypt_md5(passwd, u->passwd)) == 0) { - SEND_OK(""); - } else if (strcmp(u->passwd, (char *) md5sum(passwd)) == 0) { - SEND_OK(""); - } else { - SEND_ERR("Wrong password"); - } } if (hash != NULL) { hashFreeItems(hash, my_free); diff -aur squid-3.2.0.16-orig/helpers/basic_auth/NCSA/crypt_md5.h squid-3.2.0.16/helpers/basic_auth/NCSA/crypt_md5.h --- squid-3.2.0.16-orig/helpers/basic_auth/NCSA/crypt_md5.h 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/basic_auth/NCSA/crypt_md5.h 2012-06-19 18:47:05.979122455 -0400 @@ -20,4 +20,6 @@ /* MD5 hash without salt */ char *md5sum(const char *s); +extern int GetFIPSEnabled(void); + #endif /* _CRYPT_MD5_H */ diff -aur squid-3.2.0.16-orig/helpers/basic_auth/RADIUS/basic_radius_auth.cc squid-3.2.0.16/helpers/basic_auth/RADIUS/basic_radius_auth.cc --- squid-3.2.0.16-orig/helpers/basic_auth/RADIUS/basic_radius_auth.cc 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/basic_auth/RADIUS/basic_radius_auth.cc 2012-06-19 18:47:05.980122467 -0400 @@ -294,6 +294,11 @@ socklen_t salen; int retry = retries; + if (GetFIPSEnabled()) { + debug("MD5 not allowed in FIPS mode"); + return -1; + } + /* * Build an authentication request */ diff -aur squid-3.2.0.16-orig/helpers/digest_auth/eDirectory/ldap_backend.cc squid-3.2.0.16/helpers/digest_auth/eDirectory/ldap_backend.cc --- squid-3.2.0.16-orig/helpers/digest_auth/eDirectory/ldap_backend.cc 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/digest_auth/eDirectory/ldap_backend.cc 2012-06-19 18:47:05.980122467 -0400 @@ -676,6 +676,11 @@ xstrncpy(requestData->HHA1, password, sizeof(requestData->HHA1)); else { HASH HA1; +#ifdef LINUX + if (GetFIPSEnabled()) { + requestData->error = -1; /* not allowed to do user auth with md5 in fips */ + } else +#endif DigestCalcHA1("md5", requestData->user, requestData->realm, password, NULL, NULL, HA1, requestData->HHA1); } free(password); diff -aur squid-3.2.0.16-orig/helpers/digest_auth/eDirectory/ldap_backend.h squid-3.2.0.16/helpers/digest_auth/eDirectory/ldap_backend.h --- squid-3.2.0.16-orig/helpers/digest_auth/eDirectory/ldap_backend.h 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/digest_auth/eDirectory/ldap_backend.h 2012-06-19 18:47:05.980122467 -0400 @@ -7,3 +7,5 @@ #include "digest_common.h" extern int LDAPArguments(int argc, char **argv); extern void LDAPHHA1(RequestData * requestData); +extern int GetFIPSEnabled(void); + diff -aur squid-3.2.0.16-orig/helpers/digest_auth/file/text_backend.cc squid-3.2.0.16/helpers/digest_auth/file/text_backend.cc --- squid-3.2.0.16-orig/helpers/digest_auth/file/text_backend.cc 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/digest_auth/file/text_backend.cc 2012-06-19 18:47:05.981122479 -0400 @@ -38,6 +38,8 @@ static int ha1mode = 0; static time_t change_time = 0; +extern int GetFIPSEnabled(void); + typedef struct _user_data { hash_link hash; char *passwd; @@ -177,6 +179,11 @@ xstrncpy(requestData->HHA1, u->ha1, sizeof(requestData->HHA1)); } else { HASH HA1; +#ifdef LINUX + if (GetFIPSEnabled()) { + requestData->error = -1; /* not allowed to do user auth with md5 in fips */ + } else +#endif DigestCalcHA1("md5", requestData->user, requestData->realm, u->passwd, NULL, NULL, HA1, requestData->HHA1); } } diff -aur squid-3.2.0.16-orig/helpers/digest_auth/file/text_backend.h squid-3.2.0.16/helpers/digest_auth/file/text_backend.h --- squid-3.2.0.16-orig/helpers/digest_auth/file/text_backend.h 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/digest_auth/file/text_backend.h 2012-06-19 18:47:05.981122479 -0400 @@ -23,3 +23,5 @@ extern void TextArguments(int argc, char **argv); extern void TextHHA1(RequestData * requestData); +extern int GetFIPSEnabled(void); + diff -aur squid-3.2.0.16-orig/helpers/digest_auth/LDAP/ldap_backend.cc squid-3.2.0.16/helpers/digest_auth/LDAP/ldap_backend.cc --- squid-3.2.0.16-orig/helpers/digest_auth/LDAP/ldap_backend.cc 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/digest_auth/LDAP/ldap_backend.cc 2012-06-19 18:47:05.981122479 -0400 @@ -644,6 +644,11 @@ xstrncpy(requestData->HHA1, password, sizeof(requestData->HHA1)); else { HASH HA1; +#ifdef LINUX + if (GetFIPSEnabled()) { + requestData->error = -1; /* not allowed to do user auth with md5 in fips */ + } else +#endif DigestCalcHA1("md5", requestData->user, requestData->realm, password, NULL, NULL, HA1, requestData->HHA1); } free(password); diff -aur squid-3.2.0.16-orig/helpers/digest_auth/LDAP/ldap_backend.h squid-3.2.0.16/helpers/digest_auth/LDAP/ldap_backend.h --- squid-3.2.0.16-orig/helpers/digest_auth/LDAP/ldap_backend.h 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/helpers/digest_auth/LDAP/ldap_backend.h 2012-06-19 18:47:05.982122491 -0400 @@ -7,3 +7,4 @@ #include "digest_common.h" extern int LDAPArguments(int argc, char **argv); extern void LDAPHHA1(RequestData * requestData); +extern int GetFIPSEnabled(void); diff -aur squid-3.2.0.16-orig/include/md5.h squid-3.2.0.16/include/md5.h --- squid-3.2.0.16-orig/include/md5.h 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/include/md5.h 2012-06-19 18:47:05.982122491 -0400 @@ -38,7 +38,9 @@ uint32_t in[16]; } SquidMD5_CTX; +SQUIDCEXTERN int GetFIPSEnabled(void); SQUIDCEXTERN void SquidMD5Init(struct SquidMD5Context *context); +SQUIDCEXTERN void SquidMD5InitFipsOK(struct SquidMD5Context *context); SQUIDCEXTERN void SquidMD5Update(struct SquidMD5Context *context, const void *buf, unsigned len); SQUIDCEXTERN void SquidMD5Final(uint8_t digest[16], struct SquidMD5Context *context); SQUIDCEXTERN void SquidMD5Transform(uint32_t buf[4], uint32_t const in[16]); diff -aur squid-3.2.0.16-orig/lib/md5.c squid-3.2.0.16/lib/md5.c --- squid-3.2.0.16-orig/lib/md5.c 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/lib/md5.c 2012-06-19 18:47:05.982122491 -0400 @@ -55,13 +55,60 @@ #define byteSwap(buf,words) #endif +/* + * Return 1 if we are in fips mode and we should disallow MD5 for any + * network and authentication use + * Quick and dirty way to test functionality in fips mode: + * echo "1" > /tmp/fips_enabled + * sudo mount --bind /tmp/fips_enabled /proc/sys/crypto/fips_enabled + * and umount to disable fips again + */ +int +GetFIPSEnabled(void) +{ +#ifdef LINUX + FILE *f; + char d; + size_t size; + + f = fopen("/proc/sys/crypto/fips_enabled", "r"); + if (!f) + return 0; + + size = fread(&d, 1, 1, f); + fclose(f); + if (size != 1) + return 0; + if (d != '1') + return 0; + + return 1; +#else + return 0; /* we only know about Linux fips mode */ +#endif +} + /* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. + * since these functions can't return success/failure, we assert and + * hope people will fix the code */ void SquidMD5Init(struct SquidMD5Context *ctx) { + if(GetFIPSEnabled()){ + printf("ERROR, MD5 call in fips mode is not allowed!\n"); + assert(GetFIPSEnabled() == 1); + } + SquidMD5InitFipsOK(ctx); +} + +void +SquidMD5InitFipsOK(struct SquidMD5Context *ctx) +{ +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; ctx->buf[2] = 0x98badcfe; diff -aur squid-3.2.0.16-orig/lib/rfc2617.c squid-3.2.0.16/lib/rfc2617.c --- squid-3.2.0.16-orig/lib/rfc2617.c 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/lib/rfc2617.c 2012-06-19 18:47:05.983122503 -0400 @@ -51,6 +51,8 @@ #include "rfc2617.h" #include "md5.h" +extern int GetFIPSEnabled(void); + void CvtHex(const HASH Bin, HASHHEX Hex) { @@ -120,6 +122,11 @@ { SquidMD5_CTX Md5Ctx; + if(GetFIPSEnabled() && strncmp(pszAlg, "md5", 3) == 0) { + fprintf(stderr,"We should not call DigestCalcHA1() with md5 in fips mode\n"); + assert(GetFIPSEnabled() == 1); + } + if (pszUserName) { SquidMD5Init(&Md5Ctx); SquidMD5Update(&Md5Ctx, pszUserName, strlen(pszUserName)); diff -aur squid-3.2.0.16-orig/src/MemObject.cc squid-3.2.0.16/src/MemObject.cc --- squid-3.2.0.16-orig/src/MemObject.cc 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/src/MemObject.cc 2012-06-19 18:47:05.983122503 -0400 @@ -55,7 +55,7 @@ unsigned int ck; SquidMD5_CTX M; static unsigned char digest[16]; - SquidMD5Init(&M); + SquidMD5InitFipsOK(&M); /* override fips check, this md5 use is ok */ SquidMD5Update(&M, (unsigned char *) url, strlen(url)); SquidMD5Final(digest, &M); memcpy(&ck, digest, sizeof(ck)); diff -aur squid-3.2.0.16-orig/src/store_key_md5.cc squid-3.2.0.16/src/store_key_md5.cc --- squid-3.2.0.16-orig/src/store_key_md5.cc 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/src/store_key_md5.cc 2012-06-19 18:47:05.983122503 -0400 @@ -105,7 +105,7 @@ SquidMD5_CTX M; assert(id > 0); debugs(20, 3, "storeKeyPrivate: " << RequestMethodStr(method) << " " << url); - SquidMD5Init(&M); + SquidMD5InitFipsOK(&M); /* override fips check, this md5 use is ok */ SquidMD5Update(&M, (unsigned char *) &id, sizeof(id)); SquidMD5Update(&M, (unsigned char *) &method, sizeof(method)); SquidMD5Update(&M, (unsigned char *) url, strlen(url)); @@ -119,7 +119,7 @@ static cache_key digest[SQUID_MD5_DIGEST_LENGTH]; unsigned char m = (unsigned char) method.id(); SquidMD5_CTX M; - SquidMD5Init(&M); + SquidMD5InitFipsOK(&M); /* override fips check, this md5 use is ok */ SquidMD5Update(&M, &m, sizeof(m)); SquidMD5Update(&M, (unsigned char *) url, strlen(url)); SquidMD5Final(digest, &M); @@ -139,7 +139,7 @@ unsigned char m = (unsigned char) method.id(); const char *url = urlCanonical(request); SquidMD5_CTX M; - SquidMD5Init(&M); + SquidMD5InitFipsOK(&M); /* override fips check, this md5 use is ok */ SquidMD5Update(&M, &m, sizeof(m)); SquidMD5Update(&M, (unsigned char *) url, strlen(url)); diff -aur squid-3.2.0.16-orig/src/wccp2.cc squid-3.2.0.16/src/wccp2.cc --- squid-3.2.0.16-orig/src/wccp2.cc 2012-03-06 21:42:55.000000000 -0500 +++ squid-3.2.0.16/src/wccp2.cc 2012-06-19 18:47:05.984122515 -0400 @@ -52,6 +52,8 @@ #define WCCP_RESPONSE_SIZE 12448 #define WCCP_BUCKETS 256 +extern int GetFIPSEnabled(void); + static int theWccp2Connection = -1; static int wccp2_connected = 0; @@ -587,6 +589,13 @@ debugs(80, 5, "wccp2_update_md5_security: called"); +#ifdef LINUX + if(GetFIPSEnabled()) { + debugs(80, 5, "wccp2_update_md5_security: not allowed in fips mode, abort"); + return 0; + } +#endif + /* The password field, for the MD5 hash, needs to be 8 bytes and NUL padded. */ memset(pwd, 0, sizeof(pwd)); strncpy(pwd, password, sizeof(pwd)); @@ -655,6 +664,13 @@ /* If execution makes it here then we have an MD5 security */ +#ifdef LINUX + if(GetFIPSEnabled()) { + debugs(80, 1, "wccp2_check_security: not allowed in fips mode, abort"); + return 0; + } +#endif + /* The password field, for the MD5 hash, needs to be 8 bytes and NUL padded. */ memset(pwd, 0, sizeof(pwd));