diff --git a/src/libgcrypt.h b/src/libgcrypt.h index f9da52b..e2eb4d2 100644 --- a/src/libgcrypt.h +++ b/src/libgcrypt.h @@ -42,6 +42,8 @@ #define LIBSSH2_MD5 1 #define LIBSSH2_HMAC_RIPEMD 1 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 #define LIBSSH2_AES 1 #define LIBSSH2_AES_CTR 1 @@ -95,6 +97,12 @@ #define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \ gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) #define libssh2_hmac_update(ctx, data, datalen) \ gcry_md_write (ctx, (unsigned char *) data, datalen) #define libssh2_hmac_final(ctx, data) \ diff --git a/src/mac.c b/src/mac.c index 786a953..5ec26eb 100644 --- a/src/mac.c +++ b/src/mac.c @@ -96,6 +96,97 @@ mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract) +#if LIBSSH2_HMAC_SHA512 +/* mac_method_hmac_sha512_hash + * Calculate hash using full sha512 value + */ +static int +mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha512_init(&ctx, *abstract, 64); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = { + "hmac-sha2-512", + 64, + 64, + mac_method_common_init, + mac_method_hmac_sha2_512_hash, + mac_method_common_dtor, +}; +#endif + + + +#if LIBSSH2_HMAC_SHA256 +/* mac_method_hmac_sha256_hash + * Calculate hash using full sha256 value + */ +static int +mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha256_init(&ctx, *abstract, 32); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = { + "hmac-sha2-256", + 32, + 32, + mac_method_common_init, + mac_method_hmac_sha2_256_hash, + mac_method_common_dtor, +}; +#endif + + + + /* mac_method_hmac_sha1_hash * Calculate hash using full sha1 value */ @@ -294,6 +385,12 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = { #endif /* LIBSSH2_HMAC_RIPEMD */ static const LIBSSH2_MAC_METHOD *mac_methods[] = { +#if LIBSSH2_HMAC_SHA256 + &mac_method_hmac_sha2_256, +#endif +#if LIBSSH2_HMAC_SHA512 + &mac_method_hmac_sha2_512, +#endif &mac_method_hmac_sha1, &mac_method_hmac_sha1_96, #if LIBSSH2_MD5 diff --git a/src/openssl.h b/src/openssl.h index a571309..4c3fe89 100644 --- a/src/openssl.h +++ b/src/openssl.h @@ -76,6 +76,9 @@ # define LIBSSH2_HMAC_RIPEMD 1 #endif +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + #if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES) # define LIBSSH2_AES_CTR 1 # define LIBSSH2_AES 1 @@ -138,6 +141,10 @@ int _libssh2_md5_init(libssh2_md5_ctx *); HMAC_Init(ctx, key, keylen, EVP_md5()) #define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ HMAC_Init(ctx, key, keylen, EVP_ripemd160()) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + HMAC_Init(ctx, key, keylen, EVP_sha256()) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + HMAC_Init(ctx, key, keylen, EVP_sha512()) #define libssh2_hmac_update(ctx, data, datalen) \ HMAC_Update(&(ctx), data, datalen) #define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL) diff --git a/src/transport.c b/src/transport.c index 5b3d66d..8725da0 100644 --- a/src/transport.c +++ b/src/transport.c @@ -52,7 +52,7 @@ #include "mac.h" #define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ -#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */ +#define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */ #ifdef LIBSSH2DEBUG #define UNPRINTABLE_CHAR '.' diff --git a/src/wincng.h b/src/wincng.h index 429192c..0381247 100644 --- a/src/wincng.h +++ b/src/wincng.h @@ -51,6 +51,8 @@ #define LIBSSH2_MD5 1 #define LIBSSH2_HMAC_RIPEMD 0 +#define LIBSSH2_HMAC_SHA256 0 +#define LIBSSH2_HMAC_SHA512 0 #define LIBSSH2_AES 1 #define LIBSSH2_AES_CTR 0 @@ -158,6 +160,10 @@ typedef struct __libssh2_wincng_hash_ctx { MD5_DIGEST_LENGTH, key, keylen) #define libssh2_hmac_ripemd160_init(ctx, key, keylen) /* not implemented */ +#define libssh2_hmac_sha256_init(ctx, key, keylen) + /* not implemented */ +#define libssh2_hmac_sha512_init(ctx, key, keylen) + /* not implemented */ #define libssh2_hmac_update(ctx, data, datalen) \ _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) #define libssh2_hmac_final(ctx, hash) \