diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c
index d6e46e8..1a16b03 100644
--- a/libfreerdp/core/capabilities.c
+++ b/libfreerdp/core/capabilities.c
@@ -3657,12 +3657,12 @@ BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId)
 
 	if (rdp->settings->UseRdpSecurityLayer)
 	{
-		if (!rdp_read_security_header(s, &securityFlags))
+		if (!rdp_read_security_header(s, &securityFlags, &length))
 			return FALSE;
 
 		if (securityFlags & SEC_ENCRYPT)
 		{
-			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
+			if (!rdp_decrypt(rdp, s, length, securityFlags))
 			{
 				WLog_ERR(TAG,  "rdp_decrypt failed");
 				return FALSE;
diff --git a/libfreerdp/core/certificate.c b/libfreerdp/core/certificate.c
index 9ce68f3..d750685 100644
--- a/libfreerdp/core/certificate.c
+++ b/libfreerdp/core/certificate.c
@@ -361,7 +361,6 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w
 	UINT32 keylen;
 	UINT32 bitlen;
 	UINT32 datalen;
-	UINT32 modlen;
 
 	if (Stream_GetRemainingLength(s) < 20)
 		return FALSE;
@@ -378,12 +377,11 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w
 	Stream_Read_UINT32(s, bitlen);
 	Stream_Read_UINT32(s, datalen);
 	Stream_Read(s, certificate->cert_info.exponent, 4);
-	modlen = keylen - 8;
 
-	if (Stream_GetRemainingLength(s) < modlen + 8)	// count padding
+	if ((keylen <= 8) || (Stream_GetRemainingLength(s) < keylen))
 		return FALSE;
 
-	certificate->cert_info.ModulusLength = modlen;
+	certificate->cert_info.ModulusLength = keylen - 8;
 	certificate->cert_info.Modulus = malloc(certificate->cert_info.ModulusLength);
 
 	if (!certificate->cert_info.Modulus)
@@ -547,7 +545,7 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate
 
 BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s)
 {
-	int i;
+	UINT32 i;
 	BOOL ret;
 	UINT32 certLength;
 	UINT32 numCertBlobs;
@@ -563,7 +561,7 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
 	if (!certificate->x509_cert_chain)
 		return FALSE;
 
-	for (i = 0; i < (int) numCertBlobs; i++)
+	for (i = 0; i < numCertBlobs; i++)
 	{
 		if (Stream_GetRemainingLength(s) < 4)
 			return FALSE;
@@ -622,7 +620,7 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
  * @param length certificate length
  */
 
-BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length)
+BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, size_t length)
 {
 	BOOL ret;
 	wStream* s;
diff --git a/libfreerdp/core/certificate.h b/libfreerdp/core/certificate.h
index a48701b..3b0b4a2 100644
--- a/libfreerdp/core/certificate.h
+++ b/libfreerdp/core/certificate.h
@@ -51,7 +51,7 @@ void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain);
 
 BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate, wStream* s);
 BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s);
-BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length);
+BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, size_t length);
 
 rdpCertificate* certificate_clone(rdpCertificate* certificate);
 
diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c
index f66e181..e03ffb9 100644
--- a/libfreerdp/core/connection.c
+++ b/libfreerdp/core/connection.c
@@ -565,7 +565,7 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
 		return FALSE;
 	}
 
-	if (!rdp_read_security_header(s, &sec_flags))
+	if (!rdp_read_security_header(s, &sec_flags, NULL))
 	{
 		WLog_ERR(TAG, "invalid security header");
 		return FALSE;
@@ -787,7 +787,7 @@ BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s)
 			{
 				UINT16 securityFlags;
 
-				if (!rdp_read_security_header(s, &securityFlags))
+ 				if (!rdp_read_security_header(s, &securityFlags, &length))
 					return FALSE;
 
 				if (rdp_recv_message_channel_pdu(rdp, s, securityFlags) == 0)
diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c
index e19e019..019b48b 100644
--- a/libfreerdp/core/gcc.c
+++ b/libfreerdp/core/gcc.c
@@ -33,6 +33,7 @@
 
 #define TAG FREERDP_TAG("core.gcc")
 
+
 /**
  * T.124 GCC is defined in:
  *
@@ -1113,34 +1114,49 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs)
 	Stream_Read_UINT32(s, settings->ServerRandomLength); /* serverRandomLen */
 	Stream_Read_UINT32(s, settings->ServerCertificateLength); /* serverCertLen */
 
-	if (Stream_GetRemainingLength(s) < settings->ServerRandomLength + settings->ServerCertificateLength)
+	if ((settings->ServerRandomLength == 0) || (settings->ServerCertificateLength == 0))
 		return FALSE;
 
-	if ((settings->ServerRandomLength <= 0) || (settings->ServerCertificateLength <= 0))
+ 	if (Stream_GetRemainingLength(s) < settings->ServerRandomLength)
 		return FALSE;
 
 	/* serverRandom */
 	settings->ServerRandom = (BYTE*) malloc(settings->ServerRandomLength);
 	if (!settings->ServerRandom)
-		return FALSE;
+ 		goto fail;
 	Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength);
+ 
+ 	if (Stream_GetRemainingLength(s) < settings->ServerCertificateLength)
+ 		goto fail;
+ 
 
 
 	/* serverCertificate */
 	settings->ServerCertificate = (BYTE*) malloc(settings->ServerCertificateLength);
 	if (!settings->ServerCertificate)
-		return FALSE;
+ 		goto fail;
 	Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength);
 
 	certificate_free(settings->RdpServerCertificate);
 	settings->RdpServerCertificate = certificate_new();
 	if (!settings->RdpServerCertificate)
-		return FALSE;
+ 		goto fail;
 
 	data = settings->ServerCertificate;
 	length = settings->ServerCertificateLength;
 
-	return certificate_read_server_certificate(settings->RdpServerCertificate, data, length);
+ 	if (!certificate_read_server_certificate(settings->RdpServerCertificate, data,
+ 	        length))
+ 		goto fail;
+ 
+ 	return TRUE;
+ 
+ fail:
+ 	free (settings->ServerRandom);
+ 	free (settings->ServerCertificate);
+ 	settings->ServerRandom = NULL;
+ 	settings->ServerCertificate = NULL;
+ 	return FALSE;
 }
 
 static const BYTE initial_signature[] =
diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c
index 4f6c703..ab1161a 100644
--- a/libfreerdp/core/info.c
+++ b/libfreerdp/core/info.c
@@ -759,7 +759,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
 	if (!rdp_read_header(rdp, s, &length, &channelId))
 		return FALSE;
 
-	if (!rdp_read_security_header(s, &securityFlags))
+	if (!rdp_read_security_header(s, &securityFlags, &length))
 		return FALSE;
 
 	if ((securityFlags & SEC_INFO_PKT) == 0)
@@ -775,7 +775,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
 
 		if (securityFlags & SEC_ENCRYPT)
 		{
-			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
+			if (!rdp_decrypt(rdp, s, length, securityFlags))
 			{
 				WLog_ERR(TAG, "rdp_decrypt failed");
 				return FALSE;
diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c
index 055a2dc..83328c1 100644
--- a/libfreerdp/core/license.c
+++ b/libfreerdp/core/license.c
@@ -36,6 +36,40 @@
 /* #define LICENSE_NULL_CLIENT_RANDOM		1 */
 /* #define LICENSE_NULL_PREMASTER_SECRET		1 */
 
+static wStream* license_send_stream_init(rdpLicense* license);
+
+static void license_generate_randoms(rdpLicense* license);
+static BOOL license_generate_keys(rdpLicense* license);
+static BOOL license_generate_hwid(rdpLicense* license);
+static BOOL license_encrypt_premaster_secret(rdpLicense* license);
+static BOOL license_decrypt_platform_challenge(rdpLicense* license);
+
+static LICENSE_PRODUCT_INFO* license_new_product_info(void);
+static void license_free_product_info(LICENSE_PRODUCT_INFO* productInfo);
+static BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo);
+
+static LICENSE_BLOB* license_new_binary_blob(UINT16 type);
+static void license_free_binary_blob(LICENSE_BLOB* blob);
+static BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob);
+static BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob);
+
+static SCOPE_LIST* license_new_scope_list(void);
+static void license_free_scope_list(SCOPE_LIST* scopeList);
+static BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList);
+
+static BOOL license_read_license_request_packet(rdpLicense* license, wStream* s);
+static BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s);
+static void license_read_new_license_packet(rdpLicense* license, wStream* s);
+static void license_read_upgrade_license_packet(rdpLicense* license, wStream* s);
+static BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s);
+
+static BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s);
+static BOOL license_send_new_license_request_packet(rdpLicense* license);
+
+static BOOL license_write_platform_challenge_response_packet(
+    rdpLicense* license, wStream* s, BYTE* mac_data);
+static BOOL license_send_platform_challenge_response_packet(rdpLicense* license);
+
 #ifdef WITH_DEBUG_LICENSE
 
 static const char* const LICENSE_MESSAGE_STRINGS[] =
@@ -82,7 +116,7 @@ static const char* const  state_transitions[] =
 	"ST_RESEND_LAST_MESSAGE"
 };
 
-void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo)
+static void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo)
 {
 	char* CompanyName = NULL;
 	char* ProductId = NULL;
@@ -98,7 +132,7 @@ void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo)
 	free(ProductId);
 }
 
-void license_print_scope_list(SCOPE_LIST* scopeList)
+static void license_print_scope_list(SCOPE_LIST* scopeList)
 {
 	int index;
 	LICENSE_BLOB* scope;
@@ -251,12 +285,12 @@ int license_recv(rdpLicense* license, wStream* s)
 		return -1;
 	}
 
-	if (!rdp_read_security_header(s, &securityFlags))
+	if (!rdp_read_security_header(s, &securityFlags, &length))
 		return -1;
 
 	if (securityFlags & SEC_ENCRYPT)
 	{
-		if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags))
+		if (!rdp_decrypt(license->rdp, s, length, securityFlags))
 		{
 			WLog_ERR(TAG, "rdp_decrypt failed");
 			return -1;
@@ -468,7 +502,12 @@ BOOL license_decrypt_platform_challenge(rdpLicense* license)
 
 	if ((rc4 = winpr_RC4_New(license->LicensingEncryptionKey,
 				 LICENSING_ENCRYPTION_KEY_LENGTH)) == NULL)
+	{
+		free(license->PlatformChallenge->data);
+		license->PlatformChallenge->data = NULL;
+		license->PlatformChallenge->length = 0;
 		return FALSE;
+	}
 	rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
 			   license->EncryptedPlatformChallenge->data,
 			   license->PlatformChallenge->data);
@@ -492,15 +531,27 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
 	Stream_Read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */
 	Stream_Read_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */
 
-	if (Stream_GetRemainingLength(s) < productInfo->cbCompanyName + 4)
+	/* Name must be >0, but there is no upper limit defined, use UINT32_MAX */
+	if ((productInfo->cbCompanyName < 2) || (productInfo->cbCompanyName % 2 != 0))
+		return FALSE;
+
+	if (Stream_GetRemainingLength(s) < productInfo->cbCompanyName)
 		return FALSE;
 
+	productInfo->pbProductId = NULL;
 	productInfo->pbCompanyName = (BYTE*) malloc(productInfo->cbCompanyName);
 	if (!productInfo->pbCompanyName)
 		return FALSE;
 	Stream_Read(s, productInfo->pbCompanyName, productInfo->cbCompanyName);
+
+	if (Stream_GetRemainingLength(s) < 4)
+		goto out_fail;
+
 	Stream_Read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */
 
+	if ((productInfo->cbProductId < 2) || (productInfo->cbProductId % 2 != 0))
+		goto out_fail;
+
 	if (Stream_GetRemainingLength(s) < productInfo->cbProductId)
 		goto out_fail;
 
@@ -512,7 +563,9 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
 
 out_fail:
 	free(productInfo->pbCompanyName);
+	free(productInfo->pbProductId);
 	productInfo->pbCompanyName = NULL;
+	productInfo->pbProductId = NULL;
 	return FALSE;
 }
 
@@ -811,7 +864,9 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
 	Stream_Read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */
 	/* EncryptedPlatformChallenge */
 	license->EncryptedPlatformChallenge->type = BB_ANY_BLOB;
-	license_read_binary_blob(s, license->EncryptedPlatformChallenge);
+	if (!license_read_binary_blob(s, license->EncryptedPlatformChallenge))
+		return FALSE;
+
 	license->EncryptedPlatformChallenge->type = BB_ENCRYPTED_DATA_BLOB;
 
 	if (Stream_GetRemainingLength(s) < 16)
diff --git a/libfreerdp/core/license.h b/libfreerdp/core/license.h
index aba0a02..ef128ea 100644
--- a/libfreerdp/core/license.h
+++ b/libfreerdp/core/license.h
@@ -17,8 +17,8 @@
  * limitations under the License.
  */
 
-#ifndef __LICENSE_H
-#define __LICENSE_H
+#ifndef FREERDP_LICENSE_H
+#define FREERDP_LICENSE_H
 
 typedef struct rdp_license rdpLicense;
 
@@ -202,38 +202,6 @@ struct rdp_license
 
 int license_recv(rdpLicense* license, wStream* s);
 BOOL license_send(rdpLicense* license, wStream* s, BYTE type);
-wStream* license_send_stream_init(rdpLicense* license);
-
-void license_generate_randoms(rdpLicense* license);
-BOOL license_generate_keys(rdpLicense* license);
-BOOL license_generate_hwid(rdpLicense* license);
-BOOL license_encrypt_premaster_secret(rdpLicense* license);
-BOOL license_decrypt_platform_challenge(rdpLicense* license);
-
-LICENSE_PRODUCT_INFO* license_new_product_info(void);
-void license_free_product_info(LICENSE_PRODUCT_INFO* productInfo);
-BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo);
-
-LICENSE_BLOB* license_new_binary_blob(UINT16 type);
-void license_free_binary_blob(LICENSE_BLOB* blob);
-BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob);
-BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob);
-
-SCOPE_LIST* license_new_scope_list(void);
-void license_free_scope_list(SCOPE_LIST* scopeList);
-BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList);
-
-BOOL license_read_license_request_packet(rdpLicense* license, wStream* s);
-BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s);
-void license_read_new_license_packet(rdpLicense* license, wStream* s);
-void license_read_upgrade_license_packet(rdpLicense* license, wStream* s);
-BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s);
-
-BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s);
-BOOL license_send_new_license_request_packet(rdpLicense* license);
-
-BOOL license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* mac_data);
-BOOL license_send_platform_challenge_response_packet(rdpLicense* license);
 
 BOOL license_send_valid_client_error_packet(rdpLicense* license);
 
diff --git a/libfreerdp/core/mcs.c b/libfreerdp/core/mcs.c
index 27c9126..e3f2a71 100644
--- a/libfreerdp/core/mcs.c
+++ b/libfreerdp/core/mcs.c
@@ -223,7 +223,8 @@ BOOL mcs_read_domain_mcspdu_header(wStream* s, enum DomainMCSPDU* domainMCSPDU,
 	BYTE choice;
 	enum DomainMCSPDU MCSPDU;
 
-	*length = tpkt_read_header(s);
+	if (!tpkt_read_header(s, length))
+		return FALSE;
 
 	if (!tpdu_read_data(s, &li))
 		return FALSE;
@@ -480,8 +481,10 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s)
 	UINT16 li;
 	int length;
 	BOOL upwardFlag;
+ 	UINT16 tlength;
 
-	tpkt_read_header(s);
+ 	if (!tpkt_read_header(s, &tlength))
+ 		return FALSE;
 
 	if (!tpdu_read_data(s, &li))
 		return FALSE;
@@ -697,11 +700,13 @@ out:
 BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s)
 {
 	int length;
+	UINT16 tlength;
 	BYTE result;
 	UINT16 li;
 	UINT32 calledConnectId;
 
-	tpkt_read_header(s);
+	if (!tpkt_read_header(s, &tlength))
+		return FALSE;
 
 	if (!tpdu_read_data(s, &li))
 		return FALSE;
diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c
index 136b305..3cbad6a 100644
--- a/libfreerdp/core/nego.c
+++ b/libfreerdp/core/nego.c
@@ -575,7 +575,8 @@ int nego_recv(rdpTransport* transport, wStream* s, void* extra)
 	UINT16 length;
 	rdpNego* nego = (rdpNego*) extra;
 
-	length = tpkt_read_header(s);
+	if (!tpkt_read_header(s, &length))
+		return -1;
 
 	if (length == 0)
 		return -1;
@@ -739,8 +740,10 @@ BOOL nego_read_request(rdpNego* nego, wStream* s)
 {
 	BYTE li;
 	BYTE type;
+	UINT16 length;
 
-	tpkt_read_header(s);
+	if (!tpkt_read_header(s, &length))
+		return FALSE;
 
 	if (!tpdu_read_connection_request(s, &li))
 		return FALSE;
diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c
index 8318c4d..7263feb 100644
--- a/libfreerdp/core/peer.c
+++ b/libfreerdp/core/peer.c
@@ -369,12 +369,12 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
  
 	if (rdp->settings->UseRdpSecurityLayer)
 	{
-		if (!rdp_read_security_header(s, &securityFlags))
+		if (!rdp_read_security_header(s, &securityFlags, &length))
 			return -1;
 
 		if (securityFlags & SEC_ENCRYPT)
 		{
-			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
+			if (!rdp_decrypt(rdp, s, length, securityFlags))
 			{
 				WLog_ERR(TAG, "rdp_decrypt failed");
 				return -1;
@@ -414,7 +414,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
 	else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId)
 	{
 		if (!rdp->settings->UseRdpSecurityLayer)
-			if (!rdp_read_security_header(s, &securityFlags))
+			if (!rdp_read_security_header(s, &securityFlags, NULL))
 				return -1;
 
 		return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c
index e7c5bd2..2d34a34 100644
--- a/libfreerdp/core/rdp.c
+++ b/libfreerdp/core/rdp.c
@@ -79,13 +79,17 @@ const char* DATA_PDU_TYPE_STRINGS[80] =
  * @param flags security flags
  */
 
-BOOL rdp_read_security_header(wStream* s, UINT16* flags)
+BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length)
 {
 	/* Basic Security Header */
-	if (Stream_GetRemainingLength(s) < 4)
+	if ((Stream_GetRemainingLength(s) < 4) || (length && (*length < 4)))
 		return FALSE;
 	Stream_Read_UINT16(s, *flags); /* flags */
 	Stream_Seek(s, 2); /* flagsHi (unused) */
+
+	if (length)
+		*length -= 4;
+
 	return TRUE;
 }
 
@@ -301,7 +305,8 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
 
 	MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication;
 
-	*length = tpkt_read_header(s);
+	if (!tpkt_read_header(s, length))
+		return FALSE;
 
 	if (!tpdu_read_header(s, &code, &li))
 		return FALSE;
@@ -330,7 +335,10 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
 
 	MCSPDU = domainMCSPDU;
 
-	if ((size_t) (*length - 8) > Stream_GetRemainingLength(s))
+	if (*length < 8)
+		return FALSE;
+
+	if ((*length - 8) > Stream_GetRemainingLength(s))
 		return FALSE;
 
 	if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum)
@@ -376,8 +384,12 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
 	if (Stream_GetRemainingLength(s) < 5)
 		return FALSE;
 
-	per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
-	per_read_integer16(s, channelId, 0); /* channelId */
+	if (!per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID)) /* initiator (UserId) */
+		return FALSE;
+
+	if (!per_read_integer16(s, channelId, 0)) /* channelId */
+		return FALSE;
+
 	Stream_Read_UINT8(s, byte); /* dataPriority + Segmentation (0x70) */
 
 	if (!per_read_length(s, length)) /* userData (OCTET_STRING) */
@@ -1024,17 +1036,21 @@ void rdp_read_flow_control_pdu(wStream* s, UINT16* type)
  * @param length int
  */
 
-BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
+BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags)
 {
 	BYTE cmac[8];
 	BYTE wmac[8];
 	BOOL status;
 
+	if (!rdp || !s || (length < 0))
+		return FALSE;
+
 	if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
 	{
 		UINT16 len;
 		BYTE version, pad;
 		BYTE* sig;
+		INT64 padLength;
 
 		if (Stream_GetRemainingLength(s) < 12)
 			return FALSE;
@@ -1047,6 +1063,9 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
 		Stream_Seek(s, 8);	/* signature */
 
 		length -= 12;
+		padLength = length - pad;
+		if ((length <= 0) || (padLength <= 0))
+			return FALSE;
 
 		if (!security_fips_decrypt(Stream_Pointer(s), length, rdp))
 		{
@@ -1064,11 +1083,13 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
 		return TRUE;
 	}
 
-	if (Stream_GetRemainingLength(s) < 8)
+	if (Stream_GetRemainingLength(s) < sizeof(wmac))
 		return FALSE;
 
 	Stream_Read(s, wmac, sizeof(wmac));
 	length -= sizeof(wmac);
+	if (length <= 0)
+		return FALSE;
 
 	if (!security_decrypt(Stream_Pointer(s), length, rdp))
 		return FALSE;
@@ -1129,7 +1150,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
 
 	if (rdp->settings->UseRdpSecurityLayer)
 	{
-		if (!rdp_read_security_header(s, &securityFlags))
+		if (!rdp_read_security_header(s, &securityFlags, &length))
 		{
 			WLog_ERR(TAG, "rdp_recv_tpkt_pdu: rdp_read_security_header() fail");
 			return -1;
@@ -1137,7 +1158,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
 
 		if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
 		{
-			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
+			if (!rdp_decrypt(rdp, s, length, securityFlags))
 			{
 				WLog_ERR(TAG, "rdp_decrypt failed");
 				return -1;
@@ -1210,7 +1231,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
 	else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId)
 	{
 		if (!rdp->settings->UseRdpSecurityLayer)
-			if (!rdp_read_security_header(s, &securityFlags))
+			if (!rdp_read_security_header(s, &securityFlags, NULL))
 				return -1;
 
 		return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h
index ef8e0dc..5c6ce35 100644
--- a/libfreerdp/core/rdp.h
+++ b/libfreerdp/core/rdp.h
@@ -178,7 +178,7 @@ struct rdp_rdp
 	rdpSettings* settingsCopy;
 };
 
-BOOL rdp_read_security_header(wStream* s, UINT16* flags);
+BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length);
 void rdp_write_security_header(wStream* s, UINT16 flags);
 
 BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UINT16* channel_id);
@@ -232,7 +232,7 @@ void rdp_free(rdpRdp* rdp);
 #define DEBUG_RDP(fmt, ...) do { } while (0)
 #endif
 
-BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags);
+BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags);
 
 BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo);
 BOOL rdp_send_error_info(rdpRdp* rdp);
diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c
index e415786..e6121d4 100644
--- a/libfreerdp/core/security.c
+++ b/libfreerdp/core/security.c
@@ -580,7 +580,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
 	return TRUE;
 }
 
-BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
+BOOL security_encrypt(BYTE* data, size_t length, rdpRdp* rdp)
 {
 	if (rdp->encrypt_use_count >= 4096)
 	{
@@ -602,7 +602,7 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
 	return TRUE;
 }
 
-BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
+BOOL security_decrypt(BYTE* data, size_t length, rdpRdp* rdp)
 {
 	if (rdp->rc4_decrypt_key == NULL)
 		return FALSE;
@@ -626,7 +626,7 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
 	return TRUE;
 }
 
-BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp)
+BOOL security_hmac_signature(const BYTE* data, size_t length, BYTE* output, rdpRdp* rdp)
 {
 	BYTE buf[WINPR_SHA1_DIGEST_LENGTH];
 	BYTE use_count_le[4];
@@ -647,7 +647,7 @@ BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp*
 	return TRUE;
 }
 
-BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
+BOOL security_fips_encrypt(BYTE* data, size_t length, rdpRdp* rdp)
 {
 	size_t olen;
 
@@ -657,7 +657,7 @@ BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
 	return TRUE;
 }
 
-BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
+BOOL security_fips_decrypt(BYTE* data, size_t length, rdpRdp* rdp)
 {
 	size_t olen;
 
@@ -666,7 +666,7 @@ BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
 	return TRUE;
 }
 
-BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp)
+BOOL security_fips_check_signature(const BYTE* data, size_t length, const BYTE* sig, rdpRdp* rdp)
 {
 	BYTE buf[WINPR_SHA1_DIGEST_LENGTH];
 	BYTE use_count_le[4];
diff --git a/libfreerdp/core/security.h b/libfreerdp/core/security.h
index fc03a3e..14f4664 100644
--- a/libfreerdp/core/security.h
+++ b/libfreerdp/core/security.h
@@ -17,8 +17,8 @@
  * limitations under the License.
  */
 
-#ifndef __SECURITY_H
-#define __SECURITY_H
+#ifndef FREERDP_SECURITY_H
+#define FREERDP_SECURITY_H
 
 #include "rdp.h"
 #include <freerdp/crypto/crypto.h>
@@ -37,12 +37,12 @@ BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
 BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BOOL encryption, BYTE* output);
 BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp);
 
-BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp);
-BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp);
+BOOL security_encrypt(BYTE* data, size_t length, rdpRdp* rdp);
+BOOL security_decrypt(BYTE* data, size_t length, rdpRdp* rdp);
 
-BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp);
-BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp);
-BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp);
-BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp);
+BOOL security_hmac_signature(const BYTE* data, size_t length, BYTE* output, rdpRdp* rdp);
+BOOL security_fips_encrypt(BYTE* data, size_t length, rdpRdp* rdp);
+BOOL security_fips_decrypt(BYTE* data, size_t length, rdpRdp* rdp);
+BOOL security_fips_check_signature(const BYTE* data, size_t length, const BYTE* sig, rdpRdp* rdp);
 
 #endif /* __SECURITY_H */
diff --git a/libfreerdp/core/tpkt.c b/libfreerdp/core/tpkt.c
index 5689d62..eed79d7 100644
--- a/libfreerdp/core/tpkt.c
+++ b/libfreerdp/core/tpkt.c
@@ -78,28 +78,39 @@ BOOL tpkt_verify_header(wStream* s)
 /**
  * Read a TPKT header.\n
  * @param s
- * @return length
+ * @param length
+ * @return success
  */
 
-UINT16 tpkt_read_header(wStream* s)
+BOOL tpkt_read_header(wStream* s, UINT16* length)
 {
 	BYTE version;
-	UINT16 length;
+
+	if (Stream_GetRemainingLength(s) < 1)
+		return FALSE;
 
 	Stream_Peek_UINT8(s, version);
 
 	if (version == 3)
 	{
+		UINT16 len;
+		if (Stream_GetRemainingLength(s) < 4)
+			return FALSE;
+
 		Stream_Seek(s, 2);
-		Stream_Read_UINT16_BE(s, length);
+		Stream_Read_UINT16_BE(s, len);
+		if (len < 4)
+			return FALSE;
+
+		*length = len;
 	}
 	else
 	{
 		/* not a TPKT header */
-		length = 0;
+		*length = 0;
 	}
 
-	return length;
+	return TRUE;
 }
 
 /**
diff --git a/libfreerdp/core/tpkt.h b/libfreerdp/core/tpkt.h
index af984c1..9b51749 100644
--- a/libfreerdp/core/tpkt.h
+++ b/libfreerdp/core/tpkt.h
@@ -28,7 +28,7 @@
 #define TPKT_HEADER_LENGTH	4
 
 BOOL tpkt_verify_header(wStream* s);
-UINT16 tpkt_read_header(wStream* s);
+BOOL tpkt_read_header(wStream* s, UINT16* length);
 void tpkt_write_header(wStream* s, UINT16 length);
 
 #endif /* __TPKT_H */
