Merge pull request #3904 from bjcollins/master
FIPS Mode support for xfreerdp
This commit is contained in:
commit
b156b937fe
@ -91,6 +91,7 @@ static COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "encryption-methods", COMMAND_LINE_VALUE_REQUIRED, "[40,][56,][128,][FIPS]", NULL, NULL, -1, NULL, "RDP standard security encryption methods" },
|
||||
{ "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Fullscreen mode" },
|
||||
{ "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable fast-path input/output" },
|
||||
{ "fipsmode", COMMAND_LINE_VALUE_BOOL, NULL, NULL, NULL, -1, NULL, "Enable FIPS mode" },
|
||||
{ "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Enable smooth fonts (ClearType)" },
|
||||
{ "frame-ack", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Number of frame acknowledgement" },
|
||||
{ "from-stdin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Read credentials from stdin, do not use defaults." },
|
||||
@ -2767,6 +2768,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
if (!(settings->ActionScript = _strdup(arg->Value)))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "fipsmode")
|
||||
{
|
||||
settings->FIPSMode = TRUE;
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
}
|
||||
@ -2822,6 +2827,17 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
settings->ColorDepth = 32;
|
||||
}
|
||||
|
||||
/* FIPS Mode forces the following and overrides the following(by happening later */
|
||||
/* in the command line processing): */
|
||||
/* 1. Disables NLA Security since NLA in freerdp uses NTLM(no Kerberos support yet) which uses algorithms */
|
||||
/* not allowed in FIPS for sensitive data. So, we disallow NLA when FIPS is required. */
|
||||
/* 2. Forces the only supported RDP encryption method to be FIPS. */
|
||||
if (settings->FIPSMode)
|
||||
{
|
||||
settings->NlaSecurity = FALSE;
|
||||
settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS;
|
||||
}
|
||||
|
||||
arg = CommandLineFindArgumentA(args, "port");
|
||||
|
||||
if (arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)
|
||||
|
@ -606,6 +606,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_AllowedTlsCiphers 1101
|
||||
#define FreeRDP_VmConnectMode 1102
|
||||
#define FreeRDP_NtlmSamFile 1103
|
||||
#define FreeRDP_FIPSMode 1104
|
||||
#define FreeRDP_MstscCookieMode 1152
|
||||
#define FreeRDP_CookieMaxLength 1153
|
||||
#define FreeRDP_PreconnectionId 1154
|
||||
@ -1018,7 +1019,8 @@ struct rdp_settings
|
||||
ALIGN64 char* AllowedTlsCiphers; /* 1101 */
|
||||
ALIGN64 BOOL VmConnectMode; /* 1102 */
|
||||
ALIGN64 char* NtlmSamFile; /* 1103 */
|
||||
UINT64 padding1152[1152 - 1104]; /* 1104 */
|
||||
ALIGN64 BOOL FIPSMode; /* 1104 */
|
||||
UINT64 padding1152[1152 - 1105]; /* 1105 */
|
||||
|
||||
/* Connection Cookie */
|
||||
ALIGN64 BOOL MstscCookieMode; /* 1152 */
|
||||
|
@ -921,6 +921,9 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
|
||||
case FreeRDP_ExternalCertificateManagement:
|
||||
return settings->ExternalCertificateManagement;
|
||||
|
||||
case FreeRDP_FIPSMode:
|
||||
return settings->FIPSMode;
|
||||
|
||||
case FreeRDP_Workarea:
|
||||
return settings->Workarea;
|
||||
|
||||
@ -1381,6 +1384,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
|
||||
settings->ExternalCertificateManagement = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_FIPSMode:
|
||||
settings->FIPSMode = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_Workarea:
|
||||
settings->Workarea = param;
|
||||
break;
|
||||
|
@ -408,8 +408,13 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific
|
||||
BYTE encsig[TSSK_KEY_LENGTH + 8];
|
||||
BYTE md5hash[WINPR_MD5_DIGEST_LENGTH];
|
||||
|
||||
if (!winpr_Digest(WINPR_MD_MD5, sigdata, sigdatalen, md5hash, sizeof(md5hash)))
|
||||
return FALSE;
|
||||
/* Do not bother with validation of server proprietary certificate. The use of MD5 here is not allowed under FIPS. */
|
||||
/* Since the validation is not protecting against anything since the private/public keys are well known and documented in */
|
||||
/* MS-RDPBCGR section 5.3.3.1, we are not gaining any security by using MD5 for signature comparison. Rather then use MD5 */
|
||||
/* here we just dont do the validation to avoid its use. Historically, freerdp has been ignoring a failed validation anyways. */
|
||||
/*if (!winpr_Digest(WINPR_MD_MD5, sigdata, sigdatalen, md5hash, sizeof(md5hash)))
|
||||
return FALSE;*/
|
||||
|
||||
Stream_Read(s, encsig, siglen);
|
||||
|
||||
/* Last 8 bytes shall be all zero. */
|
||||
@ -424,15 +429,17 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific
|
||||
}
|
||||
|
||||
siglen -= 8;
|
||||
|
||||
// TODO: check the result of decrypt
|
||||
crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig);
|
||||
|
||||
/* Verify signature. */
|
||||
if (memcmp(md5hash, sig, sizeof(md5hash)) != 0)
|
||||
/* Do not bother with validation of server proprietary certificate as described above. */
|
||||
/*if (memcmp(md5hash, sig, sizeof(md5hash)) != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid signature");
|
||||
//return FALSE;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
* Verify rest of decrypted data:
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
#include <winpr/ssl.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/error.h>
|
||||
@ -178,6 +179,13 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
BOOL status;
|
||||
rdpSettings* settings = rdp->settings;
|
||||
|
||||
/* make sure SSL is initialize for earlier enough for crypto, by taking advantage of winpr SSL FIPS flag for openssl initialization */
|
||||
DWORD flags = WINPR_SSL_INIT_DEFAULT;
|
||||
|
||||
if (settings->FIPSMode)
|
||||
flags |= WINPR_SSL_INIT_ENABLE_FIPS;
|
||||
winpr_InitializeSSL(flags);
|
||||
|
||||
nego_init(rdp->nego);
|
||||
nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort);
|
||||
|
||||
|
@ -615,6 +615,7 @@ BOOL freerdp_context_new(freerdp* instance)
|
||||
rdpRdp* rdp;
|
||||
rdpContext* context;
|
||||
BOOL ret = TRUE;
|
||||
DWORD flags = WINPR_SSL_INIT_DEFAULT;
|
||||
instance->context = (rdpContext*) calloc(1, instance->ContextSize);
|
||||
|
||||
if (!instance->context)
|
||||
@ -930,7 +931,6 @@ freerdp* freerdp_new()
|
||||
if (!instance)
|
||||
return NULL;
|
||||
|
||||
winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
|
||||
instance->ContextSize = sizeof(rdpContext);
|
||||
instance->SendChannelData = freerdp_send_channel_data;
|
||||
instance->ReceiveChannelData = freerdp_channels_data;
|
||||
|
@ -424,7 +424,10 @@ BOOL license_generate_hwid(rdpLicense* license)
|
||||
ZeroMemory(macAddress, sizeof(macAddress));
|
||||
ZeroMemory(license->HardwareId, HWID_LENGTH);
|
||||
|
||||
if (!winpr_Digest(WINPR_MD_MD5, macAddress, sizeof(macAddress), &license->HardwareId[HWID_PLATFORM_ID_LENGTH], WINPR_MD5_DIGEST_LENGTH))
|
||||
/* Allow FIPS override for use of MD5 here, really this does not have to be MD5 as we are just taking a MD5 hash of the 6 bytes of 0's(macAddress) */
|
||||
/* and filling in the Data1-Data4 fields of the CLIENT_HARDWARE_ID structure(from MS-RDPELE section 2.2.2.3.1). This is for RDP licensing packets */
|
||||
/* which will already be encrypted under FIPS, so the use of MD5 here is not for sensitive data protection. */
|
||||
if (!winpr_Digest_Allow_FIPS(WINPR_MD_MD5, macAddress, sizeof(macAddress), &license->HardwareId[HWID_PLATFORM_ID_LENGTH], WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@ -495,7 +498,10 @@ BOOL license_decrypt_platform_challenge(rdpLicense* license)
|
||||
return FALSE;
|
||||
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
|
||||
|
||||
if ((rc4 = winpr_RC4_New(license->LicensingEncryptionKey,
|
||||
/* Allow FIPS override for use of RC4 here, this is only used for decrypting the MACData field of the */
|
||||
/* Server Platform Challenge packet (from MS-RDPELE section 2.2.2.4). This is for RDP licensing packets */
|
||||
/* which will already be encrypted under FIPS, so the use of RC4 here is not for sensitive data protection. */
|
||||
if ((rc4 = winpr_RC4_New_Allow_FIPS(license->LicensingEncryptionKey,
|
||||
LICENSING_ENCRYPTION_KEY_LENGTH)) == NULL)
|
||||
{
|
||||
free(license->PlatformChallenge->data);
|
||||
@ -1089,7 +1095,10 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
|
||||
if (!status)
|
||||
return FALSE;
|
||||
|
||||
rc4 = winpr_RC4_New(license->LicensingEncryptionKey,
|
||||
/* Allow FIPS override for use of RC4 here, this is only used for encrypting the EncryptedHWID field of the */
|
||||
/* Client Platform Challenge Response packet (from MS-RDPELE section 2.2.2.5). This is for RDP licensing packets */
|
||||
/* which will already be encrypted under FIPS, so the use of RC4 here is not for sensitive data protection. */
|
||||
rc4 = winpr_RC4_New_Allow_FIPS(license->LicensingEncryptionKey,
|
||||
LICENSING_ENCRYPTION_KEY_LENGTH);
|
||||
if (!rc4)
|
||||
return FALSE;
|
||||
|
@ -153,7 +153,10 @@ static BOOL security_salted_hash(const BYTE* salt, const BYTE* input, int length
|
||||
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
/* Allow FIPS override for use of MD5 here, this is used for creating hashes of the premaster_secret and master_secret */
|
||||
/* used for RDP licensing as described in MS-RDPELE. This is for RDP licensing packets */
|
||||
/* which will already be encrypted under FIPS, so the use of MD5 here is not for sensitive data protection. */
|
||||
if (!winpr_Digest_Init_Allow_FIPS(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, salt, 48)) /* Salt (48 bytes) */
|
||||
goto out;
|
||||
@ -232,11 +235,38 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_md5_16_32_32_Allow_FIPS(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output)
|
||||
{
|
||||
WINPR_DIGEST_CTX* md5 = NULL;
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Init_Allow_FIPS(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, in0, 16))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, in1, 32))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, in2, 32))
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH))
|
||||
goto out;
|
||||
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(md5);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random,
|
||||
const BYTE* server_random, BYTE* output)
|
||||
{
|
||||
/* LicensingEncryptionKey = MD5(Second128Bits(SessionKeyBlob) + ClientRandom + ServerRandom)) */
|
||||
return security_md5_16_32_32(&session_key_blob[16], client_random, server_random, output);
|
||||
/* Allow FIPS use of MD5 here, this is just used for creating the licensing encryption key as described in MS-RDPELE. */
|
||||
/* This is for RDP licensing packets which will already be encrypted under FIPS, so the use of MD5 here is not for
|
||||
/* sensitive data protection. */
|
||||
return security_md5_16_32_32_Allow_FIPS(&session_key_blob[16], client_random, server_random, output);
|
||||
}
|
||||
|
||||
void security_UINT32_le(BYTE* output, UINT32 value)
|
||||
@ -279,7 +309,10 @@ BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length
|
||||
/* MacData = MD5(MacSaltKey + pad2 + SHA1_Digest) */
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
/* Allow FIPS override for use of MD5 here, this is only used for creating the MACData field of the */
|
||||
/* Client Platform Challenge Response packet (from MS-RDPELE section 2.2.2.5). This is for RDP licensing packets */
|
||||
/* which will already be encrypted under FIPS, so the use of MD5 here is not for sensitive data protection. */
|
||||
if (!winpr_Digest_Init_Allow_FIPS(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, mac_salt_key, 16)) /* MacSaltKey */
|
||||
goto out;
|
||||
@ -546,8 +579,11 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
|
||||
}
|
||||
else
|
||||
{
|
||||
status = security_md5_16_32_32(&session_key_blob[16], client_random, server_random, rdp->decrypt_key);
|
||||
status &= security_md5_16_32_32(&session_key_blob[32], client_random, server_random, rdp->encrypt_key);
|
||||
/* Allow FIPS use of MD5 here, this is just used for generation of the SessionKeyBlob as described in MS-RDPELE. */
|
||||
/* This is for RDP licensing packets which will already be encrypted under FIPS, so the use of MD5 here is not */
|
||||
/* for sensitive data protection. */
|
||||
status = security_md5_16_32_32_Allow_FIPS(&session_key_blob[16], client_random, server_random, rdp->decrypt_key);
|
||||
status &= security_md5_16_32_32_Allow_FIPS(&session_key_blob[32], client_random, server_random, rdp->encrypt_key);
|
||||
}
|
||||
|
||||
if (!status)
|
||||
|
@ -333,6 +333,7 @@ rdpSettings* freerdp_settings_new(DWORD flags)
|
||||
settings->ConnectionType = CONNECTION_TYPE_LAN;
|
||||
settings->EncryptionMethods = ENCRYPTION_METHOD_NONE;
|
||||
settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
|
||||
settings->FIPSMode = FALSE;
|
||||
settings->CompressionEnabled = TRUE;
|
||||
settings->LogonNotify = TRUE;
|
||||
|
||||
|
@ -1466,7 +1466,6 @@ rdpTls* tls_new(rdpSettings* settings)
|
||||
if (!tls)
|
||||
return NULL;
|
||||
|
||||
winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
|
||||
tls->settings = settings;
|
||||
|
||||
if (!settings->ServerMode)
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/ssl.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/string.h>
|
||||
#include <winpr/path.h>
|
||||
@ -919,6 +920,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi());
|
||||
winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
|
||||
instance = freerdp_listener_new();
|
||||
|
||||
if (!instance)
|
||||
|
@ -665,10 +665,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
WINPR_API WINPR_DIGEST_CTX* winpr_Digest_New(void);
|
||||
WINPR_API BOOL winpr_Digest_Init_Allow_FIPS(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md);
|
||||
WINPR_API BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md);
|
||||
WINPR_API BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen);
|
||||
WINPR_API BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t ilen);
|
||||
WINPR_API void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx);
|
||||
WINPR_API BOOL winpr_Digest_Allow_FIPS(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen);
|
||||
WINPR_API BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -700,6 +702,7 @@ typedef struct _winpr_rc4_ctx_private_st WINPR_RC4_CTX;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WINPR_API WINPR_RC4_CTX* winpr_RC4_New_Allow_FIPS(const BYTE* key, size_t keylen);
|
||||
WINPR_API WINPR_RC4_CTX* winpr_RC4_New(const BYTE* key, size_t keylen);
|
||||
WINPR_API BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output);
|
||||
WINPR_API void winpr_RC4_Free(WINPR_RC4_CTX* ctx);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define WINPR_SSL_INIT_DEFAULT 0x00
|
||||
#define WINPR_SSL_INIT_ALREADY_INITIALIZED 0x01
|
||||
#define WINPR_SSL_INIT_ENABLE_LOCKING 0x2
|
||||
#define WINPR_SSL_INIT_ENABLE_FIPS 0x4
|
||||
|
||||
#define WINPR_SSL_CLEANUP_GLOBAL 0x01
|
||||
#define WINPR_SSL_CLEANUP_THREAD 0x02
|
||||
|
@ -43,17 +43,36 @@
|
||||
* RC4
|
||||
*/
|
||||
|
||||
WINPR_RC4_CTX* winpr_RC4_New(const BYTE* key, size_t keylen)
|
||||
WINPR_RC4_CTX* winpr_RC4_New_Internal(const BYTE* key, size_t keylen, BOOL override_fips)
|
||||
{
|
||||
WINPR_RC4_CTX* ctx = NULL;
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_CIPHER* evp = NULL;
|
||||
#endif
|
||||
|
||||
if (!key || (keylen == 0))
|
||||
return NULL;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
if (!(ctx = (WINPR_RC4_CTX*) calloc(1, sizeof(RC4_KEY))))
|
||||
if (!(ctx = EVP_CIPHER_CTX_new()))
|
||||
return NULL;
|
||||
RC4_set_key((RC4_KEY*) ctx, keylen, key);
|
||||
|
||||
evp = EVP_rc4();
|
||||
|
||||
if (!evp)
|
||||
return NULL;
|
||||
|
||||
EVP_CIPHER_CTX_init((EVP_CIPHER_CTX *) ctx);
|
||||
EVP_EncryptInit_ex((EVP_CIPHER_CTX *) ctx, evp, NULL, NULL, NULL);
|
||||
|
||||
/* EVP_CIPH_FLAG_NON_FIPS_ALLOW does not exist before openssl 1.0.1 */
|
||||
#if !(OPENSSL_VERSION_NUMBER < 0x10001000L)
|
||||
if (override_fips == TRUE)
|
||||
EVP_CIPHER_CTX_set_flags((EVP_CIPHER_CTX *) ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
|
||||
#endif
|
||||
|
||||
EVP_CIPHER_CTX_set_key_length((EVP_CIPHER_CTX *) ctx, keylen);
|
||||
EVP_EncryptInit_ex((EVP_CIPHER_CTX *) ctx, NULL, NULL, key, NULL);
|
||||
|
||||
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
||||
if (!(ctx = (WINPR_RC4_CTX*) calloc(1, sizeof(mbedtls_arc4_context))))
|
||||
@ -64,10 +83,21 @@ WINPR_RC4_CTX* winpr_RC4_New(const BYTE* key, size_t keylen)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
WINPR_RC4_CTX* winpr_RC4_New_Allow_FIPS(const BYTE* key, size_t keylen)
|
||||
{
|
||||
return winpr_RC4_New_Internal(key, keylen, TRUE);
|
||||
}
|
||||
|
||||
WINPR_RC4_CTX* winpr_RC4_New(const BYTE* key, size_t keylen)
|
||||
{
|
||||
return winpr_RC4_New_Internal(key, keylen, FALSE);
|
||||
}
|
||||
|
||||
BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
RC4((RC4_KEY*) ctx, length, input, output);
|
||||
int outputLength;
|
||||
EVP_CipherUpdate((EVP_CIPHER_CTX *) ctx, output, &outputLength, input, length);
|
||||
return TRUE;
|
||||
|
||||
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
||||
@ -83,9 +113,7 @@ void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
|
||||
return;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
memset(ctx, 0, sizeof(RC4_KEY));
|
||||
free(ctx);
|
||||
|
||||
EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *) ctx);
|
||||
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
||||
mbedtls_arc4_free((mbedtls_arc4_context*) ctx);
|
||||
free(ctx);
|
||||
|
@ -143,29 +143,30 @@ mbedtls_md_type_t winpr_mbedtls_get_md_type(int md)
|
||||
WINPR_HMAC_CTX* winpr_HMAC_New(void)
|
||||
{
|
||||
WINPR_HMAC_CTX* ctx = NULL;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = NULL;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
if (!(hmac = (HMAC_CTX*) calloc(1, sizeof(HMAC_CTX))))
|
||||
return NULL;
|
||||
|
||||
HMAC_CTX_init(hmac);
|
||||
#else
|
||||
|
||||
if (!(hmac = HMAC_CTX_new()))
|
||||
return NULL;
|
||||
|
||||
#endif
|
||||
ctx = (WINPR_HMAC_CTX*) hmac;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* hmac;
|
||||
|
||||
if (!(hmac = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t))))
|
||||
return NULL;
|
||||
|
||||
mbedtls_md_init(hmac);
|
||||
|
||||
ctx = (WINPR_HMAC_CTX*) hmac;
|
||||
#endif
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@ -182,10 +183,11 @@ BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, siz
|
||||
HMAC_Init_ex(hmac, key, keylen, evp, NULL); /* no return value on OpenSSL 0.9.x */
|
||||
return TRUE;
|
||||
#else
|
||||
|
||||
if (HMAC_Init_ex(hmac, key, keylen, evp, NULL) == 1)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* hmac = (mbedtls_md_context_t*) ctx;
|
||||
mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
|
||||
@ -204,8 +206,8 @@ BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, siz
|
||||
|
||||
if (mbedtls_md_hmac_starts(hmac, key, keylen) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -213,21 +215,22 @@ BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*) ctx;
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
HMAC_Update(hmac, input, ilen); /* no return value on OpenSSL 0.9.x */
|
||||
return TRUE;
|
||||
#else
|
||||
|
||||
if (HMAC_Update(hmac, input, ilen) == 1)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
|
||||
if (mbedtls_md_hmac_update(mdctx, input, ilen) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -248,16 +251,18 @@ BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
|
||||
HMAC_Final(hmac, output, NULL); /* no return value on OpenSSL 0.9.x */
|
||||
return TRUE;
|
||||
#else
|
||||
|
||||
if (HMAC_Final(hmac, output, NULL) == 1)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mdctx = (mbedtls_md_context_t*) ctx;
|
||||
|
||||
if (mbedtls_md_hmac_finish(mdctx, output) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -265,6 +270,7 @@ void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*) ctx;
|
||||
|
||||
if (hmac)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
@ -277,27 +283,31 @@ void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx)
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* hmac = (mbedtls_md_context_t*) ctx;
|
||||
|
||||
if (hmac)
|
||||
{
|
||||
mbedtls_md_free(hmac);
|
||||
free(hmac);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen,
|
||||
const BYTE* input, size_t ilen, BYTE* output, size_t olen)
|
||||
const BYTE* input, size_t ilen, BYTE* output, size_t olen)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
WINPR_HMAC_CTX *ctx = winpr_HMAC_New();
|
||||
WINPR_HMAC_CTX* ctx = winpr_HMAC_New();
|
||||
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
if (!winpr_HMAC_Init(ctx, md, key, keylen))
|
||||
goto out;
|
||||
|
||||
if (!winpr_HMAC_Update(ctx, input, ilen))
|
||||
goto out;
|
||||
|
||||
if (!winpr_HMAC_Final(ctx, output, olen))
|
||||
goto out;
|
||||
|
||||
@ -314,7 +324,6 @@ out:
|
||||
WINPR_DIGEST_CTX* winpr_Digest_New(void)
|
||||
{
|
||||
WINPR_DIGEST_CTX* ctx = NULL;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
@ -323,23 +332,22 @@ WINPR_DIGEST_CTX* winpr_Digest_New(void)
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
#endif
|
||||
ctx = (WINPR_DIGEST_CTX*) mdctx;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx;
|
||||
mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t));
|
||||
|
||||
if (mdctx)
|
||||
mbedtls_md_init(mdctx);
|
||||
|
||||
ctx = (WINPR_DIGEST_CTX*) mdctx;
|
||||
#endif
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md, const EVP_MD* evp)
|
||||
{
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx;
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
|
||||
if (!mdctx || !evp)
|
||||
return FALSE;
|
||||
@ -347,7 +355,12 @@ BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
{
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
|
||||
const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
|
||||
@ -365,21 +378,57 @@ BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
|
||||
if (mbedtls_md_starts(mdctx) != 0)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL winpr_Digest_Init_Allow_FIPS(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx;
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
|
||||
/* Only MD5 is supported for FIPS allow override */
|
||||
if (md != WINPR_MD_MD5)
|
||||
return FALSE;
|
||||
|
||||
EVP_MD_CTX_set_flags(mdctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
return winpr_Digest_Init_Internal(ctx, md, evp);
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
|
||||
/* Only MD5 is supported for FIPS allow override */
|
||||
if (md != WINPR_MD_MD5)
|
||||
return FALSE;
|
||||
|
||||
return winpr_Digest_Init_Internal(ctx, md);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
return winpr_Digest_Init_Internal(ctx, md, evp);
|
||||
#else
|
||||
return winpr_Digest_Init_Internal(ctx, md);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx;
|
||||
|
||||
if (EVP_DigestUpdate(mdctx, input, ilen) != 1)
|
||||
return FALSE;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
|
||||
if (mbedtls_md_update(mdctx, input, ilen) != 0)
|
||||
return FALSE;
|
||||
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
@ -388,15 +437,17 @@ BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx;
|
||||
|
||||
if (EVP_DigestFinal_ex(mdctx, output, NULL) == 1)
|
||||
return TRUE;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
|
||||
if (mbedtls_md_finish(mdctx, output) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -404,6 +455,7 @@ void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx;
|
||||
|
||||
if (mdctx)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
@ -415,26 +467,53 @@ void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx)
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
|
||||
if (mdctx)
|
||||
{
|
||||
mbedtls_md_free(mdctx);
|
||||
free(mdctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen)
|
||||
BOOL winpr_Digest_Allow_FIPS(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
WINPR_DIGEST_CTX *ctx = winpr_Digest_New();
|
||||
WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
|
||||
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
if (!winpr_Digest_Init(ctx, md))
|
||||
if (!winpr_Digest_Init_Allow_FIPS(ctx, md))
|
||||
goto out;
|
||||
|
||||
if (!winpr_Digest_Update(ctx, input, ilen))
|
||||
goto out;
|
||||
|
||||
if (!winpr_Digest_Final(ctx, output, olen))
|
||||
goto out;
|
||||
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
|
||||
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
if (!winpr_Digest_Init(ctx, md))
|
||||
goto out;
|
||||
|
||||
if (!winpr_Digest_Update(ctx, input, ilen))
|
||||
goto out;
|
||||
|
||||
if (!winpr_Digest_Final(ctx, output, olen))
|
||||
goto out;
|
||||
|
||||
|
@ -276,6 +276,25 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO
|
||||
|
||||
#endif
|
||||
g_winpr_openssl_initialized_by_winpr = TRUE;
|
||||
|
||||
if (flags & WINPR_SSL_INIT_ENABLE_FIPS)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10001000L)
|
||||
WLog_ERR(TAG, "Openssl fips mode ENable not available on openssl versions less than 1.0.1!");
|
||||
#else
|
||||
WLog_DBG(TAG, "Ensuring openssl fips mode is ENabled");
|
||||
|
||||
if (FIPS_mode() != 1)
|
||||
{
|
||||
if (FIPS_mode_set(1))
|
||||
WLog_INFO(TAG, "Openssl fips mode ENabled!");
|
||||
else
|
||||
WLog_ERR(TAG, "Openssl fips mode ENable failed!");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user