浏览代码

Add support for HMAC SHA2-256, HMAC SHA2-384, HMAC SHA2-512

Moataz Elmasry 8 年之前
父节点
当前提交
342d602f5d
共有 2 个文件被更改,包括 112 次插入19 次删除
  1. 98 19
      src/Mayaqua/Encrypt.c
  2. 14 0
      src/Mayaqua/Encrypt.h

+ 98 - 19
src/Mayaqua/Encrypt.c

@@ -378,14 +378,44 @@ 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)
+void HMacSha(UINT sha_type, 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];
+	UINT hmac_block_size;
+	switch(sha_type) {
+		case _SHA1_160:
+		case _SHA2_256:
+			hmac_block_size = HMAC_BLOCK_SIZE;
+			break;
+		case _SHA2_384:
+		case _SHA2_512:
+			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];
+	UCHAR pad1[hmac_block_size];
 	UINT i;
 	// Validate arguments
 	if (dst == NULL || (key == NULL && key_size != 0) || (data == NULL && data_size != 0))
@@ -393,14 +423,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 +441,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_ctx1);
+			SHA1_Update(&sha_ctx1, pad1, sizeof(pad1));
+			SHA1_Update(&sha_ctx1, data, data_size);
+			SHA1_Final(hash1, &sha_ctx1);
+			break;
+		case _SHA2_256:
+			SHA256_Init(&sha_ctx1);
+			SHA256_Update(&sha_ctx1, pad1, sizeof(pad1));
+			SHA256_Update(&sha_ctx1, data, data_size);
+			SHA256_Final(hash1, &sha_ctx1);
+			break;
+		case _SHA2_384:
+			SHA384_Init(&sha_ctx1);
+			SHA384_Update(&sha_ctx1, pad1, sizeof(pad1));
+			SHA384_Update(&sha_ctx1, data, data_size);
+			SHA384_Final(hash1, &sha_ctx1);
+			break;
+		case _SHA2_512:
+			SHA512_Init(&sha_ctx1);
+			SHA512_Update(&sha_ctx1, pad1, sizeof(pad1));
+			SHA512_Update(&sha_ctx1, data, data_size);
+			SHA512_Final(hash1, &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_ctx1);
+		SHA1_Update(&sha_ctx1, data2, hmac_block_size);
+		SHA1_Update(&sha_ctx1, hash1, SHA1_SIZE);
+		SHA1_Final(dst, &sha_ctx1);
+		break;
+	case _SHA2_256:
+		SHA256_Init(&sha_ctx1);
+		SHA256_Update(&sha_ctx1, data2, hmac_block_size);
+		SHA256_Update(&sha_ctx1, hash1, SHA256_SIZE);
+		SHA256_Final(dst, &sha_ctx1);
+		break;
+	case _SHA2_384:
+		SHA384_Init(&sha_ctx1);
+		SHA384_Update(&sha_ctx1, data2, hmac_block_size);
+		SHA384_Update(&sha_ctx1, hash1, SHA384_SIZE);
+		SHA384_Final(dst, &sha_ctx1);
+		break;
+
+	case _SHA2_512:
+		SHA384_Init(&sha_ctx1);
+		SHA384_Update(&sha_ctx1, data2, hmac_block_size);
+		SHA1_Update(&sha_ctx1, hash1, SHA512_SIZE);
+		SHA384_Final(dst, &sha_ctx1);
+		break;
+
+	}
+
 }
 
 // Calculate the HMAC

+ 14 - 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. For internal use only
+#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
@@ -559,7 +569,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);