boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length, uint16 securityFlags) { uint8 cmac[8], wmac[8]; if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { uint16 len; uint8 version, pad; uint8 *sig; stream_read_uint16(s, len); /* 0x10 */ stream_read_uint8(s, version); /* 0x1 */ stream_read_uint8(s, pad); sig = s->p; stream_seek(s, 8); /* signature */ length -= 12; if (!security_fips_decrypt(s->p, length, rdp)) { printf("FATAL: cannot decrypt\n"); return false; /* TODO */ } if (!security_fips_check_signature(s->p, length - pad, sig, rdp)) { printf("FATAL: invalid packet signature\n"); return false; /* TODO */ } /* is this what needs adjusting? */ s->size -= pad; return true; } stream_read(s, wmac, sizeof(wmac)); length -= sizeof(wmac); security_decrypt(s->p, length, rdp); if (securityFlags & SEC_SECURE_CHECKSUM) security_salted_mac_signature(rdp, s->p, length, false, cmac); else security_mac_signature(rdp, s->p, length, cmac); if (memcmp(wmac, cmac, sizeof(wmac)) != 0) { printf("WARNING: invalid packet signature\n"); /* * Because Standard RDP Security is totally broken, * and cannot protect against MITM, don't treat signature * verification failure as critical. This at least enables * us to work with broken RDP clients and servers that * generate invalid signatures. */ //return false; } return true; }
static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length) { BYTE* data; UINT32 sec_flags; UINT32 pad = 0; sec_flags = rdp->sec_flags; if (sec_flags != 0) { rdp_write_security_header(s, sec_flags); if (sec_flags & SEC_ENCRYPT) { if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { data = Stream_Pointer(s) + 12; length = length - (data - Stream_Buffer(s)); Stream_Write_UINT16(s, 0x10); /* length */ Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/ /* handle padding */ pad = 8 - (length % 8); if (pad == 8) pad = 0; if (pad) memset(data+length, 0, pad); Stream_Write_UINT8(s, pad); security_hmac_signature(data, length, Stream_Pointer(s), rdp); Stream_Seek(s, 8); security_fips_encrypt(data, length + pad, rdp); } else { data = Stream_Pointer(s) + 8; length = length - (data - Stream_Buffer(s)); if (sec_flags & SEC_SECURE_CHECKSUM) security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s)); else security_mac_signature(rdp, data, length, Stream_Pointer(s)); Stream_Seek(s, 8); security_encrypt(Stream_Pointer(s), length, rdp); } } rdp->sec_flags = 0; } return pad; }
static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) { uint32 ml; uint8* mk; uint8* data; uint32 sec_flags; uint32 pad = 0; sec_flags = rdp->sec_flags; if (sec_flags != 0) { rdp_write_security_header(s, sec_flags); if (sec_flags & SEC_ENCRYPT) { if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { data = s->p + 12; length = length - (data - s->data); stream_write_uint16(s, 0x10); /* length */ stream_write_uint8(s, 0x1); /* TSFIPS_VERSION 1*/ /* handle padding */ pad = 8 - (length % 8); if (pad == 8) pad = 0; if (pad) memset(data+length, 0, pad); stream_write_uint8(s, pad); security_hmac_signature(data, length, s->p, rdp); stream_seek(s, 8); security_fips_encrypt(data, length + pad, rdp); } else { data = s->p + 8; length = length - (data - s->data); mk = rdp->sign_key; ml = rdp->rc4_key_len; security_mac_signature(mk, ml, data, length, s->p); stream_seek(s, 8); security_encrypt(s->p, length, rdp); } } rdp->sec_flags = 0; } return pad; }
static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) { uint8* data; uint32 sec_flags; uint32 pad = 0; sec_flags = rdp->sec_flags; if (sec_flags != 0) { rdp_write_security_header(s, sec_flags); if (sec_flags & SEC_ENCRYPT) { if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { data = s->p + 12; length = length - (data - s->data); stream_write_uint16(s, 0x10); /* length */ stream_write_uint8(s, 0x1); /* TSFIPS_VERSION 1*/ /* handle padding */ pad = (8 - (length % 8)) & 7; memset(data+length, 0, pad); stream_write_uint8(s, pad); security_hmac_signature(data, length, s->p, rdp); stream_seek(s, 8); security_fips_encrypt(data, length + pad, rdp); } else { data = s->p + 8; length = length - (data - s->data); if (sec_flags & SEC_SECURE_CHECKSUM) security_salted_mac_signature(rdp, data, length, true, s->p); else security_mac_signature(rdp, data, length, s->p); stream_seek(s, 8); security_encrypt(s->p, length, rdp); } } rdp->sec_flags = 0; } return pad; }
boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length) { uint8 cmac[8], wmac[8]; uint32 ml; uint8* mk; if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { uint16 len; uint8 version, pad; uint8 *sig; stream_read_uint16(s, len); /* 0x10 */ stream_read_uint8(s, version); /* 0x1 */ stream_read_uint8(s, pad); sig = s->p; stream_seek(s, 8); /* signature */ length -= 12; if (!security_fips_decrypt(s->p, length, rdp)) { printf("FATAL: cannot decrypt\n"); return false; /* TODO */ } if (!security_fips_check_signature(s->p, length - pad, sig, rdp)) { printf("FATAL: invalid packet signature\n"); return false; /* TODO */ } /* is this what needs adjusting? */ s->size -= pad; return true; } stream_read(s, wmac, sizeof(wmac)); length -= sizeof(wmac); security_decrypt(s->p, length, rdp); mk = rdp->sign_key; ml = rdp->rc4_key_len; security_mac_signature(mk, ml, s->p, length, cmac); if (memcmp(wmac, cmac, sizeof(wmac)) != 0) { printf("FATAL: invalid packet signature\n"); return false; } return true; }
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags) { BYTE cmac[8]; BYTE wmac[8]; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { UINT16 len; BYTE version, pad; BYTE* sig; if (Stream_GetRemainingLength(s) < 12) return FALSE; Stream_Read_UINT16(s, len); /* 0x10 */ Stream_Read_UINT8(s, version); /* 0x1 */ Stream_Read_UINT8(s, pad); sig = Stream_Pointer(s); Stream_Seek(s, 8); /* signature */ length -= 12; if (!security_fips_decrypt(Stream_Pointer(s), length, rdp)) { DEBUG_WARN( "FATAL: cannot decrypt\n"); return FALSE; /* TODO */ } if (!security_fips_check_signature(Stream_Pointer(s), length - pad, sig, rdp)) { DEBUG_WARN( "FATAL: invalid packet signature\n"); return FALSE; /* TODO */ } Stream_Length(s) -= pad; return TRUE; } if (Stream_GetRemainingLength(s) < 8) return FALSE; Stream_Read(s, wmac, sizeof(wmac)); length -= sizeof(wmac); if (!security_decrypt(Stream_Pointer(s), length, rdp)) return FALSE; if (securityFlags & SEC_SECURE_CHECKSUM) security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac); else security_mac_signature(rdp, Stream_Pointer(s), length, cmac); if (memcmp(wmac, cmac, sizeof(wmac)) != 0) { DEBUG_WARN( "WARNING: invalid packet signature\n"); /* * Because Standard RDP Security is totally broken, * and cannot protect against MITM, don't treat signature * verification failure as critical. This at least enables * us to work with broken RDP clients and servers that * generate invalid signatures. */ //return FALSE; } return TRUE; }