mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-01-31 01:04:03 -05:00
Allow non-FIPS MD5 to be used with TLS PRF even in FIPS mode
This is allowed per FIPS1402IG.pdf since the TLS PRF depends fully on both MD5 and SHA-1.
This commit is contained in:
parent
be299ca4ce
commit
ff916b9df7
@ -47,6 +47,22 @@ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
|
|||||||
*/
|
*/
|
||||||
int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
|
int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
|
||||||
|
|
||||||
|
#ifdef CONFIG_FIPS
|
||||||
|
/**
|
||||||
|
* md5_vector_non_fips_allow - MD5 hash for data vector (non-FIPS use allowed)
|
||||||
|
* @num_elem: Number of elements in the data vector
|
||||||
|
* @addr: Pointers to the data areas
|
||||||
|
* @len: Lengths of the data blocks
|
||||||
|
* @mac: Buffer for the hash
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int md5_vector_non_fips_allow(size_t num_elem, const u8 *addr[],
|
||||||
|
const size_t *len, u8 *mac);
|
||||||
|
#else /* CONFIG_FIPS */
|
||||||
|
#define md5_vector_non_fips_allow md5_vector
|
||||||
|
#endif /* CONFIG_FIPS */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sha1_vector - SHA-1 hash for data vector
|
* sha1_vector - SHA-1 hash for data vector
|
||||||
* @num_elem: Number of elements in the data vector
|
* @num_elem: Number of elements in the data vector
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#endif /* openssl < 0.9.7 */
|
#endif /* openssl < 0.9.7 */
|
||||||
|
|
||||||
|
|
||||||
int openssl_digest_vector(const EVP_MD *type, size_t num_elem,
|
int openssl_digest_vector(const EVP_MD *type, int non_fips, size_t num_elem,
|
||||||
const u8 *addr[], const size_t *len, u8 *mac)
|
const u8 *addr[], const size_t *len, u8 *mac)
|
||||||
{
|
{
|
||||||
EVP_MD_CTX ctx;
|
EVP_MD_CTX ctx;
|
||||||
@ -40,6 +40,8 @@ int openssl_digest_vector(const EVP_MD *type, size_t num_elem,
|
|||||||
unsigned int mac_len;
|
unsigned int mac_len;
|
||||||
|
|
||||||
EVP_MD_CTX_init(&ctx);
|
EVP_MD_CTX_init(&ctx);
|
||||||
|
if (non_fips)
|
||||||
|
EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||||
if (!EVP_DigestInit_ex(&ctx, type, NULL)) {
|
if (!EVP_DigestInit_ex(&ctx, type, NULL)) {
|
||||||
wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
|
wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
@ -65,7 +67,7 @@ int openssl_digest_vector(const EVP_MD *type, size_t num_elem,
|
|||||||
|
|
||||||
int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
|
int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
|
||||||
{
|
{
|
||||||
return openssl_digest_vector(EVP_md4(), num_elem, addr, len, mac);
|
return openssl_digest_vector(EVP_md4(), 0, num_elem, addr, len, mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -92,20 +94,30 @@ void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
|
|||||||
|
|
||||||
int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
|
int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
|
||||||
{
|
{
|
||||||
return openssl_digest_vector(EVP_md5(), num_elem, addr, len, mac);
|
return openssl_digest_vector(EVP_md5(), 0, num_elem, addr, len, mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_FIPS
|
||||||
|
int md5_vector_non_fips_allow(size_t num_elem, const u8 *addr[],
|
||||||
|
const size_t *len, u8 *mac)
|
||||||
|
{
|
||||||
|
return openssl_digest_vector(EVP_md5(), 1, num_elem, addr, len, mac);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FIPS */
|
||||||
|
|
||||||
|
|
||||||
int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
|
int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
|
||||||
{
|
{
|
||||||
return openssl_digest_vector(EVP_sha1(), num_elem, addr, len, mac);
|
return openssl_digest_vector(EVP_sha1(), 0, num_elem, addr, len, mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
|
int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
|
||||||
u8 *mac)
|
u8 *mac)
|
||||||
{
|
{
|
||||||
return openssl_digest_vector(EVP_sha256(), num_elem, addr, len, mac);
|
return openssl_digest_vector(EVP_sha256(), 0, num_elem, addr, len,
|
||||||
|
mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
113
src/crypto/md5-non-fips.c
Normal file
113
src/crypto/md5-non-fips.c
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* MD5 hash implementation and interface functions (non-FIPS allowed cases)
|
||||||
|
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Alternatively, this software may be distributed under the terms of BSD
|
||||||
|
* license.
|
||||||
|
*
|
||||||
|
* See README and COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "md5.h"
|
||||||
|
#include "crypto.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hmac_md5_vector_non_fips_allow - HMAC-MD5 over data vector (RFC 2104)
|
||||||
|
* @key: Key for HMAC operations
|
||||||
|
* @key_len: Length of the key in bytes
|
||||||
|
* @num_elem: Number of elements in the data vector
|
||||||
|
* @addr: Pointers to the data areas
|
||||||
|
* @len: Lengths of the data blocks
|
||||||
|
* @mac: Buffer for the hash (16 bytes)
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int hmac_md5_vector_non_fips_allow(const u8 *key, size_t key_len,
|
||||||
|
size_t num_elem, const u8 *addr[],
|
||||||
|
const size_t *len, u8 *mac)
|
||||||
|
{
|
||||||
|
u8 k_pad[64]; /* padding - key XORd with ipad/opad */
|
||||||
|
u8 tk[16];
|
||||||
|
const u8 *_addr[6];
|
||||||
|
size_t i, _len[6];
|
||||||
|
|
||||||
|
if (num_elem > 5) {
|
||||||
|
/*
|
||||||
|
* Fixed limit on the number of fragments to avoid having to
|
||||||
|
* allocate memory (which could fail).
|
||||||
|
*/
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if key is longer than 64 bytes reset it to key = MD5(key) */
|
||||||
|
if (key_len > 64) {
|
||||||
|
if (md5_vector_non_fips_allow(1, &key, &key_len, tk))
|
||||||
|
return -1;
|
||||||
|
key = tk;
|
||||||
|
key_len = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the HMAC_MD5 transform looks like:
|
||||||
|
*
|
||||||
|
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
||||||
|
*
|
||||||
|
* where K is an n byte key
|
||||||
|
* ipad is the byte 0x36 repeated 64 times
|
||||||
|
* opad is the byte 0x5c repeated 64 times
|
||||||
|
* and text is the data being protected */
|
||||||
|
|
||||||
|
/* start out by storing key in ipad */
|
||||||
|
os_memset(k_pad, 0, sizeof(k_pad));
|
||||||
|
os_memcpy(k_pad, key, key_len);
|
||||||
|
|
||||||
|
/* XOR key with ipad values */
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
k_pad[i] ^= 0x36;
|
||||||
|
|
||||||
|
/* perform inner MD5 */
|
||||||
|
_addr[0] = k_pad;
|
||||||
|
_len[0] = 64;
|
||||||
|
for (i = 0; i < num_elem; i++) {
|
||||||
|
_addr[i + 1] = addr[i];
|
||||||
|
_len[i + 1] = len[i];
|
||||||
|
}
|
||||||
|
if (md5_vector_non_fips_allow(1 + num_elem, _addr, _len, mac))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
os_memset(k_pad, 0, sizeof(k_pad));
|
||||||
|
os_memcpy(k_pad, key, key_len);
|
||||||
|
/* XOR key with opad values */
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
k_pad[i] ^= 0x5c;
|
||||||
|
|
||||||
|
/* perform outer MD5 */
|
||||||
|
_addr[0] = k_pad;
|
||||||
|
_len[0] = 64;
|
||||||
|
_addr[1] = mac;
|
||||||
|
_len[1] = MD5_MAC_LEN;
|
||||||
|
return md5_vector_non_fips_allow(2, _addr, _len, mac);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hmac_md5_non_fips_allow - HMAC-MD5 over data buffer (RFC 2104)
|
||||||
|
* @key: Key for HMAC operations
|
||||||
|
* @key_len: Length of the key in bytes
|
||||||
|
* @data: Pointers to the data area
|
||||||
|
* @data_len: Length of the data area
|
||||||
|
* @mac: Buffer for the hash (16 bytes)
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int hmac_md5_non_fips_allow(const u8 *key, size_t key_len, const u8 *data,
|
||||||
|
size_t data_len, u8 *mac)
|
||||||
|
{
|
||||||
|
return hmac_md5_vector_non_fips_allow(key, key_len, 1, &data,
|
||||||
|
&data_len, mac);
|
||||||
|
}
|
@ -21,5 +21,15 @@ int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
|
|||||||
const u8 *addr[], const size_t *len, u8 *mac);
|
const u8 *addr[], const size_t *len, u8 *mac);
|
||||||
int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
|
int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
|
||||||
u8 *mac);
|
u8 *mac);
|
||||||
|
#ifdef CONFIG_FIPS
|
||||||
|
int hmac_md5_vector_non_fips_allow(const u8 *key, size_t key_len,
|
||||||
|
size_t num_elem, const u8 *addr[],
|
||||||
|
const size_t *len, u8 *mac);
|
||||||
|
int hmac_md5_non_fips_allow(const u8 *key, size_t key_len, const u8 *data,
|
||||||
|
size_t data_len, u8 *mac);
|
||||||
|
#else /* CONFIG_FIPS */
|
||||||
|
#define hmac_md5_vector_non_fips_allow hmac_md5_vector
|
||||||
|
#define hmac_md5_non_fips_allow hmac_md5
|
||||||
|
#endif /* CONFIG_FIPS */
|
||||||
|
|
||||||
#endif /* MD5_H */
|
#endif /* MD5_H */
|
||||||
|
@ -78,16 +78,19 @@ int tls_prf(const u8 *secret, size_t secret_len, const char *label,
|
|||||||
S2--;
|
S2--;
|
||||||
}
|
}
|
||||||
|
|
||||||
hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
|
hmac_md5_vector_non_fips_allow(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1],
|
||||||
|
A_MD5);
|
||||||
hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
|
hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
|
||||||
|
|
||||||
MD5_pos = MD5_MAC_LEN;
|
MD5_pos = MD5_MAC_LEN;
|
||||||
SHA1_pos = SHA1_MAC_LEN;
|
SHA1_pos = SHA1_MAC_LEN;
|
||||||
for (i = 0; i < outlen; i++) {
|
for (i = 0; i < outlen; i++) {
|
||||||
if (MD5_pos == MD5_MAC_LEN) {
|
if (MD5_pos == MD5_MAC_LEN) {
|
||||||
hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
|
hmac_md5_vector_non_fips_allow(S1, L_S1, 3, MD5_addr,
|
||||||
|
MD5_len, P_MD5);
|
||||||
MD5_pos = 0;
|
MD5_pos = 0;
|
||||||
hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
|
hmac_md5_non_fips_allow(S1, L_S1, A_MD5, MD5_MAC_LEN,
|
||||||
|
A_MD5);
|
||||||
}
|
}
|
||||||
if (SHA1_pos == SHA1_MAC_LEN) {
|
if (SHA1_pos == SHA1_MAC_LEN) {
|
||||||
hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
|
hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
|
||||||
|
@ -1068,6 +1068,7 @@ endif
|
|||||||
|
|
||||||
ifdef CONFIG_FIPS
|
ifdef CONFIG_FIPS
|
||||||
CFLAGS += -DCONFIG_FIPS
|
CFLAGS += -DCONFIG_FIPS
|
||||||
|
MD5OBJS += ../src/crypto/md5-non-fips.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_NDIS_EVENTS_INTEGRATED
|
ifdef CONFIG_NDIS_EVENTS_INTEGRATED
|
||||||
|
Loading…
Reference in New Issue
Block a user