1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-27 13:21:11 +03:00

chacha: packet decryption

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Aris Adamantiadis
2018-02-28 10:24:54 -06:00
committed by Andreas Schneider
parent d038c4dee7
commit 8a735d5eb7
7 changed files with 275 additions and 103 deletions

View File

@@ -155,6 +155,10 @@ struct ssh_cipher_struct {
unsigned long len); unsigned long len);
void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out, void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
size_t len, uint8_t *mac, uint64_t seq); size_t len, uint8_t *mac, uint64_t seq);
int (*aead_decrypt_length)(struct ssh_cipher_struct *cipher, void *in,
uint8_t *out, size_t len, uint64_t seq);
int (*aead_decrypt)(struct ssh_cipher_struct *cipher, void *complete_packet, uint8_t *out,
size_t encrypted_size, uint64_t seq);
void (*cleanup)(struct ssh_cipher_struct *cipher); void (*cleanup)(struct ssh_cipher_struct *cipher);
}; };

View File

@@ -78,8 +78,9 @@ void ssh_packet_set_default_callbacks(ssh_session session);
void ssh_packet_process(ssh_session session, uint8_t type); void ssh_packet_process(ssh_session session, uint8_t type);
/* PACKET CRYPT */ /* PACKET CRYPT */
uint32_t ssh_packet_decrypt_len(ssh_session session, char *crypted); uint32_t ssh_packet_decrypt_len(ssh_session session, uint8_t *destination, uint8_t *source);
int ssh_packet_decrypt(ssh_session session, void *packet, unsigned int len); int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *source,
size_t start, size_t encrypted_size);
unsigned char *ssh_packet_encrypt(ssh_session session, unsigned char *ssh_packet_encrypt(ssh_session session,
void *packet, void *packet,
unsigned int len); unsigned int len);

View File

@@ -109,8 +109,82 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
out_packet->payload, out_packet->payload,
len - sizeof(uint32_t)); len - sizeof(uint32_t));
/* ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx)); */
/* step 4, compute the MAC */ /* step 4, compute the MAC */
poly1305_auth(tag, (uint8_t *)out_packet, len, poly1305_ctx); poly1305_auth(tag, (uint8_t *)out_packet, len, poly1305_ctx);
/* ssh_print_hexa("poly1305 src", (uint8_t *)out_packet, len);
ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN); */
}
static int chacha20_poly1305_aead_decrypt_length(
struct ssh_cipher_struct *cipher,
void *in,
uint8_t *out,
size_t len,
uint64_t seq)
{
struct chacha20_poly1305_keysched *keys = cipher->chacha20_schedule;
if (len < sizeof(uint32_t)) {
return SSH_ERROR;
}
seq = htonll(seq);
chacha_ivsetup(&keys->k1, (uint8_t *)&seq, zero_block_counter);
chacha_encrypt_bytes(&keys->k1,
in,
(uint8_t *)out,
sizeof(uint32_t));
return SSH_OK;
}
static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher,
void *complete_packet,
uint8_t *out,
size_t encrypted_size,
uint64_t seq)
{
uint8_t poly1305_ctx[POLY1305_KEYLEN] = {0};
uint8_t tag[POLY1305_TAGLEN] = {0};
struct chacha20_poly1305_keysched *keys = cipher->chacha20_schedule;
uint8_t *mac = (uint8_t *)complete_packet + sizeof(uint32_t) + encrypted_size;
int cmp;
seq = htonll(seq);
ZERO_STRUCT(poly1305_ctx);
chacha_ivsetup(&keys->k2, (uint8_t *)&seq, zero_block_counter);
chacha_encrypt_bytes(&keys->k2,
poly1305_ctx,
poly1305_ctx,
POLY1305_KEYLEN);
#if 0
ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx));
#endif
poly1305_auth(tag, (uint8_t *)complete_packet, encrypted_size +
sizeof(uint32_t), poly1305_ctx);
#if 0
ssh_print_hexa("poly1305 src",
(uint8_t*)complete_packet,
encrypted_size + 4);
ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN);
ssh_print_hexa("received tag", mac, POLY1305_TAGLEN);
#endif
cmp = memcmp(tag, mac, POLY1305_TAGLEN);
if(cmp != 0) {
/* mac error */
SSH_LOG(SSH_LOG_PACKET,"poly1305 verify error");
return SSH_ERROR;
}
chacha_ivsetup(&keys->k2, (uint8_t *)&seq, payload_block_counter);
chacha_encrypt_bytes(&keys->k2,
(uint8_t *)complete_packet + sizeof(uint32_t),
out,
encrypted_size);
return SSH_OK;
} }
const struct ssh_cipher_struct chacha20poly1305_cipher = { const struct ssh_cipher_struct chacha20poly1305_cipher = {
@@ -123,4 +197,6 @@ const struct ssh_cipher_struct chacha20poly1305_cipher = {
.set_encrypt_key = chacha20_set_encrypt_key, .set_encrypt_key = chacha20_set_encrypt_key,
.set_decrypt_key = chacha20_set_encrypt_key, .set_decrypt_key = chacha20_set_encrypt_key,
.aead_encrypt = chacha20_poly1305_aead_encrypt, .aead_encrypt = chacha20_poly1305_aead_encrypt,
.aead_decrypt_length = chacha20_poly1305_aead_decrypt_length,
.aead_decrypt = chacha20_poly1305_aead_decrypt
}; };

View File

@@ -120,7 +120,7 @@ static const char *supported_methods[] = {
KEY_EXCHANGE, KEY_EXCHANGE,
HOSTKEYS, HOSTKEYS,
CHACHA20 AES BLOWFISH DES_SUPPORTED, CHACHA20 AES BLOWFISH DES_SUPPORTED,
AES BLOWFISH DES_SUPPORTED, CHACHA20 AES BLOWFISH DES_SUPPORTED,
"hmac-sha2-256,hmac-sha2-512,hmac-sha1", "hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1", "hmac-sha2-256,hmac-sha2-512,hmac-sha1",
ZLIB, ZLIB,

View File

@@ -144,20 +144,26 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
ssh_session session= (ssh_session) user; ssh_session session= (ssh_session) user;
unsigned int blocksize = (session->current_crypto ? unsigned int blocksize = (session->current_crypto ?
session->current_crypto->in_cipher->blocksize : 8); session->current_crypto->in_cipher->blocksize : 8);
unsigned char mac[DIGEST_MAX_LEN] = {0}; unsigned int lenfield_blocksize = (session->current_crypto ?
char buffer[16] = {0}; session->current_crypto->in_cipher->lenfield_blocksize : 8);
size_t current_macsize = 0; size_t current_macsize = 0;
const uint8_t *packet; uint8_t *ptr = NULL;
int to_be_read; int to_be_read;
int rc; int rc;
uint32_t len, compsize, payloadsize; uint8_t *cleartext_packet = NULL;
uint8_t *packet_second_block = NULL;
uint8_t *mac = NULL;
size_t packet_remaining;
uint32_t packet_len, compsize, payloadsize;
uint8_t padding; uint8_t padding;
size_t processed = 0; /* number of byte processed from the callback */ size_t processed = 0; /* number of byte processed from the callback */
if(session->current_crypto != NULL) { if(session->current_crypto != NULL) {
current_macsize = hmac_digest_len(session->current_crypto->in_hmac); current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
} }
if (lenfield_blocksize == 0) {
lenfield_blocksize = blocksize;
}
if (data == NULL) { if (data == NULL) {
goto error; goto error;
} }
@@ -178,7 +184,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
#endif #endif
switch(session->packet_state) { switch(session->packet_state) {
case PACKET_STATE_INIT: case PACKET_STATE_INIT:
if (receivedlen < blocksize) { if (receivedlen < lenfield_blocksize) {
/* /*
* We didn't receive enough data to read at least one * We didn't receive enough data to read at least one
* block size, give up * block size, give up
@@ -187,7 +193,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
SSH_LOG(SSH_LOG_PACKET, SSH_LOG(SSH_LOG_PACKET,
"Waiting for more data (%zu < %zu)", "Waiting for more data (%zu < %zu)",
receivedlen, receivedlen,
blocksize); lenfield_blocksize);
#endif #endif
return 0; return 0;
} }
@@ -206,24 +212,21 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
} }
} }
memcpy(buffer, data, blocksize); ptr = ssh_buffer_allocate(session->in_buffer, lenfield_blocksize);
processed += blocksize; if (ptr == NULL) {
len = ssh_packet_decrypt_len(session, buffer);
rc = ssh_buffer_add_data(session->in_buffer, buffer, blocksize);
if (rc < 0) {
goto error; goto error;
} }
processed += lenfield_blocksize;
packet_len = ssh_packet_decrypt_len(session, ptr, (uint8_t *)data);
if (len > MAX_PACKET_LEN) { if (packet_len > MAX_PACKET_LEN) {
ssh_set_error(session, ssh_set_error(session,
SSH_FATAL, SSH_FATAL,
"read_packet(): Packet len too high(%u %.4x)", "read_packet(): Packet len too high(%u %.4x)",
len, len); packet_len, packet_len);
goto error; goto error;
} }
to_be_read = packet_len - lenfield_blocksize + sizeof(uint32_t);
to_be_read = len - blocksize + sizeof(uint32_t);
if (to_be_read < 0) { if (to_be_read < 0) {
/* remote sshd sends invalid sizes? */ /* remote sshd sends invalid sizes? */
ssh_set_error(session, ssh_set_error(session,
@@ -233,59 +236,52 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
goto error; goto error;
} }
/* Saves the status of the current operations */ session->in_packet.len = packet_len;
session->in_packet.len = len;
session->packet_state = PACKET_STATE_SIZEREAD; session->packet_state = PACKET_STATE_SIZEREAD;
FALL_THROUGH; FALL_THROUGH;
case PACKET_STATE_SIZEREAD: case PACKET_STATE_SIZEREAD:
len = session->in_packet.len; packet_len = session->in_packet.len;
to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize; processed = lenfield_blocksize;
to_be_read = packet_len + sizeof(uint32_t) + current_macsize;
/* if to_be_read is zero, the whole packet was blocksize bytes. */ /* if to_be_read is zero, the whole packet was blocksize bytes. */
if (to_be_read != 0) { if (to_be_read != 0) {
if (receivedlen - processed < (unsigned int)to_be_read) { if (receivedlen < (unsigned int)to_be_read) {
/* give up, not enough data in buffer */ /* give up, not enough data in buffer */
SSH_LOG(SSH_LOG_PACKET,"packet: partial packet (read len) [len=%d]",len); SSH_LOG(SSH_LOG_PACKET,
return processed; "packet: partial packet (read len) "
"[len=%d, receivedlen=%d, to_be_read=%d]",
packet_len,
(int)receivedlen,
to_be_read);
return 0;
} }
packet = ((uint8_t*)data) + processed; packet_second_block = (uint8_t*)data + lenfield_blocksize;
#if 0 processed = to_be_read - current_macsize;
ssh_socket_read(session->socket,
packet,
to_be_read - current_macsize);
#endif
rc = ssh_buffer_add_data(session->in_buffer,
packet,
to_be_read - current_macsize);
if (rc < 0) {
goto error;
}
processed += to_be_read - current_macsize;
} }
/* remaining encrypted bytes from the packet, MAC not included */
packet_remaining =
packet_len - (lenfield_blocksize - sizeof(uint32_t));
cleartext_packet = ssh_buffer_allocate(session->in_buffer,
packet_remaining);
if (session->current_crypto) { if (session->current_crypto) {
/* /*
* Decrypt the rest of the packet (blocksize bytes already * Decrypt the rest of the packet (lenfield_blocksize bytes already
* have been decrypted) * have been decrypted)
*/ */
uint32_t buffer_len = ssh_buffer_get_len(session->in_buffer); if (packet_remaining > 0) {
rc = ssh_packet_decrypt(session,
/* The following check avoids decrypting zero bytes */ cleartext_packet,
if (buffer_len > blocksize) { (uint8_t *)data,
uint8_t *payload = ((uint8_t*)ssh_buffer_get(session->in_buffer) + blocksize); lenfield_blocksize,
uint32_t plen = buffer_len - blocksize; processed - lenfield_blocksize);
rc = ssh_packet_decrypt(session, payload, plen);
if (rc < 0) { if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "Decrypt error"); ssh_set_error(session, SSH_FATAL, "Decryption error");
goto error; goto error;
} }
} }
mac = packet_second_block + packet_remaining;
/* copy the last part from the incoming buffer */
packet = ((uint8_t *)data) + processed;
memcpy(mac, packet, current_macsize);
rc = ssh_packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac); rc = ssh_packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac);
if (rc < 0) { if (rc < 0) {
@@ -293,6 +289,8 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
goto error; goto error;
} }
processed += current_macsize; processed += current_macsize;
} else {
memcpy(cleartext_packet, packet_second_block, packet_remaining);
} }
/* skip the size field which has been processed before */ /* skip the size field which has been processed before */
@@ -342,7 +340,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
ssh_packet_parse_type(session); ssh_packet_parse_type(session);
SSH_LOG(SSH_LOG_PACKET, SSH_LOG(SSH_LOG_PACKET,
"packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]", "packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]",
session->in_packet.type, len, padding, compsize, payloadsize); session->in_packet.type, packet_len, padding, compsize, payloadsize);
/* Execute callbacks */ /* Execute callbacks */
ssh_packet_process(session, session->in_packet.type); ssh_packet_process(session, session->in_packet.type);
@@ -353,9 +351,9 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
"Processing %" PRIdS " bytes left in socket buffer", "Processing %" PRIdS " bytes left in socket buffer",
receivedlen-processed); receivedlen-processed);
packet = ((uint8_t*)data) + processed; ptr = ((uint8_t*)data) + processed;
rc = ssh_packet_socket_callback(packet, receivedlen - processed,user); rc = ssh_packet_socket_callback(ptr, receivedlen - processed,user);
processed += rc; processed += rc;
} }
@@ -372,7 +370,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
error: error:
session->session_state= SSH_SESSION_STATE_ERROR; session->session_state= SSH_SESSION_STATE_ERROR;
SSH_LOG(SSH_LOG_PACKET,"Packet: processed %" PRIdS " bytes", processed);
return processed; return processed;
} }

View File

@@ -44,39 +44,96 @@
#include "libssh/crypto.h" #include "libssh/crypto.h"
#include "libssh/buffer.h" #include "libssh/buffer.h"
uint32_t ssh_packet_decrypt_len(ssh_session session, char *crypted){ /** @internal
* @brief decrypt the packet length from a raw encrypted packet, and store the first decrypted
* blocksize.
* @returns native byte-ordered decrypted length of the upcoming packet
*/
uint32_t ssh_packet_decrypt_len(ssh_session session,
uint8_t *destination,
uint8_t *source)
{
uint32_t decrypted; uint32_t decrypted;
int rc;
if (session->current_crypto) { if (session->current_crypto != NULL) {
if (ssh_packet_decrypt(session, crypted, if (session->current_crypto->in_cipher->aead_decrypt_length != NULL) {
session->current_crypto->in_cipher->blocksize) < 0) { rc =
session->current_crypto->in_cipher->set_decrypt_key(
session->current_crypto->in_cipher,
session->current_crypto->decryptkey,
session->current_crypto->decryptIV);
if (rc < 0) {
return (uint32_t)-1;
}
session->current_crypto->in_cipher->aead_decrypt_length(
session->current_crypto->in_cipher, source, destination,
session->current_crypto->in_cipher->lenfield_blocksize,
session->recv_seq);
} else {
rc = ssh_packet_decrypt(
session,
destination,
source,
0,
session->current_crypto->in_cipher->blocksize);
if (rc < 0) {
return 0; return 0;
} }
} }
memcpy(&decrypted,crypted,sizeof(decrypted)); } else {
memcpy(destination, source, 8);
}
memcpy(&decrypted,destination,sizeof(decrypted));
return ntohl(decrypted); return ntohl(decrypted);
} }
int ssh_packet_decrypt(ssh_session session, void *data,uint32_t len) { /** @internal
* @brief decrypts the content of an SSH packet.
* @param[source] source packet, including the encrypted length field
* @param[start] index in the packet that was not decrypted yet.
* @param[encrypted_size] size of the encrypted data to be decrypted after start.
*/
int ssh_packet_decrypt(ssh_session session,
uint8_t *destination,
uint8_t *source,
size_t start,
size_t encrypted_size)
{
struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher; struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher;
char *out = NULL; int rc;
assert(len); if (encrypted_size <= 0) {
if(len % session->current_crypto->in_cipher->blocksize != 0){
ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
return SSH_ERROR; return SSH_ERROR;
} }
out = malloc(len);
if (out == NULL) { if (encrypted_size % session->current_crypto->in_cipher->blocksize != 0) {
ssh_set_error(session,
SSH_FATAL,
"Cryptographic functions must be used on multiple of "
"blocksize (received %" PRIdS ")",
encrypted_size);
return SSH_ERROR;
}
rc = crypto->set_decrypt_key(crypto,
session->current_crypto->decryptkey,
session->current_crypto->decryptIV);
if (rc < 0) {
return -1; return -1;
} }
crypto->decrypt(crypto,data,out,len); if (crypto->aead_decrypt != NULL) {
return crypto->aead_decrypt(crypto,
source,
destination,
encrypted_size,
session->recv_seq);
} else {
crypto->decrypt(crypto, source + start, destination, encrypted_size);
}
memcpy(data,out,len);
explicit_bzero(out, len);
SAFE_FREE(out);
return 0; return 0;
} }
@@ -159,13 +216,21 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
* @return 0 if hmac and mac are equal, < 0 if not or an error * @return 0 if hmac and mac are equal, < 0 if not or an error
* occurred. * occurred.
*/ */
int ssh_packet_hmac_verify(ssh_session session, ssh_buffer buffer, int ssh_packet_hmac_verify(ssh_session session,
unsigned char *mac, enum ssh_hmac_e type) { ssh_buffer buffer,
uint8_t *mac,
enum ssh_hmac_e type)
{
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0}; unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
HMACCTX ctx; HMACCTX ctx;
unsigned int len; unsigned int len;
uint32_t seq; uint32_t seq;
/* AEAD type have no mac checking */
if (type == SSH_HMAC_AEAD_POLY1305) {
return SSH_OK;
}
ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type); ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type);
if (ctx == NULL) { if (ctx == NULL) {
return -1; return -1;
@@ -188,5 +253,3 @@ int ssh_packet_hmac_verify(ssh_session session, ssh_buffer buffer,
return -1; return -1;
} }
/* vim: set ts=2 sw=2 et cindent: */

View File

@@ -231,8 +231,13 @@ static int crypt_set_algorithms2(ssh_session session){
int i = 0; int i = 0;
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab(); struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab(); struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
int cmp;
/*
* We must scan the kex entries to find crypto algorithms and set their
* appropriate structure.
*/
/* we must scan the kex entries to find crypto algorithms and set their appropriate structure */
/* out */ /* out */
wanted = session->next_crypto->kex_methods[SSH_CRYPT_C_S]; wanted = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) { while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) {
@@ -258,12 +263,20 @@ static int crypt_set_algorithms2(ssh_session session){
/* this cipher has integrated MAC */ /* this cipher has integrated MAC */
wanted = "aead-poly1305"; wanted = "aead-poly1305";
} else { } else {
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */ /*
* We must scan the kex entries to find hmac algorithms and set their
* appropriate structure.
*/
/* out */ /* out */
wanted = session->next_crypto->kex_methods[SSH_MAC_C_S]; wanted = session->next_crypto->kex_methods[SSH_MAC_C_S];
} }
while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) {
i++; for (i = 0; ssh_hmactab[i].name != NULL; i++) {
cmp = strcmp(wanted, ssh_hmactab[i].name);
if (cmp == 0) {
break;
}
} }
if (ssh_hmactab[i].name == NULL) { if (ssh_hmactab[i].name == NULL) {
@@ -275,12 +288,15 @@ static int crypt_set_algorithms2(ssh_session session){
SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted); SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted);
session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type; session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
i = 0;
/* in */ /* in */
wanted = session->next_crypto->kex_methods[SSH_CRYPT_S_C]; wanted = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) {
i++; for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
cmp = strcmp(wanted, ssh_ciphertab[i].name);
if (cmp == 0) {
break;
}
} }
if (ssh_ciphertab[i].name == NULL) { if (ssh_ciphertab[i].name == NULL) {
@@ -296,12 +312,20 @@ static int crypt_set_algorithms2(ssh_session session){
ssh_set_error_oom(session); ssh_set_error_oom(session);
return SSH_ERROR; return SSH_ERROR;
} }
i = 0;
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
/* this cipher has integrated MAC */
wanted = "aead-poly1305";
} else {
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */ /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
wanted = session->next_crypto->kex_methods[SSH_MAC_S_C]; wanted = session->next_crypto->kex_methods[SSH_MAC_S_C];
while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) { }
i++;
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
cmp = strcmp(wanted, ssh_hmactab[i].name);
if (cmp == 0) {
break;
}
} }
if (ssh_hmactab[i].name == NULL) { if (ssh_hmactab[i].name == NULL) {
@@ -310,7 +334,7 @@ static int crypt_set_algorithms2(ssh_session session){
wanted); wanted);
return SSH_ERROR; return SSH_ERROR;
} }
SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted); SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", wanted);
session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type; session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
i = 0; i = 0;
@@ -458,7 +482,13 @@ int crypt_set_algorithms_server(ssh_session session){
} }
i=0; i=0;
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
/* this cipher has integrated MAC */
method = "aead-poly1305";
} else {
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
method = session->next_crypto->kex_methods[SSH_MAC_C_S]; method = session->next_crypto->kex_methods[SSH_MAC_C_S];
}
for (i = 0; ssh_hmactab[i].name != NULL; i++) { for (i = 0; ssh_hmactab[i].name != NULL; i++) {
int cmp; int cmp;