Add support for hmac-md5-96, hmac-sha1-96-etm@openssh.com, hmac-sha1-96, hmac-md5-96-etm@openssh.com in libssh.

This commit is contained in:
KingToolbox 2020-10-18 17:18:45 +08:00
parent 3b5a92f238
commit e2a4cb6e80
7 changed files with 61 additions and 17 deletions

View File

@ -38,9 +38,11 @@ enum ssh_kdf_digest {
enum ssh_hmac_e {
SSH_HMAC_SHA1 = 1,
SSH_HMAC_SHA1_96,
SSH_HMAC_SHA256,
SSH_HMAC_SHA512,
SSH_HMAC_MD5,
SSH_HMAC_MD5_96,
SSH_HMAC_AEAD_POLY1305,
SSH_HMAC_AEAD_GCM
};
@ -97,8 +99,9 @@ void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen);
HMACCTX hmac_init(const void *key,int len, enum ssh_hmac_e type);
void hmac_update(HMACCTX c, const void *data, unsigned long len);
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len, enum ssh_hmac_e type);
size_t hmac_digest_len(enum ssh_hmac_e type);
size_t hmac_key_len(enum ssh_hmac_e type);
int ssh_kdf(struct ssh_crypto_struct *crypto,
unsigned char *key, size_t key_len,

View File

@ -216,8 +216,8 @@ static const char *default_methods[] = {
PUBLIC_KEY_ALGORITHMS,
AES BLOWFISH DES,
AES BLOWFISH DES,
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-sha1-96",
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-sha1-96",
"none",
"none",
"",
@ -231,8 +231,8 @@ static const char *supported_methods[] = {
PUBLIC_KEY_ALGORITHMS,
CHACHA20 AES BLOWFISH DES_SUPPORTED,
CHACHA20 AES BLOWFISH DES_SUPPORTED,
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-sha1-96",
"hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-sha1-96",
ZLIB,
ZLIB,
"",
@ -1317,13 +1317,13 @@ int ssh_generate_session_keys(ssh_session session)
if (session->client) {
enckey_cli_to_srv_len = crypto->out_cipher->keysize / 8;
enckey_srv_to_cli_len = crypto->in_cipher->keysize / 8;
intkey_cli_to_srv_len = hmac_digest_len(crypto->out_hmac);
intkey_srv_to_cli_len = hmac_digest_len(crypto->in_hmac);
intkey_cli_to_srv_len = hmac_key_len(crypto->out_hmac);
intkey_srv_to_cli_len = hmac_key_len(crypto->in_hmac);
} else {
enckey_cli_to_srv_len = crypto->in_cipher->keysize / 8;
enckey_srv_to_cli_len = crypto->out_cipher->keysize / 8;
intkey_cli_to_srv_len = hmac_digest_len(crypto->in_hmac);
intkey_srv_to_cli_len = hmac_digest_len(crypto->out_hmac);
intkey_cli_to_srv_len = hmac_key_len(crypto->in_hmac);
intkey_srv_to_cli_len = hmac_key_len(crypto->out_hmac);
}
IV_cli_to_srv = malloc(IV_len);

View File

@ -253,7 +253,7 @@ static int match_hashed_host(const char *host, const char *sourcehash)
}
size = sizeof(buffer);
hmac_update(mac, host, strlen(host));
hmac_final(mac, buffer, &size);
hmac_final(mac, buffer, &size, SSH_HMAC_SHA1);
if (size == ssh_buffer_get_len(hash) &&
memcmp(buffer, ssh_buffer_get(hash), size) == 0) {

View File

@ -64,7 +64,7 @@ static int hash_hostname(const char *name,
}
hmac_update(mac_ctx, name, strlen(name));
hmac_final(mac_ctx, *hash, hash_size);
hmac_final(mac_ctx, *hash, hash_size, SSH_HMAC_SHA1);
return SSH_OK;
}

View File

@ -431,6 +431,7 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
switch(type) {
case SSH_HMAC_SHA1:
case SSH_HMAC_SHA1_96:
HMAC_Init_ex(ctx, key, len, EVP_sha1(), NULL);
break;
case SSH_HMAC_SHA256:
@ -440,6 +441,7 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
HMAC_Init_ex(ctx, key, len, EVP_sha512(), NULL);
break;
case SSH_HMAC_MD5:
case SSH_HMAC_MD5_96:
HMAC_Init_ex(ctx, key, len, EVP_md5(), NULL);
break;
default:
@ -454,9 +456,16 @@ void hmac_update(HMACCTX ctx, const void *data, unsigned long len) {
HMAC_Update(ctx, data, len);
}
void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) {
void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len, enum ssh_hmac_e type) {
HMAC_Final(ctx,hashmacbuf,len);
switch (type) {
case SSH_HMAC_SHA1_96:
case SSH_HMAC_MD5_96:
*len = hmac_digest_len(type);
break;
}
#if OPENSSL_VERSION_NUMBER > 0x10100000L
HMAC_CTX_free(ctx);
ctx = NULL;

View File

@ -177,7 +177,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
crypto->hmacbuf, session->send_seq);
memcpy(data, out, len);
} else {
ctx = hmac_init(crypto->encryptMAC, hmac_digest_len(type), type);
ctx = hmac_init(crypto->encryptMAC, hmac_key_len(type), type);
if (ctx == NULL) {
SAFE_FREE(out);
return NULL;
@ -186,7 +186,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
if (!etm) {
hmac_update(ctx, (unsigned char *)&seq, sizeof(uint32_t));
hmac_update(ctx, data, len);
hmac_final(ctx, crypto->hmacbuf, &finallen);
hmac_final(ctx, crypto->hmacbuf, &finallen, type);
}
cipher->encrypt(cipher, (uint8_t*)data + etm_packet_offset, out, len - etm_packet_offset);
@ -196,7 +196,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
PUSH_BE_U32(data, 0, len - etm_packet_offset);
hmac_update(ctx, (unsigned char *)&seq, sizeof(uint32_t));
hmac_update(ctx, data, len);
hmac_final(ctx, crypto->hmacbuf, &finallen);
hmac_final(ctx, crypto->hmacbuf, &finallen, type);
}
#ifdef DEBUG_CRYPTO
ssh_log_hexdump("mac: ", data, len);
@ -259,7 +259,7 @@ int ssh_packet_hmac_verify(ssh_session session,
return SSH_ERROR;
}
ctx = hmac_init(crypto->decryptMAC, hmac_digest_len(type), type);
ctx = hmac_init(crypto->decryptMAC, hmac_key_len(type), type);
if (ctx == NULL) {
return -1;
}
@ -268,7 +268,7 @@ int ssh_packet_hmac_verify(ssh_session session,
hmac_update(ctx, (unsigned char *) &seq, sizeof(uint32_t));
hmac_update(ctx, data, len);
hmac_final(ctx, hmacbuf, &hmaclen);
hmac_final(ctx, hmacbuf, &hmaclen, type);
#ifdef DEBUG_CRYPTO
ssh_log_hexdump("received mac",mac,hmaclen);

View File

@ -55,17 +55,24 @@
#include "libssh/ecdh.h"
#include "libssh/curve25519.h"
#define SHA_96_DIGEST_LEN 12
#define MD5_96_DIGEST_LEN 12
static struct ssh_hmac_struct ssh_hmac_tab[] = {
{ "hmac-sha1", SSH_HMAC_SHA1, false },
{ "hmac-sha1-96", SSH_HMAC_SHA1_96, false },
{ "hmac-sha2-256", SSH_HMAC_SHA256, false },
{ "hmac-sha2-512", SSH_HMAC_SHA512, false },
{ "hmac-md5", SSH_HMAC_MD5, false },
{ "hmac-md5-96", SSH_HMAC_MD5_96, false },
{ "aead-poly1305", SSH_HMAC_AEAD_POLY1305, false },
{ "aead-gcm", SSH_HMAC_AEAD_GCM, false },
{ "hmac-sha1-etm@openssh.com", SSH_HMAC_SHA1, true },
{ "hmac-sha1-96-etm@openssh.com", SSH_HMAC_SHA1_96, true },
{ "hmac-sha2-256-etm@openssh.com", SSH_HMAC_SHA256, true },
{ "hmac-sha2-512-etm@openssh.com", SSH_HMAC_SHA512, true },
{ "hmac-md5-etm@openssh.com", SSH_HMAC_MD5, true },
{ "hmac-md5-96-etm@openssh.com", SSH_HMAC_MD5_96, true },
{ NULL, 0, false }
};
@ -77,12 +84,37 @@ size_t hmac_digest_len(enum ssh_hmac_e type) {
switch(type) {
case SSH_HMAC_SHA1:
return SHA_DIGEST_LEN;
case SSH_HMAC_SHA1_96:
return SHA_96_DIGEST_LEN;
case SSH_HMAC_SHA256:
return SHA256_DIGEST_LEN;
case SSH_HMAC_SHA512:
return SHA512_DIGEST_LEN;
case SSH_HMAC_MD5:
return MD5_DIGEST_LEN;
case SSH_HMAC_MD5_96:
return MD5_96_DIGEST_LEN;
case SSH_HMAC_AEAD_POLY1305:
return POLY1305_TAGLEN;
case SSH_HMAC_AEAD_GCM:
return AES_GCM_TAGLEN;
default:
return 0;
}
}
size_t hmac_key_len(enum ssh_hmac_e type) {
switch (type) {
case SSH_HMAC_SHA1:
case SSH_HMAC_SHA1_96:
return SHA_DIGEST_LEN;
case SSH_HMAC_SHA256:
return SHA256_DIGEST_LEN;
case SSH_HMAC_SHA512:
return SHA512_DIGEST_LEN;
case SSH_HMAC_MD5:
case SSH_HMAC_MD5_96:
return MD5_DIGEST_LEN;
case SSH_HMAC_AEAD_POLY1305:
return POLY1305_TAGLEN;
case SSH_HMAC_AEAD_GCM: