Răsfoiți Sursa

Merge pull request #294 from moatazelmasry2/add-sha2

Add HMAC SHA2-256, HMAC SHA2-384, HMAC SHA2-512 support
Daiyuu Nobori 8 ani în urmă
părinte
comite
c32310205d

+ 61 - 8
src/Cedar/IPsec_IkePacket.c

@@ -2558,6 +2558,8 @@ IKE_ENGINE *NewIkeEngine()
 {
 	IKE_ENGINE *e = ZeroMalloc(sizeof(IKE_ENGINE));
 	IKE_CRYPTO *des, *des3, *aes;
+	IKE_HASH *sha1, *md5, *sha2_256, *sha2_384, *sha2_512;
+	IKE_DH *dh1, *dh2, *dh5;
 	IKE_HASH *sha1, *md5;
 	IKE_DH *dh1, *dh2, *dh5, *dh2048, *dh3072, *dh4096;
 	UINT des_key_sizes[] =
@@ -2594,6 +2596,14 @@ IKE_ENGINE *NewIkeEngine()
 	// SHA-1
 	sha1 = NewIkeHash(e, IKE_HASH_SHA1_ID, IKE_HASH_SHA1_STRING, 20);
 
+	// SHA-2
+	// sha2-256
+	sha2_256 = NewIkeHash(e, IKE_HASH_SHA2_256_ID, IKE_HASH_SHA2_256_STRING, 32);
+	// sha2-384
+	sha2_384 = NewIkeHash(e, IKE_HASH_SHA2_384_ID, IKE_HASH_SHA2_384_STRING, 48);
+	// sha2-512
+	sha2_512 = NewIkeHash(e, IKE_HASH_SHA2_512_ID, IKE_HASH_SHA2_512_STRING, 64);
+
 	// MD5
 	md5 = NewIkeHash(e, IKE_HASH_MD5_ID, IKE_HASH_MD5_STRING, 16);
 
@@ -2611,6 +2621,10 @@ IKE_ENGINE *NewIkeEngine()
 	e->IkeCryptos[IKE_P1_CRYPTO_AES_CBC] = aes;
 	e->IkeHashes[IKE_P1_HASH_MD5] = md5;
 	e->IkeHashes[IKE_P1_HASH_SHA1] = sha1;
+	e->IkeHashes[IKE_P1_HASH_SHA2_256] = sha2_256;
+	e->IkeHashes[IKE_P1_HASH_SHA2_384] = sha2_384;
+	e->IkeHashes[IKE_P1_HASH_SHA2_512] = sha2_512;
+
 
 	// Definition of ESP algorithm
 	e->EspCryptos[IKE_TRANSFORM_ID_P2_ESP_DES] = des;
@@ -2931,6 +2945,15 @@ void IkeHash(IKE_HASH *h, void *dst, void *src, UINT size)
 		// SHA-1
 		Sha1(dst, src, size);
 		break;
+	case IKE_HASH_SHA2_256_ID:
+		Sha2_256(dst, src, size);
+		break;
+	case IKE_HASH_SHA2_384_ID:
+		Sha2_384(dst, src, size);
+		break;
+	case IKE_HASH_SHA2_512_ID:
+		Sha2_512(dst, src, size);
+		break;
 
 	default:
 		// Unknown
@@ -2942,11 +2965,26 @@ void IkeHash(IKE_HASH *h, void *dst, void *src, UINT size)
 // Calculation of HMAC
 void IkeHMac(IKE_HASH *h, void *dst, void *key, UINT key_size, void *data, UINT data_size)
 {
-	UCHAR k[HMAC_BLOCK_SIZE];
+	UINT hmac_block_size;
+	if (h == NULL) {
+		return;
+	}
+	switch (h->HashId) {
+		case IKE_HASH_SHA1_ID:
+		case IKE_HASH_SHA2_256_ID:
+			hmac_block_size = HMAC_BLOCK_SIZE;
+			break;
+		case IKE_HASH_SHA2_384_ID:
+		case IKE_HASH_SHA2_512_ID:
+			hmac_block_size = HMAC_BLOCK_SIZE_1024;
+			break;
+		default: return;
+	}
+	UCHAR k[hmac_block_size];
 	UCHAR *data1;
 	UCHAR hash1[IKE_MAX_HASH_SIZE];
 	UINT data1_size;
-	UCHAR data2[IKE_MAX_HASH_SIZE + HMAC_BLOCK_SIZE];
+	UCHAR data2[IKE_MAX_HASH_SIZE + hmac_block_size];
 	UINT data2_size;
 	UCHAR tmp1600[1600];
 	bool no_free = false;
@@ -2963,6 +3001,21 @@ void IkeHMac(IKE_HASH *h, void *dst, void *key, UINT key_size, void *data, UINT
 		HMacSha1(dst, key, key_size, data, data_size);
 		return;
 	}
+	else if (h->HashId == IKE_HASH_SHA2_256_ID)
+	{
+		HMacSha2_256(dst, key, key_size, data, data_size);
+		return;
+	}
+	else if (h->HashId == IKE_HASH_SHA2_384_ID)
+	{
+		HMacSha2_384(dst, key, key_size, data, data_size);
+		return;
+	}
+	else if (h->HashId == IKE_HASH_SHA2_512_ID)
+	{
+		HMacSha2_512(dst, key, key_size, data, data_size);
+		return;
+	}
 	else if (h->HashId == IKE_HASH_MD5_ID)
 	{
 		// Use the special function (fast) in the case of MD5
@@ -2972,7 +3025,7 @@ void IkeHMac(IKE_HASH *h, void *dst, void *key, UINT key_size, void *data, UINT
 
 	// Creating a K
 	Zero(k, sizeof(k));
-	if (key_size <= HMAC_BLOCK_SIZE)
+	if (key_size <= hmac_block_size)
 	{
 		Copy(k, key, key_size);
 	}
@@ -2982,7 +3035,7 @@ void IkeHMac(IKE_HASH *h, void *dst, void *key, UINT key_size, void *data, UINT
 	}
 
 	// Generation of data 1
-	data1_size = data_size + HMAC_BLOCK_SIZE;
+	data1_size = data_size + hmac_block_size;
 
 	if (data1_size > sizeof(tmp1600))
 	{
@@ -2994,12 +3047,12 @@ void IkeHMac(IKE_HASH *h, void *dst, void *key, UINT key_size, void *data, UINT
 		no_free = true;
 	}
 
-	for (i = 0;i < HMAC_BLOCK_SIZE;i++)
+	for (i = 0;i < hmac_block_size;i++)
 	{
 		data1[i] = k[i] ^ 0x36;
 	}
 
-	Copy(data1 + HMAC_BLOCK_SIZE, data, data_size);
+	Copy(data1 + hmac_block_size, data, data_size);
 
 	// Calculate the hash value
 	IkeHash(h, hash1, data1, data1_size);
@@ -3010,14 +3063,14 @@ void IkeHMac(IKE_HASH *h, void *dst, void *key, UINT key_size, void *data, UINT
 	}
 
 	// Generation of data 2
-	data2_size = h->HashSize + HMAC_BLOCK_SIZE;
+	data2_size = h->HashSize + hmac_block_size;
 
 	for (i = 0;i < HMAC_BLOCK_SIZE;i++)
 	{
 		data2[i] = k[i] ^ 0x5c;
 	}
 
-	Copy(data2 + HMAC_BLOCK_SIZE, hash1, h->HashSize);
+	Copy(data2 + hmac_block_size, hash1, h->HashSize);
 
 	// Calculate the hash value
 	IkeHash(h, dst, data2, data2_size);

+ 13 - 1
src/Cedar/IPsec_IkePacket.h

@@ -120,7 +120,7 @@
 #endif	// OS_WIN32
 
 // Maximum hash size
-#define	IKE_MAX_HASH_SIZE				20		// Size of SHA-1 is the maximum for now
+#define	IKE_MAX_HASH_SIZE				64		// Size of SHA-2-512 is the maximum for now
 
 // Maximum block size
 #define	IKE_MAX_BLOCK_SIZE				16		// Size of AES is maximum at the moment
@@ -250,6 +250,9 @@ struct IKE_TRANSFORM_VALUE
 // Phase 1: The hash algorithm in IKE transform value
 #define	IKE_P1_HASH_MD5						1
 #define IKE_P1_HASH_SHA1					2
+#define IKE_P1_HASH_SHA2_256				4
+#define IKE_P1_HASH_SHA2_384				5
+#define IKE_P1_HASH_SHA2_512				6
 
 // Phase 1: The authentication method in the IKE transform value
 #define IKE_P1_AUTH_METHOD_PRESHAREDKEY		1
@@ -536,6 +539,15 @@ struct IKE_P1_KEYSET
 #define	IKE_HASH_SHA1_ID						1
 #define	IKE_HASH_SHA1_STRING					"SHA-1"
 
+#define	IKE_HASH_SHA2_256_ID					2
+#define	IKE_HASH_SHA2_256_STRING				"SHA-2-256"
+
+#define	IKE_HASH_SHA2_384_ID					3
+#define	IKE_HASH_SHA2_384_STRING				"SHA-2-384"
+
+#define	IKE_HASH_SHA2_512_ID					4
+#define	IKE_HASH_SHA2_512_STRING				"SHA-2-512"
+
 // Number and name of DH algorithm for IKE
 #define	IKE_DH_1_ID								0
 #define	IKE_DH_1_STRING							"MODP 768 (Group 1)"

+ 1 - 1
src/Cedar/Interop_OpenVPN.h

@@ -155,7 +155,7 @@
 #define	OPENVPN_CIPHER_LIST						"[NULL-CIPHER] NULL AES-128-CBC AES-192-CBC AES-256-CBC BF-CBC CAST-CBC CAST5-CBC DES-CBC DES-EDE-CBC DES-EDE3-CBC DESX-CBC RC2-40-CBC RC2-64-CBC RC2-CBC"
 
 // List of the supported hash algorithm
-#define	OPENVPN_MD_LIST							"SHA SHA1 MD5 MD4 RMD160"
+#define	OPENVPN_MD_LIST							"SHA SHA1 SHA256 SHA384 SHA512 MD5 MD4 RMD160"
 
 // MTU
 #define	OPENVPN_MTU_LINK						1514	// Ethernet MTU

+ 136 - 23
src/Mayaqua/Encrypt.c

@@ -378,14 +378,50 @@ void HMacMd5(void *dst, void *key, UINT key_size, void *data, UINT data_size)
 	MD5_Final(dst, &md5_ctx1);
 }
 
+void HMacSha1(void *dst, void *key, UINT key_size, void *data, UINT data_size) {
+	HMacSha(SHA1_160, dst, key, key_size, data, data_size);
+}
+
+void HMacSha2_256(void *dst, void *key, UINT key_size, void *data, UINT data_size) {
+	HMacSha(SHA2_256, dst, key, key_size, data, data_size);
+}
+
+void HMacSha2_384(void *dst, void *key, UINT key_size, void *data, UINT data_size) {
+	HMacSha(SHA2_384, dst, key, key_size, data, data_size);
+}
+
+void HMacSha2_512(void *dst, void *key, UINT key_size, void *data, UINT data_size) {
+	HMacSha(SHA2_512, dst, key, key_size, data, data_size);
+}
+
 // Calculation of HMAC (SHA-1)
-void HMacSha1(void *dst, void *key, UINT key_size, void *data, UINT data_size)
-{
-	UCHAR k[HMAC_BLOCK_SIZE];
-	UCHAR hash1[SHA1_SIZE];
-	UCHAR data2[HMAC_BLOCK_SIZE];
-	SHA_CTX sha_ctx1;
-	UCHAR pad1[HMAC_BLOCK_SIZE];
+void HMacSha(UINT sha_type, void *dst, void *key, UINT key_size, void *data, UINT data_size)
+{
+	UINT hmac_block_size;
+	void* sha_ctx1;
+	switch(sha_type) {
+		case SHA1_160:
+			sha_ctx1 = ZeroMalloc(sizeof(SHA_CTX));
+			hmac_block_size = HMAC_BLOCK_SIZE;
+			break;
+		case SHA2_256:
+			sha_ctx1 = ZeroMalloc(sizeof(SHA256_CTX));
+			hmac_block_size = HMAC_BLOCK_SIZE;
+			break;
+		case SHA2_384:
+		case SHA2_512:
+			sha_ctx1 = ZeroMalloc(sizeof(SHA512_CTX));
+			hmac_block_size = HMAC_BLOCK_SIZE_1024;
+			break;
+		default:
+		return;
+	}
+
+	UCHAR k[hmac_block_size];
+	UCHAR hash1[hmac_block_size];
+	UCHAR data2[hmac_block_size];
+	//SHA_CTX sha_ctx1;
+	UCHAR pad1[hmac_block_size];
 	UINT i;
 	// Validate arguments
 	if (dst == NULL || (key == NULL && key_size != 0) || (data == NULL && data_size != 0))
@@ -393,14 +429,15 @@ void HMacSha1(void *dst, void *key, UINT key_size, void *data, UINT data_size)
 		return;
 	}
 
+
 	// Creating a K
-	if (key_size <= HMAC_BLOCK_SIZE)
+	if (key_size <= hmac_block_size)
 	{
 		for (i = 0;i < key_size;i++)
 		{
 			pad1[i] = ((UCHAR *)key)[i] ^ 0x36;
 		}
-		for (i = key_size;i < HMAC_BLOCK_SIZE;i++)
+		for (i = key_size;i < hmac_block_size;i++)
 		{
 			pad1[i] = 0 ^ 0x36;
 		}
@@ -410,41 +447,89 @@ void HMacSha1(void *dst, void *key, UINT key_size, void *data, UINT data_size)
 		Zero(k, sizeof(k));
 		HashSha1(k, key, key_size);
 
-		for (i = 0;i < HMAC_BLOCK_SIZE;i++)
+		for (i = 0;i < hmac_block_size;i++)
 		{
 			pad1[i] = k[i] ^ 0x36;
 		}
 	}
 
-	SHA1_Init(&sha_ctx1);
-	SHA1_Update(&sha_ctx1, pad1, sizeof(pad1));
-	SHA1_Update(&sha_ctx1, data, data_size);
-	SHA1_Final(hash1, &sha_ctx1);
+	switch(sha_type) {
+		case SHA1_160:
+			SHA1_Init((SHA_CTX *)sha_ctx1);
+			SHA1_Update((SHA_CTX *)sha_ctx1, pad1, sizeof(pad1));
+			SHA1_Update((SHA_CTX *)sha_ctx1, data, data_size);
+			SHA1_Final(hash1, (SHA_CTX *)sha_ctx1);
+			break;
+		case SHA2_256:
+			SHA256_Init((SHA256_CTX *)sha_ctx1);
+			SHA256_Update((SHA256_CTX *)sha_ctx1, pad1, sizeof(pad1));
+			SHA256_Update((SHA256_CTX *)sha_ctx1, data, data_size);
+			SHA256_Final(hash1, (SHA256_CTX *)sha_ctx1);
+			break;
+		case SHA2_384:
+			SHA384_Init((SHA512_CTX *)sha_ctx1);
+			SHA384_Update((SHA512_CTX *)sha_ctx1, pad1, sizeof(pad1));
+			SHA384_Update((SHA512_CTX *)sha_ctx1, data, data_size);
+			SHA384_Final(hash1, (SHA512_CTX *)sha_ctx1);
+			break;
+		case SHA2_512:
+			SHA512_Init((SHA512_CTX *)sha_ctx1);
+			SHA512_Update((SHA512_CTX *)sha_ctx1, pad1, sizeof(pad1));
+			SHA512_Update((SHA512_CTX *)sha_ctx1, data, data_size);
+			SHA512_Final(hash1, (SHA512_CTX *)sha_ctx1);
+			break;
+	}
+
 
 	// Generation of data 2
-	if (key_size <= HMAC_BLOCK_SIZE)
+	if (key_size <= hmac_block_size)
 	{
 		for (i = 0;i < key_size;i++)
 		{
 			data2[i] = ((UCHAR *)key)[i] ^ 0x5c;
 		}
-		for (i = key_size;i < HMAC_BLOCK_SIZE;i++)
+		for (i = key_size;i < hmac_block_size;i++)
 		{
 			data2[i] = 0 ^ 0x5c;
 		}
 	}
 	else
 	{
-		for (i = 0;i < HMAC_BLOCK_SIZE;i++)
+		for (i = 0;i < hmac_block_size;i++)
 		{
 			data2[i] = k[i] ^ 0x5c;
 		}
 	}
 
-	SHA1_Init(&sha_ctx1);
-	SHA1_Update(&sha_ctx1, data2, HMAC_BLOCK_SIZE);
-	SHA1_Update(&sha_ctx1, hash1, SHA1_SIZE);
-	SHA1_Final(dst, &sha_ctx1);
+	switch(sha_type) {
+	case SHA1_160:
+		SHA1_Init((SHA_CTX *)sha_ctx1);
+		SHA1_Update((SHA_CTX *)sha_ctx1, data2, hmac_block_size);
+		SHA1_Update((SHA_CTX *)sha_ctx1, hash1, SHA1_SIZE);
+		SHA1_Final(dst, (SHA_CTX *)sha_ctx1);
+		break;
+	case SHA2_256:
+		SHA256_Init((SHA256_CTX *)sha_ctx1);
+		SHA256_Update((SHA256_CTX *)sha_ctx1, data2, hmac_block_size);
+		SHA256_Update((SHA256_CTX *)sha_ctx1, hash1, SHA256_SIZE);
+		SHA256_Final(dst, (SHA256_CTX *)sha_ctx1);
+		break;
+	case SHA2_384:
+		SHA384_Init((SHA512_CTX *)sha_ctx1);
+		SHA384_Update((SHA512_CTX *)sha_ctx1, data2, hmac_block_size);
+		SHA384_Update((SHA512_CTX *)sha_ctx1, hash1, SHA384_SIZE);
+		SHA384_Final(dst, (SHA512_CTX *)sha_ctx1);
+		break;
+
+	case SHA2_512:
+		SHA512_Init((SHA512_CTX *)sha_ctx1);
+		SHA512_Update((SHA512_CTX *)sha_ctx1, data2, hmac_block_size);
+		SHA512_Update((SHA512_CTX *)sha_ctx1, hash1, SHA512_SIZE);
+		SHA512_Final(dst, (SHA512_CTX *)sha_ctx1);
+		break;
+	}
+	Free(sha_ctx1);
+
 }
 
 // Calculate the HMAC
@@ -4358,7 +4443,7 @@ void Encrypt(CRYPT *c, void *dst, void *src, UINT size)
 }
 
 // SHA-1 hash
-void Sha1(void *dst, void *src, UINT size)
+void Sha(UINT sha_type, void *dst, void *src, UINT size)
 {
 	// Validate arguments
 	if (dst == NULL || src == NULL)
@@ -4366,7 +4451,35 @@ void Sha1(void *dst, void *src, UINT size)
 		return;
 	}
 
-	SHA1(src, size, dst);
+	switch(sha_type) {
+	case SHA1_160:
+		SHA1(src, size, dst);
+		break;
+	case SHA2_256:
+		SHA256(src, size, dst);
+		break;
+	case SHA2_384:
+		SHA384(src, size, dst);
+		break;
+	case SHA2_512:
+		SHA512(src, size, dst);
+		break;
+	}
+
+}
+
+void Sha1(void *dst, void *src, UINT size) {
+	Sha(SHA1_160, dst, src, size);
+}
+
+void Sha2_256(void *dst, void *src, UINT size) {
+	Sha(SHA2_256, dst, src, size);
+}
+void Sha2_384(void *dst, void *src, UINT size) {
+	Sha(SHA2_384, dst, src, size);
+}
+void Sha2_512(void *dst, void *src, UINT size) {
+	Sha(SHA2_512, dst, src, size);
 }
 
 // MD5 hash

+ 19 - 0
src/Mayaqua/Encrypt.h

@@ -141,8 +141,16 @@ void RAND_Free_For_SoftEther();
 #define	AES_IV_SIZE					16			// AES IV size
 #define	AES_MAX_KEY_SIZE			32			// Maximum AES key size
 
+// IANA definitions taken from IKEv1 Phase 1
+#define SHA1_160						2
+#define SHA2_256						4
+#define SHA2_384						5
+#define SHA2_512						6
+
 // HMAC block size
 #define	HMAC_BLOCK_SIZE					64
+// The block size for sha-384 and sha-512 as defined by rfc4868
+#define HMAC_BLOCK_SIZE_1024			128
 
 #define DH_GROUP1_PRIME_768 \
 	"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
@@ -294,6 +302,8 @@ struct X_CRL
 #define	MD5_SIZE	16
 #define	SHA1_SIZE	20
 #define	SHA256_SIZE	32
+#define	SHA384_SIZE	48
+#define	SHA512_SIZE	64
 
 // Key element of DES
 struct DES_KEY_VALUE
@@ -508,7 +518,12 @@ void Des3Encrypt(void *dest, void *src, UINT size, DES_KEY *key, void *ivec);
 void Des3Encrypt2(void *dest, void *src, UINT size, DES_KEY_VALUE *k1, DES_KEY_VALUE *k2, DES_KEY_VALUE *k3, void *ivec);
 void Des3Decrypt(void *dest, void *src, UINT size, DES_KEY *key, void *ivec);
 void Des3Decrypt2(void *dest, void *src, UINT size, DES_KEY_VALUE *k1, DES_KEY_VALUE *k2, DES_KEY_VALUE *k3, void *ivec);
+void Sha(UINT sha_type, void *dst, void *src, UINT size);
 void Sha1(void *dst, void *src, UINT size);
+void Sha2_256(void *dst, void *src, UINT size);
+void Sha2_384(void *dst, void *src, UINT size);
+void Sha2_512(void *dst, void *src, UINT size);
+
 void Md5(void *dst, void *src, UINT size);
 void MacSha1(void *dst, void *key, UINT key_size, void *data, UINT data_size);
 void MacSha196(void *dst, void *key, void *data, UINT data_size);
@@ -559,7 +574,11 @@ void MdProcess(MD *md, void *dest, void *src, UINT size);
 void Enc_tls1_PRF(unsigned char *label, int label_len, const unsigned char *sec,
 				  int slen, unsigned char *out1, int olen);
 
+void HMacSha(UINT sha_type, void *dst, void *key, UINT key_size, void *data, UINT data_size);
 void HMacSha1(void *dst, void *key, UINT key_size, void *data, UINT data_size);
+void HMacSha2_256(void *dst, void *key, UINT key_size, void *data, UINT data_size);
+void HMacSha2_384(void *dst, void *key, UINT key_size, void *data, UINT data_size);
+void HMacSha2_512(void *dst, void *key, UINT key_size, void *data, UINT data_size);
 void HMacMd5(void *dst, void *key, UINT key_size, void *data, UINT data_size);
 
 BUF *EasyEncrypt(BUF *src_buf);

+ 1 - 1
src/bin/hamcore/openvpn_sample.ovpn

@@ -83,7 +83,7 @@ $TAG_BEFORE_REMOTE$remote $TAG_HOSTNAME$ $TAG_PORT$
 #  cipher: [NULL-CIPHER] NULL AES-128-CBC AES-192-CBC AES-256-CBC BF-CBC
 #          CAST-CBC CAST5-CBC DES-CBC DES-EDE-CBC DES-EDE3-CBC DESX-CBC
 #          RC2-40-CBC RC2-64-CBC RC2-CBC
-#  auth:   SHA SHA1 MD5 MD4 RMD160
+#  auth:   SHA SHA1 SHA256 SHA384 SHA512 MD5 MD4 RMD160
 
 cipher AES-128-CBC
 auth SHA1