1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-12 15:41:16 +03:00

Update HMAC function parameter type

New openssl API, libmbedtls, libgcrypt use size_t for
HMAC len pameter.

New helper functions were added in libcrypto.c to avoid
code duplication. (the header pki.h is needed for this
reason)

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Norbert Pocs
2022-06-23 15:33:05 +00:00
committed by Andreas Schneider
parent 51c940adc9
commit debd0ea4d3
8 changed files with 328 additions and 50 deletions

View File

@@ -80,7 +80,7 @@ int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *sourc
size_t start, size_t encrypted_size);
unsigned char *ssh_packet_encrypt(ssh_session session,
void *packet,
uint32_t len);
size_t len);
int ssh_packet_hmac_verify(ssh_session session, const void *data, size_t len,
unsigned char *mac, enum ssh_hmac_e type);
int ssh_packet_set_newkeys(ssh_session session,

View File

@@ -96,9 +96,9 @@ EVPCTX evp_init(int nid);
void evp_update(EVPCTX ctx, const void *data, size_t len);
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen);
HMACCTX hmac_init(const void *key, size_t len, enum ssh_hmac_e type);
void hmac_update(HMACCTX c, const void *data, size_t len);
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
HMACCTX hmac_init(const void *key,size_t len, enum ssh_hmac_e type);
int hmac_update(HMACCTX c, const void *data, size_t len);
int hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, size_t *len);
size_t hmac_digest_len(enum ssh_hmac_e type);
int ssh_kdf(struct ssh_crypto_struct *crypto,
@@ -120,4 +120,11 @@ struct ssh_hmac_struct *ssh_get_hmactab(void);
struct ssh_cipher_struct *ssh_get_ciphertab(void);
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type, bool etm);
#if defined(HAVE_LIBCRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
int evp_build_pkey(const char* name, OSSL_PARAM_BLD *param_bld, EVP_PKEY **pkey, int selection);
int evp_dup_dsa_pkey(const ssh_key key, ssh_key new, int demote);
int evp_dup_rsa_pkey(const ssh_key key, ssh_key new, int demote);
int evp_dup_ecdsa_pkey(const ssh_key key, ssh_key new, int demote);
#endif /* HAVE_LIBCRYPTO && OPENSSL_VERSION_NUMBER */
#endif /* WRAPPER_H_ */

View File

@@ -210,8 +210,8 @@ static int match_hashed_host(const char *host, const char *sourcehash)
HMACCTX mac;
char *source;
char *b64hash;
int match;
unsigned int size;
int match, rc;
size_t size;
if (strncmp(sourcehash, "|1|", 3) != 0) {
return 0;
@@ -256,8 +256,20 @@ static int match_hashed_host(const char *host, const char *sourcehash)
return 0;
}
size = sizeof(buffer);
hmac_update(mac, host, strlen(host));
hmac_final(mac, buffer, &size);
rc = hmac_update(mac, host, strlen(host));
if (rc != 1) {
ssh_buffer_free(salt);
ssh_buffer_free(hash);
return 0;
}
rc = hmac_final(mac, buffer, &size);
if (rc != 1) {
ssh_buffer_free(salt);
ssh_buffer_free(hash);
return 0;
}
if (size == ssh_buffer_get_len(hash) &&
memcmp(buffer, ssh_buffer_get(hash), size) == 0) {

View File

@@ -58,8 +58,9 @@ static int hash_hostname(const char *name,
unsigned char *salt,
unsigned int salt_size,
unsigned char **hash,
unsigned int *hash_size)
size_t *hash_size)
{
int rc;
HMACCTX mac_ctx;
mac_ctx = hmac_init(salt, salt_size, SSH_HMAC_SHA1);
@@ -67,8 +68,13 @@ static int hash_hostname(const char *name,
return SSH_ERROR;
}
hmac_update(mac_ctx, name, strlen(name));
hmac_final(mac_ctx, *hash, hash_size);
rc = hmac_update(mac_ctx, name, strlen(name));
if (rc != 1)
return SSH_ERROR;
rc = hmac_final(mac_ctx, *hash, hash_size);
if (rc != 1)
return SSH_ERROR;
return SSH_OK;
}
@@ -81,7 +87,7 @@ static int match_hashed_hostname(const char *host, const char *hashed_host)
ssh_buffer hash = NULL;
unsigned char hashed_buf[256] = {0};
unsigned char *hashed_buf_ptr = hashed_buf;
unsigned int hashed_buf_size = sizeof(hashed_buf);
size_t hashed_buf_size = sizeof(hashed_buf);
int cmp;
int rc;
int match = 0;

View File

@@ -26,13 +26,14 @@
#include <string.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#endif /* HAVE_SYS_TIME_H */
#include "libssh/priv.h"
#include "libssh/session.h"
#include "libssh/crypto.h"
#include "libssh/wrapper.h"
#include "libssh/libcrypto.h"
#include "libssh/pki.h"
#if defined(HAVE_OPENSSL_EVP_CHACHA20) && defined(HAVE_OPENSSL_EVP_POLY1305)
#include "libssh/bytearray.h"
#include "libssh/chacha20-poly1305-common.h"
@@ -40,12 +41,17 @@
#ifdef HAVE_LIBCRYPTO
#include <openssl/opensslv.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
#if OPENSSL_VERSION_NUMBER < 0x30000000L
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/hmac.h>
#include <openssl/opensslv.h>
#else
#include <openssl/param_build.h>
#include <openssl/core_names.h>
#endif /* OPENSSL_VERSION_NUMBER */
#include <openssl/rand.h>
#include <openssl/engine.h>
@@ -54,11 +60,11 @@
#ifdef HAVE_OPENSSL_AES_H
#define HAS_AES
#include <openssl/aes.h>
#endif
#endif /* HAVE_OPENSSL_AES_H */
#ifdef HAVE_OPENSSL_DES_H
#define HAS_DES
#include <openssl/des.h>
#endif
#endif /* HAVE_OPENSSL_DES_H */
#if (defined(HAVE_VALGRIND_VALGRIND_H) && defined(HAVE_OPENSSL_IA32CAP_LOC))
#include <valgrind/valgrind.h>
@@ -200,7 +206,7 @@ void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
EVP_DigestFinal(ctx, md, mdlen);
EVP_MD_CTX_free(ctx);
}
#endif
#endif /* HAVE_OPENSSL_ECC */
SHA256CTX sha256_init(void)
{
@@ -414,8 +420,7 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
return sshkdf_derive_key(crypto, key, key_len,
key_type, output, requested_len);
}
#endif
#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */
HMACCTX hmac_init(const void *key, size_t len, enum ssh_hmac_e type)
{
HMACCTX ctx = NULL;
@@ -461,17 +466,22 @@ error:
return NULL;
}
void hmac_update(HMACCTX ctx, const void *data, size_t len)
int hmac_update(HMACCTX ctx, const void *data, size_t len)
{
EVP_DigestSignUpdate(ctx, data, len);
return EVP_DigestSignUpdate(ctx, data, len);
}
void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len)
int hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, size_t *len)
{
size_t res = 0;
EVP_DigestSignFinal(ctx, hashmacbuf, &res);
size_t res = *len;
int rc;
rc = EVP_DigestSignFinal(ctx, hashmacbuf, &res);
EVP_MD_CTX_free(ctx);
*len = res;
if (rc == 1) {
*len = res;
}
return rc;
}
static void evp_cipher_init(struct ssh_cipher_struct *cipher)
@@ -515,7 +525,7 @@ static void evp_cipher_init(struct ssh_cipher_struct *cipher)
cipher->cipher = EVP_bf_cbc();
break;
/* ciphers not using EVP */
#endif
#endif /* WITH_BLOWFISH_CIPHER */
case SSH_AEAD_CHACHA20_POLY1305:
SSH_LOG(SSH_LOG_WARNING, "The ChaCha cipher cannot be handled here");
break;
@@ -822,12 +832,17 @@ struct chacha20_poly1305_keysched {
EVP_CIPHER_CTX *main_evp;
/* cipher handle used for encrypting the length field */
EVP_CIPHER_CTX *header_evp;
#if OPENSSL_VERSION_NUMBER < 0x30000000L
/* mac handle used for authenticating the packets */
EVP_PKEY_CTX *pctx;
/* Poly1305 key */
EVP_PKEY *key;
/* MD context for digesting data in poly1305 */
EVP_MD_CTX *mctx;
#else
/* MAC context used to do poly1305 */
EVP_MAC_CTX *mctx;
#endif /* OPENSSL_VERSION_NUMBER */
};
static void
@@ -845,11 +860,16 @@ chacha20_poly1305_cleanup(struct ssh_cipher_struct *cipher)
ctx->main_evp = NULL;
EVP_CIPHER_CTX_free(ctx->header_evp);
ctx->header_evp = NULL;
#if OPENSSL_VERSION_NUMBER < 0x30000000L
/* ctx->pctx is freed as part of MD context */
EVP_PKEY_free(ctx->key);
ctx->key = NULL;
EVP_MD_CTX_free(ctx->mctx);
ctx->mctx = NULL;
#else
EVP_MAC_CTX_free(ctx->mctx);
ctx->mctx = NULL;
#endif /* OPENSSL_VERSION_NUMBER */
SAFE_FREE(cipher->chacha20_schedule);
}
@@ -862,6 +882,9 @@ chacha20_poly1305_set_key(struct ssh_cipher_struct *cipher,
struct chacha20_poly1305_keysched *ctx = NULL;
uint8_t *u8key = key;
int ret = SSH_ERROR, rv;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MAC *mac = NULL;
#endif
if (cipher->chacha20_schedule == NULL) {
ctx = calloc(1, sizeof(*ctx));
@@ -901,14 +924,30 @@ chacha20_poly1305_set_key(struct ssh_cipher_struct *cipher,
/* The Poly1305 key initialization is delayed to the time we know
* the actual key for packet so we do not need to create a bogus keys
*/
#if OPENSSL_VERSION_NUMBER < 0x30000000L
ctx->mctx = EVP_MD_CTX_new();
if (ctx->mctx == NULL) {
SSH_LOG(SSH_LOG_WARNING, "EVP_MD_CTX_new failed");
return SSH_ERROR;
}
#else
mac = EVP_MAC_fetch(NULL, "poly1305", NULL);
if (mac == NULL) {
SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_fetch failed");
goto out;
}
ctx->mctx = EVP_MAC_CTX_new(mac);
if (ctx->mctx == NULL) {
SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_CTX_new failed");
goto out;
}
#endif /* OPENSSL_VERSION_NUMBER */
ret = SSH_OK;
out:
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MAC_free(mac);
#endif
if (ret != SSH_OK) {
chacha20_poly1305_cleanup(cipher);
}
@@ -980,6 +1019,7 @@ chacha20_poly1305_packet_setup(struct ssh_cipher_struct *cipher,
#endif /* DEBUG_CRYPTO */
/* Set the Poly1305 key */
#if OPENSSL_VERSION_NUMBER < 0x30000000L
if (ctx->key == NULL) {
/* Poly1305 Initialization needs to know the actual key */
ctx->key = EVP_PKEY_new_mac_key(EVP_PKEY_POLY1305, NULL,
@@ -1003,6 +1043,13 @@ chacha20_poly1305_packet_setup(struct ssh_cipher_struct *cipher,
goto out;
}
}
#else
rv = EVP_MAC_init(ctx->mctx, poly_key, POLY1305_KEYLEN, NULL);
if (rv != 1) {
SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_init failed");
goto out;
}
#endif /* OPENSSL_VERSION_NUMBER */
ret = SSH_OK;
out:
@@ -1080,6 +1127,7 @@ chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher,
#endif /* DEBUG_CRYPTO */
/* Calculate MAC of received data */
#if OPENSSL_VERSION_NUMBER < 0x30000000L
rv = EVP_DigestSignUpdate(ctx->mctx, complete_packet,
encrypted_size + sizeof(uint32_t));
if (rv != 1) {
@@ -1092,6 +1140,20 @@ chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher,
SSH_LOG(SSH_LOG_WARNING, "poly1305 verify error");
goto out;
}
#else
rv = EVP_MAC_update(ctx->mctx, complete_packet,
encrypted_size + sizeof(uint32_t));
if (rv != 1) {
SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_update failed");
goto out;
}
rv = EVP_MAC_final(ctx->mctx, tag, &taglen, POLY1305_TAGLEN);
if (rv != 1) {
SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_final failed");
goto out;
}
#endif /* OPENSSL_VERSION_NUMBER */
#ifdef DEBUG_CRYPTO
ssh_log_hexdump("calculated mac", tag, POLY1305_TAGLEN);
@@ -1182,6 +1244,7 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
}
/* step 4, compute the MAC */
#if OPENSSL_VERSION_NUMBER < 0x30000000L
ret = EVP_DigestSignUpdate(ctx->mctx, out_packet, len);
if (ret <= 0) {
SSH_LOG(SSH_LOG_WARNING, "EVP_DigestSignUpdate failed");
@@ -1192,6 +1255,19 @@ chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
SSH_LOG(SSH_LOG_WARNING, "EVP_DigestSignFinal failed");
return;
}
#else
ret = EVP_MAC_update(ctx->mctx, (void*)out_packet, len);
if (ret != 1) {
SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_update failed");
return;
}
ret = EVP_MAC_final(ctx->mctx, tag, &taglen, POLY1305_TAGLEN);
if (ret != 1) {
SSH_LOG(SSH_LOG_WARNING, "EVP_MAC_final failed");
return;
}
#endif /* OPENSSL_VERSION_NUMBER */
}
#endif /* defined(HAVE_OPENSSL_EVP_CHACHA20) && defined(HAVE_OPENSSL_EVP_POLY1305) */
@@ -1222,7 +1298,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.decrypt = evp_cipher_decrypt,
.cleanup = evp_cipher_cleanup
},
#endif
#endif /* WITH_BLOWFISH_CIPHER */
#ifdef HAS_AES
{
.name = "aes128-ctr",
@@ -1398,10 +1474,10 @@ int ssh_crypto_init(void)
/* Bit #57 denotes AES-NI instruction set extension */
OPENSSL_ia32cap &= ~(1LL << 57);
}
#endif
#endif /* CAN_DISABLE_AESNI */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
OpenSSL_add_all_algorithms();
#endif
#endif /* OPENSSL_VERSION_NUMBER */
#if !defined(HAVE_OPENSSL_EVP_CHACHA20) || !defined(HAVE_OPENSSL_EVP_POLY1305)
for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
@@ -1436,9 +1512,151 @@ void ssh_crypto_finalize(void)
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
#endif
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
libcrypto_initialized = 0;
}
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
/**
* @internal
* @brief Create EVP_PKEY from parameters
*
* @param[in] name Algorithm to use. For more info see manpage of EVP_PKEY_CTX_new_from_name
*
* @param[in] param_bld Constructed param builder for the pkey
*
* @param[out] pkey Created EVP_PKEY variable
*
* @param[in] selection Reference selections at man EVP_PKEY_FROMDATA
*
* @return 0 on success, -1 on error
*/
int evp_build_pkey(const char* name, OSSL_PARAM_BLD *param_bld,
EVP_PKEY **pkey, int selection)
{
int rc;
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
OSSL_PARAM *params = NULL;
if (ctx == NULL) {
return -1;
}
params = OSSL_PARAM_BLD_to_param(param_bld);
if (params == NULL) {
EVP_PKEY_CTX_free(ctx);
return -1;
}
rc = EVP_PKEY_fromdata_init(ctx);
if (rc != 1) {
OSSL_PARAM_free(params);
EVP_PKEY_CTX_free(ctx);
return -1;
}
rc = EVP_PKEY_fromdata(ctx, pkey, selection, params);
if (rc != 1) {
OSSL_PARAM_free(params);
EVP_PKEY_CTX_free(ctx);
return -1;
}
OSSL_PARAM_free(params);
EVP_PKEY_CTX_free(ctx);
return SSH_OK;
}
/**
* @brief creates a copy of EVP_PKEY
*
* @param[in] name Algorithm to use. For more info see manpage of
* EVP_PKEY_CTX_new_from_name
*
* @param[in] key Key being duplicated from
*
* @param[in] demote Same as at pki_key_dup, only the public
* part of the key gets duplicated if true
*
* @param[out] new_key The key where the duplicate is saved
*
* @return 0 on success, -1 on error
*/
static int evp_dup_pkey(const char* name, const ssh_key key, int demote,
ssh_key new_key)
{
int rc;
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
OSSL_PARAM *params = NULL;
if (ctx == NULL) {
return -1;
}
if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) {
rc = EVP_PKEY_todata(key->key, EVP_PKEY_KEYPAIR, &params);
if (rc != 1) {
EVP_PKEY_CTX_free(ctx);
return -1;
}
rc = EVP_PKEY_fromdata_init(ctx);
if (rc != 1) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
return -1;
}
rc = EVP_PKEY_fromdata(ctx, &(new_key->key), EVP_PKEY_KEYPAIR, params);
if (rc != 1) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
return -1;
}
} else {
rc = EVP_PKEY_todata(key->key, EVP_PKEY_PUBLIC_KEY, &params);
if (rc != 1) {
EVP_PKEY_CTX_free(ctx);
return -1;
}
rc = EVP_PKEY_fromdata_init(ctx);
if (rc != 1) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
return -1;
}
rc = EVP_PKEY_fromdata(ctx, &(new_key->key), EVP_PKEY_PUBLIC_KEY, params);
if (rc != 1) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
return -1;
}
}
OSSL_PARAM_free(params);
EVP_PKEY_CTX_free(ctx);
return SSH_OK;
}
int evp_dup_dsa_pkey(const ssh_key key, ssh_key new, int demote)
{
return evp_dup_pkey("DSA", key, demote, new);
}
int evp_dup_rsa_pkey(const ssh_key key, ssh_key new, int demote)
{
return evp_dup_pkey("RSA", key, demote, new);
}
int evp_dup_ecdsa_pkey(const ssh_key key, ssh_key new, int demote)
{
return evp_dup_pkey("EC", key, demote, new);
}
#endif /* OPENSSL_VERSION_NUMBER */
#endif /* LIBCRYPTO */

View File

@@ -268,14 +268,20 @@ HMACCTX hmac_init(const void *key, size_t len, enum ssh_hmac_e type) {
return c;
}
void hmac_update(HMACCTX c, const void *data, size_t len) {
int hmac_update(HMACCTX c, const void *data, size_t len) {
gcry_md_write(c, data, len);
return 1;
}
void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len) {
*len = gcry_md_get_algo_dlen(gcry_md_get_algo(c));
int hmac_final(HMACCTX c, unsigned char *hashmacbuf, size_t *len) {
unsigned int tmp = gcry_md_get_algo_dlen(gcry_md_get_algo(c));
if (tmp > SIZE_MAX) {
return 0;
}
*len = (size_t)tmp;
memcpy(hashmacbuf, gcry_md_read(c, 0), *len);
gcry_md_close(c);
return 1;
}
#ifdef WITH_BLOWFISH_CIPHER

View File

@@ -447,17 +447,21 @@ error:
return NULL;
}
void hmac_update(HMACCTX c, const void *data, size_t len)
/* mbedtls returns 0 on success, but in this context
* success is 1 */
int hmac_update(HMACCTX c, const void *data, size_t len)
{
mbedtls_md_hmac_update(c, data, len);
return !mbedtls_md_hmac_update(c, data, len);
}
void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len)
int hmac_final(HMACCTX c, unsigned char *hashmacbuf, size_t *len)
{
*len = mbedtls_md_get_size(c->MBEDTLS_PRIVATE(md_info));
mbedtls_md_hmac_finish(c, hashmacbuf);
int rc;
*len = (unsigned int)mbedtls_md_get_size(c->md_info);
rc = !mbedtls_md_hmac_finish(c, hashmacbuf);
mbedtls_md_free(c);
SAFE_FREE(c);
return rc;
}
static int

View File

@@ -130,14 +130,15 @@ int ssh_packet_decrypt(ssh_session session,
return 0;
}
unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
unsigned char *ssh_packet_encrypt(ssh_session session, void *data, size_t len)
{
struct ssh_crypto_struct *crypto = NULL;
struct ssh_cipher_struct *cipher = NULL;
HMACCTX ctx = NULL;
char *out = NULL;
int etm_packet_offset = 0;
unsigned int finallen, blocksize;
int etm_packet_offset = 0, rc;
unsigned int blocksize;
size_t finallen = DIGEST_MAX_LEN;
uint32_t seq, lenfield_blocksize;
enum ssh_hmac_e type;
bool etm;
@@ -161,7 +162,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
if ((len - lenfield_blocksize - etm_packet_offset) % blocksize != 0) {
ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set"
" on at least one blocksize (received %d)", len);
" on at least one blocksize (received %zu)", len);
return NULL;
}
out = calloc(1, len);
@@ -185,9 +186,21 @@ 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);
rc = hmac_update(ctx, (unsigned char *)&seq, sizeof(uint32_t));
if (rc != 1) {
SAFE_FREE(out);
return NULL;
}
rc = hmac_update(ctx, data, len);
if (rc != 1) {
SAFE_FREE(out);
return NULL;
}
rc = hmac_final(ctx, crypto->hmacbuf, &finallen);
if (rc != 1) {
SAFE_FREE(out);
return NULL;
}
}
}
@@ -197,14 +210,26 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
if (type != SSH_HMAC_NONE) {
if (etm) {
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);
rc = hmac_update(ctx, (unsigned char *)&seq, sizeof(uint32_t));
if (rc != 1) {
SAFE_FREE(out);
return NULL;
}
rc = hmac_update(ctx, data, len);
if (rc != 1) {
SAFE_FREE(out);
return NULL;
}
rc = hmac_final(ctx, crypto->hmacbuf, &finallen);
if (rc != 1) {
SAFE_FREE(out);
return NULL;
}
}
#ifdef DEBUG_CRYPTO
ssh_log_hexdump("mac: ", data, len);
if (finallen != hmac_digest_len(type)) {
printf("Final len is %d\n", finallen);
printf("Final len is %zu\n", finallen);
}
ssh_log_hexdump("Packet hmac", crypto->hmacbuf, hmac_digest_len(type));
#endif
@@ -238,7 +263,7 @@ int ssh_packet_hmac_verify(ssh_session session,
struct ssh_crypto_struct *crypto = NULL;
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
HMACCTX ctx;
unsigned int hmaclen;
size_t hmaclen = DIGEST_MAX_LEN;
uint32_t seq;
/* AEAD types have no mac checking */