mirror of
https://github.com/kingToolbox/WindTerm.git
synced 2025-03-22 10:50:07 +08:00
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:
parent
3b5a92f238
commit
e2a4cb6e80
@ -38,9 +38,11 @@ enum ssh_kdf_digest {
|
|||||||
|
|
||||||
enum ssh_hmac_e {
|
enum ssh_hmac_e {
|
||||||
SSH_HMAC_SHA1 = 1,
|
SSH_HMAC_SHA1 = 1,
|
||||||
|
SSH_HMAC_SHA1_96,
|
||||||
SSH_HMAC_SHA256,
|
SSH_HMAC_SHA256,
|
||||||
SSH_HMAC_SHA512,
|
SSH_HMAC_SHA512,
|
||||||
SSH_HMAC_MD5,
|
SSH_HMAC_MD5,
|
||||||
|
SSH_HMAC_MD5_96,
|
||||||
SSH_HMAC_AEAD_POLY1305,
|
SSH_HMAC_AEAD_POLY1305,
|
||||||
SSH_HMAC_AEAD_GCM
|
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);
|
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_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_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,
|
int ssh_kdf(struct ssh_crypto_struct *crypto,
|
||||||
unsigned char *key, size_t key_len,
|
unsigned char *key, size_t key_len,
|
||||||
|
@ -216,8 +216,8 @@ static const char *default_methods[] = {
|
|||||||
PUBLIC_KEY_ALGORITHMS,
|
PUBLIC_KEY_ALGORITHMS,
|
||||||
AES BLOWFISH DES,
|
AES BLOWFISH DES,
|
||||||
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-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-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",
|
||||||
"none",
|
"none",
|
||||||
"none",
|
"none",
|
||||||
"",
|
"",
|
||||||
@ -231,8 +231,8 @@ static const char *supported_methods[] = {
|
|||||||
PUBLIC_KEY_ALGORITHMS,
|
PUBLIC_KEY_ALGORITHMS,
|
||||||
CHACHA20 AES BLOWFISH DES_SUPPORTED,
|
CHACHA20 AES BLOWFISH DES_SUPPORTED,
|
||||||
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-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-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",
|
||||||
ZLIB,
|
ZLIB,
|
||||||
ZLIB,
|
ZLIB,
|
||||||
"",
|
"",
|
||||||
@ -1317,13 +1317,13 @@ int ssh_generate_session_keys(ssh_session session)
|
|||||||
if (session->client) {
|
if (session->client) {
|
||||||
enckey_cli_to_srv_len = crypto->out_cipher->keysize / 8;
|
enckey_cli_to_srv_len = crypto->out_cipher->keysize / 8;
|
||||||
enckey_srv_to_cli_len = crypto->in_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_cli_to_srv_len = hmac_key_len(crypto->out_hmac);
|
||||||
intkey_srv_to_cli_len = hmac_digest_len(crypto->in_hmac);
|
intkey_srv_to_cli_len = hmac_key_len(crypto->in_hmac);
|
||||||
} else {
|
} else {
|
||||||
enckey_cli_to_srv_len = crypto->in_cipher->keysize / 8;
|
enckey_cli_to_srv_len = crypto->in_cipher->keysize / 8;
|
||||||
enckey_srv_to_cli_len = crypto->out_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_cli_to_srv_len = hmac_key_len(crypto->in_hmac);
|
||||||
intkey_srv_to_cli_len = hmac_digest_len(crypto->out_hmac);
|
intkey_srv_to_cli_len = hmac_key_len(crypto->out_hmac);
|
||||||
}
|
}
|
||||||
|
|
||||||
IV_cli_to_srv = malloc(IV_len);
|
IV_cli_to_srv = malloc(IV_len);
|
||||||
|
@ -253,7 +253,7 @@ static int match_hashed_host(const char *host, const char *sourcehash)
|
|||||||
}
|
}
|
||||||
size = sizeof(buffer);
|
size = sizeof(buffer);
|
||||||
hmac_update(mac, host, strlen(host));
|
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) &&
|
if (size == ssh_buffer_get_len(hash) &&
|
||||||
memcmp(buffer, ssh_buffer_get(hash), size) == 0) {
|
memcmp(buffer, ssh_buffer_get(hash), size) == 0) {
|
||||||
|
@ -64,7 +64,7 @@ static int hash_hostname(const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hmac_update(mac_ctx, name, strlen(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;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
@ -431,6 +431,7 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
|
|||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case SSH_HMAC_SHA1:
|
case SSH_HMAC_SHA1:
|
||||||
|
case SSH_HMAC_SHA1_96:
|
||||||
HMAC_Init_ex(ctx, key, len, EVP_sha1(), NULL);
|
HMAC_Init_ex(ctx, key, len, EVP_sha1(), NULL);
|
||||||
break;
|
break;
|
||||||
case SSH_HMAC_SHA256:
|
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);
|
HMAC_Init_ex(ctx, key, len, EVP_sha512(), NULL);
|
||||||
break;
|
break;
|
||||||
case SSH_HMAC_MD5:
|
case SSH_HMAC_MD5:
|
||||||
|
case SSH_HMAC_MD5_96:
|
||||||
HMAC_Init_ex(ctx, key, len, EVP_md5(), NULL);
|
HMAC_Init_ex(ctx, key, len, EVP_md5(), NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -454,9 +456,16 @@ void hmac_update(HMACCTX ctx, const void *data, unsigned long len) {
|
|||||||
HMAC_Update(ctx, data, 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);
|
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
|
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||||
HMAC_CTX_free(ctx);
|
HMAC_CTX_free(ctx);
|
||||||
ctx = NULL;
|
ctx = NULL;
|
||||||
|
@ -177,7 +177,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
|
|||||||
crypto->hmacbuf, session->send_seq);
|
crypto->hmacbuf, session->send_seq);
|
||||||
memcpy(data, out, len);
|
memcpy(data, out, len);
|
||||||
} else {
|
} else {
|
||||||
ctx = hmac_init(crypto->encryptMAC, hmac_digest_len(type), type);
|
ctx = hmac_init(crypto->encryptMAC, hmac_key_len(type), type);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
SAFE_FREE(out);
|
SAFE_FREE(out);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -186,7 +186,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
|
|||||||
if (!etm) {
|
if (!etm) {
|
||||||
hmac_update(ctx, (unsigned char *)&seq, sizeof(uint32_t));
|
hmac_update(ctx, (unsigned char *)&seq, sizeof(uint32_t));
|
||||||
hmac_update(ctx, data, len);
|
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);
|
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);
|
PUSH_BE_U32(data, 0, len - etm_packet_offset);
|
||||||
hmac_update(ctx, (unsigned char *)&seq, sizeof(uint32_t));
|
hmac_update(ctx, (unsigned char *)&seq, sizeof(uint32_t));
|
||||||
hmac_update(ctx, data, len);
|
hmac_update(ctx, data, len);
|
||||||
hmac_final(ctx, crypto->hmacbuf, &finallen);
|
hmac_final(ctx, crypto->hmacbuf, &finallen, type);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_log_hexdump("mac: ", data, len);
|
ssh_log_hexdump("mac: ", data, len);
|
||||||
@ -259,7 +259,7 @@ int ssh_packet_hmac_verify(ssh_session session,
|
|||||||
return SSH_ERROR;
|
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) {
|
if (ctx == NULL) {
|
||||||
return -1;
|
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, (unsigned char *) &seq, sizeof(uint32_t));
|
||||||
hmac_update(ctx, data, len);
|
hmac_update(ctx, data, len);
|
||||||
hmac_final(ctx, hmacbuf, &hmaclen);
|
hmac_final(ctx, hmacbuf, &hmaclen, type);
|
||||||
|
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_log_hexdump("received mac",mac,hmaclen);
|
ssh_log_hexdump("received mac",mac,hmaclen);
|
||||||
|
@ -55,17 +55,24 @@
|
|||||||
#include "libssh/ecdh.h"
|
#include "libssh/ecdh.h"
|
||||||
#include "libssh/curve25519.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[] = {
|
static struct ssh_hmac_struct ssh_hmac_tab[] = {
|
||||||
{ "hmac-sha1", SSH_HMAC_SHA1, false },
|
{ "hmac-sha1", SSH_HMAC_SHA1, false },
|
||||||
|
{ "hmac-sha1-96", SSH_HMAC_SHA1_96, false },
|
||||||
{ "hmac-sha2-256", SSH_HMAC_SHA256, false },
|
{ "hmac-sha2-256", SSH_HMAC_SHA256, false },
|
||||||
{ "hmac-sha2-512", SSH_HMAC_SHA512, false },
|
{ "hmac-sha2-512", SSH_HMAC_SHA512, false },
|
||||||
{ "hmac-md5", SSH_HMAC_MD5, false },
|
{ "hmac-md5", SSH_HMAC_MD5, false },
|
||||||
|
{ "hmac-md5-96", SSH_HMAC_MD5_96, false },
|
||||||
{ "aead-poly1305", SSH_HMAC_AEAD_POLY1305, false },
|
{ "aead-poly1305", SSH_HMAC_AEAD_POLY1305, false },
|
||||||
{ "aead-gcm", SSH_HMAC_AEAD_GCM, false },
|
{ "aead-gcm", SSH_HMAC_AEAD_GCM, false },
|
||||||
{ "hmac-sha1-etm@openssh.com", SSH_HMAC_SHA1, true },
|
{ "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-256-etm@openssh.com", SSH_HMAC_SHA256, true },
|
||||||
{ "hmac-sha2-512-etm@openssh.com", SSH_HMAC_SHA512, true },
|
{ "hmac-sha2-512-etm@openssh.com", SSH_HMAC_SHA512, true },
|
||||||
{ "hmac-md5-etm@openssh.com", SSH_HMAC_MD5, true },
|
{ "hmac-md5-etm@openssh.com", SSH_HMAC_MD5, true },
|
||||||
|
{ "hmac-md5-96-etm@openssh.com", SSH_HMAC_MD5_96, true },
|
||||||
{ NULL, 0, false }
|
{ NULL, 0, false }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,12 +84,37 @@ size_t hmac_digest_len(enum ssh_hmac_e type) {
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case SSH_HMAC_SHA1:
|
case SSH_HMAC_SHA1:
|
||||||
return SHA_DIGEST_LEN;
|
return SHA_DIGEST_LEN;
|
||||||
|
case SSH_HMAC_SHA1_96:
|
||||||
|
return SHA_96_DIGEST_LEN;
|
||||||
case SSH_HMAC_SHA256:
|
case SSH_HMAC_SHA256:
|
||||||
return SHA256_DIGEST_LEN;
|
return SHA256_DIGEST_LEN;
|
||||||
case SSH_HMAC_SHA512:
|
case SSH_HMAC_SHA512:
|
||||||
return SHA512_DIGEST_LEN;
|
return SHA512_DIGEST_LEN;
|
||||||
case SSH_HMAC_MD5:
|
case SSH_HMAC_MD5:
|
||||||
return MD5_DIGEST_LEN;
|
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:
|
case SSH_HMAC_AEAD_POLY1305:
|
||||||
return POLY1305_TAGLEN;
|
return POLY1305_TAGLEN;
|
||||||
case SSH_HMAC_AEAD_GCM:
|
case SSH_HMAC_AEAD_GCM:
|
||||||
|
Loading…
Reference in New Issue
Block a user