From 342d602f5d8405ddc248a90c4caa4c04c797bfa2 Mon Sep 17 00:00:00 2001 From: Moataz Elmasry Date: Sun, 22 Jan 2017 16:09:30 +0100 Subject: Add support for HMAC SHA2-256, HMAC SHA2-384, HMAC SHA2-512 --- src/Mayaqua/Encrypt.c | 117 ++++++++++++++++++++++++++++++++++++++++++-------- src/Mayaqua/Encrypt.h | 14 ++++++ 2 files changed, 112 insertions(+), 19 deletions(-) diff --git a/src/Mayaqua/Encrypt.c b/src/Mayaqua/Encrypt.c index 9914646b..21058a77 100644 --- a/src/Mayaqua/Encrypt.c +++ b/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 diff --git a/src/Mayaqua/Encrypt.h b/src/Mayaqua/Encrypt.h index 46720fb5..9021b983 100644 --- a/src/Mayaqua/Encrypt.h +++ b/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); -- cgit v1.2.3