1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-07-02 22:02:25 +03:00

mac: handle low-level errors

- update low-level hmac functions from macros to functions.
- libgcrypt: propagate low-level hmac errors.
- libgcrypt: add error checks for hmac calls.
- os400qc3: add error checks, propagate them.
  Assisted-by: Patrick Monnerat
- mbedtls: fix propagating low-level hmac errors.
- wincng: fix propagating low-level hmac errors.
- mac: verify success of low-level hmac functions.
- knownhost: verify success of low-level hmac functions.
- transport: verify success of MAC hash call.
- minor type cleanup in wincng.
- delete unused ripemd wrapper in wincng.
- delete unused SHA384 wrapper in mbedtls.

Reported-by: Paul Howarth
Reviewed-by: Michael Buckley
Closes #1297
This commit is contained in:
Viktor Szakats
2023-12-22 12:12:21 +00:00
parent f52ffc1ccd
commit f64885b6ab
16 changed files with 583 additions and 331 deletions

View File

@ -63,27 +63,21 @@ libssh2_hmac_ctx
Type of an HMAC computation context. Generally a struct. Type of an HMAC computation context. Generally a struct.
Used for all hash algorithms. Used for all hash algorithms.
void libssh2_hmac_ctx_init(libssh2_hmac_ctx ctx); int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx);
Initializes the HMAC computation context ctx. Initializes the HMAC computation context ctx.
Called before setting-up the hash algorithm. Called before setting-up the hash algorithm.
Note: if the ctx parameter is modified by the underlying code, Must return 1 for success and 0 for failure.
this procedure must be implemented as a macro to map ctx --> &ctx.
void libssh2_hmac_update(libssh2_hmac_ctx ctx, int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const unsigned char *data, const void *data, int datalen);
int datalen);
Continue computation of an HMAC on datalen bytes at data using context ctx. Continue computation of an HMAC on datalen bytes at data using context ctx.
Note: if the ctx parameter is modified by the underlying code,
this procedure must be implemented as a macro to map ctx --> &ctx.
void libssh2_hmac_final(libssh2_hmac_ctx ctx, int _libssh2_hmac_final(libssh2_hmac_ctx *ctx,
unsigned char output[]); void output[]);
Get the computed HMAC from context ctx into the output buffer. The Get the computed HMAC from context ctx into the output buffer. The
minimum data buffer size depends on the HMAC hash algorithm. minimum data buffer size depends on the HMAC hash algorithm.
Note: if the ctx parameter is modified by the underlying code,
this procedure must be implemented as a macro to map ctx --> &ctx.
void libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx); void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx);
Releases the HMAC computation context at ctx. Releases the HMAC computation context at ctx.

View File

@ -587,6 +587,7 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_RANDGEN -49 #define LIBSSH2_ERROR_RANDGEN -49
#define LIBSSH2_ERROR_MISSING_USERAUTH_BANNER -50 #define LIBSSH2_ERROR_MISSING_USERAUTH_BANNER -50
#define LIBSSH2_ERROR_ALGO_UNSUPPORTED -51 #define LIBSSH2_ERROR_ALGO_UNSUPPORTED -51
#define LIBSSH2_ERROR_MAC_FAILURE -52
/* this is a define to provide the old (<= 1.2.7) name */ /* this is a define to provide the old (<= 1.2.7) name */
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV #define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV

View File

@ -55,6 +55,27 @@
#error "no cryptography backend selected" #error "no cryptography backend selected"
#endif #endif
/* return: success = 1, error = 0 */
int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx);
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
#endif
#if LIBSSH2_HMAC_RIPEMD
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen);
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data);
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx);
#define LIBSSH2_ED25519_KEY_LEN 32 #define LIBSSH2_ED25519_KEY_LEN 32
#define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64 #define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64
#define LIBSSH2_ED25519_SIG_LEN 64 #define LIBSSH2_ED25519_SIG_LEN 64

View File

@ -421,19 +421,23 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
*/ */
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
libssh2_hmac_ctx_init(ctx); if(!_libssh2_hmac_ctx_init(&ctx))
break;
if(SHA_DIGEST_LENGTH != node->name_len) { if(SHA_DIGEST_LENGTH != node->name_len) {
/* the name hash length must be the sha1 size or /* the name hash length must be the sha1 size or
we can't match it */ we can't match it */
break; break;
} }
libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt, if(!_libssh2_hmac_sha1_init(&ctx,
node->salt_len); node->salt, node->salt_len))
libssh2_hmac_update(ctx, (unsigned char *)host, break;
strlen(host)); if(!_libssh2_hmac_update(&ctx, host, strlen(host)) ||
libssh2_hmac_final(ctx, hash); !_libssh2_hmac_final(&ctx, hash)) {
libssh2_hmac_cleanup(&ctx); _libssh2_hmac_cleanup(&ctx);
break;
}
_libssh2_hmac_cleanup(&ctx);
if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH)) if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH))
/* this is a node we're interested in */ /* this is a node we're interested in */

View File

@ -40,6 +40,105 @@
#ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */ #ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */
int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
{
*ctx = NULL;
return 1;
}
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
#endif
#if LIBSSH2_HMAC_RIPEMD
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen)
{
gcry_md_write(*ctx, data, datalen);
return 1;
}
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
{
unsigned char *res = gcry_md_read(*ctx, 0);
if(!res)
return 0;
memcpy(data, res, gcry_md_get_algo_dlen(gcry_md_get_algo(*ctx)));
return 1;
}
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
{
gcry_md_close(*ctx);
}
#if LIBSSH2_RSA #if LIBSSH2_RSA
int int
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa, _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,

View File

@ -144,30 +144,6 @@
#endif #endif
#define libssh2_hmac_ctx gcry_md_hd_t #define libssh2_hmac_ctx gcry_md_hd_t
#define libssh2_hmac_ctx_init(ctx)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey(*ctx, key, keylen)
#if LIBSSH2_MD5
#define libssh2_hmac_md5_init(ctx, key, keylen) \
gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey(*ctx, key, keylen)
#endif
#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) \
memcpy(data, gcry_md_read(ctx, 0), \
gcry_md_get_algo_dlen(gcry_md_get_algo(ctx)))
#define libssh2_hmac_cleanup(ctx) gcry_md_close(*ctx)
#define libssh2_crypto_init() gcry_control(GCRYCTL_DISABLE_SECMEM) #define libssh2_crypto_init() gcry_control(GCRYCTL_DISABLE_SECMEM)
#define libssh2_crypto_exit() #define libssh2_crypto_exit()

126
src/mac.c
View File

@ -124,23 +124,27 @@ mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,
{ {
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
int res;
(void)session; (void)session;
_libssh2_htonu32(seqno_buf, seqno); _libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx); if(!_libssh2_hmac_ctx_init(&ctx))
libssh2_hmac_sha512_init(&ctx, *abstract, 64); return 1;
libssh2_hmac_update(ctx, seqno_buf, 4); res = _libssh2_hmac_sha512_init(&ctx, *abstract, 64) &&
libssh2_hmac_update(ctx, packet, packet_len); _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
if(addtl && addtl_len) { _libssh2_hmac_update(&ctx, packet, packet_len);
libssh2_hmac_update(ctx, addtl, addtl_len); if(res && addtl && addtl_len)
} res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
libssh2_hmac_final(ctx, buf); if(res)
libssh2_hmac_cleanup(&ctx); res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0; return !res;
} }
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = { static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = {
"hmac-sha2-512", "hmac-sha2-512",
64, 64,
@ -179,21 +183,23 @@ mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,
{ {
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
int res;
(void)session; (void)session;
_libssh2_htonu32(seqno_buf, seqno); _libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx); if(!_libssh2_hmac_ctx_init(&ctx))
libssh2_hmac_sha256_init(&ctx, *abstract, 32); return 1;
libssh2_hmac_update(ctx, seqno_buf, 4); res = _libssh2_hmac_sha256_init(&ctx, *abstract, 32) &&
libssh2_hmac_update(ctx, packet, packet_len); _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
if(addtl && addtl_len) { _libssh2_hmac_update(&ctx, packet, packet_len);
libssh2_hmac_update(ctx, addtl, addtl_len); if(res && addtl && addtl_len)
} res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
libssh2_hmac_final(ctx, buf); if(res)
libssh2_hmac_cleanup(&ctx); res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0; return !res;
} }
@ -236,21 +242,23 @@ mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
{ {
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
int res;
(void)session; (void)session;
_libssh2_htonu32(seqno_buf, seqno); _libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx); if(!_libssh2_hmac_ctx_init(&ctx))
libssh2_hmac_sha1_init(&ctx, *abstract, 20); return 1;
libssh2_hmac_update(ctx, seqno_buf, 4); res = _libssh2_hmac_sha1_init(&ctx, *abstract, 20) &&
libssh2_hmac_update(ctx, packet, packet_len); _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
if(addtl && addtl_len) { _libssh2_hmac_update(&ctx, packet, packet_len);
libssh2_hmac_update(ctx, addtl, addtl_len); if(res && addtl && addtl_len)
} res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
libssh2_hmac_final(ctx, buf); if(res)
libssh2_hmac_cleanup(&ctx); res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0; return !res;
} }
@ -288,10 +296,11 @@ mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
{ {
unsigned char temp[SHA_DIGEST_LENGTH]; unsigned char temp[SHA_DIGEST_LENGTH];
mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, if(mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract); addtl, addtl_len, abstract))
memcpy(buf, (char *) temp, 96 / 8); return 1;
memcpy(buf, (char *) temp, 96 / 8);
return 0; return 0;
} }
@ -321,21 +330,23 @@ mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
{ {
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
int res;
(void)session; (void)session;
_libssh2_htonu32(seqno_buf, seqno); _libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx); if(!_libssh2_hmac_ctx_init(&ctx))
libssh2_hmac_md5_init(&ctx, *abstract, 16); return 1;
libssh2_hmac_update(ctx, seqno_buf, 4); res = _libssh2_hmac_md5_init(&ctx, *abstract, 16) &&
libssh2_hmac_update(ctx, packet, packet_len); _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
if(addtl && addtl_len) { _libssh2_hmac_update(&ctx, packet, packet_len);
libssh2_hmac_update(ctx, addtl, addtl_len); if(res && addtl && addtl_len)
} res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
libssh2_hmac_final(ctx, buf); if(res)
libssh2_hmac_cleanup(&ctx); res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0; return !res;
} }
@ -362,8 +373,11 @@ mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
size_t addtl_len, void **abstract) size_t addtl_len, void **abstract)
{ {
unsigned char temp[MD5_DIGEST_LENGTH]; unsigned char temp[MD5_DIGEST_LENGTH];
mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract); if(mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract))
return 1;
memcpy(buf, (char *) temp, 96 / 8); memcpy(buf, (char *) temp, 96 / 8);
return 0; return 0;
} }
@ -396,21 +410,23 @@ mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
{ {
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
int res;
(void)session; (void)session;
_libssh2_htonu32(seqno_buf, seqno); _libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx); if(!_libssh2_hmac_ctx_init(&ctx))
libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); return 1;
libssh2_hmac_update(ctx, seqno_buf, 4); res = _libssh2_hmac_ripemd160_init(&ctx, *abstract, 20) &&
libssh2_hmac_update(ctx, packet, packet_len); _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
if(addtl && addtl_len) { _libssh2_hmac_update(&ctx, packet, packet_len);
libssh2_hmac_update(ctx, addtl, addtl_len); if(res && addtl && addtl_len)
} res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
libssh2_hmac_final(ctx, buf); if(res)
libssh2_hmac_cleanup(&ctx); res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0; return !res;
} }

View File

@ -238,6 +238,66 @@ _libssh2_mbedtls_hash(const unsigned char *data, size_t datalen,
return ret == 0 ? 0 : -1; return ret == 0 ? 0 : -1;
} }
int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
return 1;
}
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_MD5, key, keylen);
}
#endif
#if LIBSSH2_HMAC_RIPEMD
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_RIPEMD160, key, keylen);
}
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_SHA1, key, keylen);
}
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_SHA256, key, keylen);
}
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_SHA512, key, keylen);
}
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen)
{
int ret = mbedtls_md_hmac_update(ctx, data, datalen);
return ret == 0 ? 1 : 0;
}
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
{
int ret = mbedtls_md_hmac_finish(ctx, data);
return ret == 0 ? 1 : 0;
}
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
{
mbedtls_md_free(ctx);
}
/*******************************************************************/ /*******************************************************************/
/* /*
* mbedTLS backend: BigNumber functions * mbedTLS backend: BigNumber functions

View File

@ -147,29 +147,6 @@
#define libssh2_hmac_ctx mbedtls_md_context_t #define libssh2_hmac_ctx mbedtls_md_context_t
#define libssh2_hmac_ctx_init(ctx)
#define libssh2_hmac_cleanup(pctx) \
mbedtls_md_free(pctx)
#define libssh2_hmac_update(ctx, data, datalen) \
mbedtls_md_hmac_update(&ctx, (const unsigned char *) data, datalen)
#define libssh2_hmac_final(ctx, hash) \
mbedtls_md_hmac_finish(&ctx, hash)
#define libssh2_hmac_sha1_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, key, keylen)
#if LIBSSH2_MD5
#define libssh2_hmac_md5_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, key, keylen)
#endif
#define libssh2_hmac_ripemd160_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_RIPEMD160, key, keylen)
#define libssh2_hmac_sha256_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, key, keylen)
#define libssh2_hmac_sha384_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, key, keylen)
#define libssh2_hmac_sha512_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, key, keylen)
/*******************************************************************/ /*******************************************************************/
/* /*

View File

@ -44,9 +44,149 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#ifndef EVP_MAX_BLOCK_LENGTH int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
#define EVP_MAX_BLOCK_LENGTH 32 {
#ifdef USE_OPENSSL_3
*ctx = NULL;
return 1;
#elif defined(HAVE_OPAQUE_STRUCTS)
*ctx = HMAC_CTX_new();
return *ctx ? 1 : 0;
#else
HMAC_CTX_init(ctx);
return 1;
#endif #endif
}
#ifdef USE_OPENSSL_3
static int _libssh2_hmac_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen,
const char *digest_name)
{
EVP_MAC* mac;
OSSL_PARAM params[3];
mac = EVP_MAC_fetch(NULL, OSSL_MAC_NAME_HMAC, NULL);
if(!mac)
return 0;
*ctx = EVP_MAC_CTX_new(mac);
EVP_MAC_free(mac);
if(!*ctx)
return 0;
params[0] = OSSL_PARAM_construct_octet_string(
OSSL_MAC_PARAM_KEY, (void *)key, keylen);
params[1] = OSSL_PARAM_construct_utf8_string(
OSSL_MAC_PARAM_DIGEST, (char *)digest_name, 0);
params[2] = OSSL_PARAM_construct_end();
return EVP_MAC_init(*ctx, NULL, 0, params);
}
#endif
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
#ifdef USE_OPENSSL_3
return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_MD5);
#elif defined(HAVE_OPAQUE_STRUCTS)
return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_md5(), NULL);
#else
return HMAC_Init_ex(ctx, key, (int)keylen, EVP_md5(), NULL);
#endif
}
#endif
#if LIBSSH2_HMAC_RIPEMD
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
#ifdef USE_OPENSSL_3
return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_RIPEMD160);
#elif defined(HAVE_OPAQUE_STRUCTS)
return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_ripemd160(), NULL);
#else
return HMAC_Init_ex(ctx, key, (int)keylen, EVP_ripemd160(), NULL);
#endif
}
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
#ifdef USE_OPENSSL_3
return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_SHA1);
#elif defined(HAVE_OPAQUE_STRUCTS)
return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_sha1(), NULL);
#else
return HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha1(), NULL);
#endif
}
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
#ifdef USE_OPENSSL_3
return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_SHA2_256);
#elif defined(HAVE_OPAQUE_STRUCTS)
return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_sha256(), NULL);
#else
return HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha256(), NULL);
#endif
}
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
#ifdef USE_OPENSSL_3
return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_SHA2_512);
#elif defined(HAVE_OPAQUE_STRUCTS)
return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_sha512(), NULL);
#else
return HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha512(), NULL);
#endif
}
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen)
{
#ifdef USE_OPENSSL_3
return EVP_MAC_update(*ctx, data, datalen);
#elif defined(HAVE_OPAQUE_STRUCTS)
/* FIXME: upstream bug as of v5.6.0: datalen is int instead of size_t */
#if defined(LIBSSH2_WOLFSSL)
return HMAC_Update(*ctx, data, (int)datalen);
#else /* !LIBSSH2_WOLFSSL */
return HMAC_Update(*ctx, data, datalen);
#endif /* LIBSSH2_WOLFSSL */
#else
return HMAC_Update(ctx, data, datalen);
#endif
}
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
{
#ifdef USE_OPENSSL_3
return EVP_MAC_final(*ctx, data, NULL, MAX_MACSIZE);
#elif defined(HAVE_OPAQUE_STRUCTS)
return HMAC_Final(*ctx, data, NULL);
#else
return HMAC_Final(ctx, data, NULL);
#endif
}
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
{
#ifdef USE_OPENSSL_3
EVP_MAC_CTX_free(*ctx);
#elif defined(HAVE_OPAQUE_STRUCTS)
HMAC_CTX_free(*ctx);
#else
HMAC_cleanup(ctx);
#endif
}
static int static int
read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session, read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session,
@ -92,32 +232,6 @@ write_bn(unsigned char *buf, const BIGNUM *bn, int bn_bytes)
} }
#endif #endif
#ifdef USE_OPENSSL_3
int _libssh2_hmac_init(libssh2_hmac_ctx *ctx, void *key, size_t keylen,
const char *digest_name)
{
EVP_MAC* mac;
OSSL_PARAM params[3];
mac = EVP_MAC_fetch(NULL, OSSL_MAC_NAME_HMAC, NULL);
if(!mac)
return 0;
*ctx = EVP_MAC_CTX_new(mac);
EVP_MAC_free(mac);
if(!*ctx)
return 0;
params[0] = OSSL_PARAM_construct_octet_string(
OSSL_MAC_PARAM_KEY, (void *)key, keylen);
params[1] = OSSL_PARAM_construct_utf8_string(
OSSL_MAC_PARAM_DIGEST, (char *)digest_name, 0);
params[2] = OSSL_PARAM_construct_end();
return EVP_MAC_init(*ctx, NULL, 0, params);
}
#endif
static inline void static inline void
_libssh2_swap_bytes(unsigned char *buf, unsigned long len) _libssh2_swap_bytes(unsigned char *buf, unsigned long len)
{ {
@ -851,6 +965,10 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
#endif #endif
} }
#ifndef EVP_MAX_BLOCK_LENGTH
#define EVP_MAX_BLOCK_LENGTH 32
#endif
int int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),

View File

@ -326,74 +326,11 @@ int _libssh2_md5_init(libssh2_md5_ctx *ctx);
#endif /* LIBSSH2_MD5 || LIBSSH2_MD5_PEM */ #endif /* LIBSSH2_MD5 || LIBSSH2_MD5_PEM */
#ifdef USE_OPENSSL_3 #ifdef USE_OPENSSL_3
#define libssh2_hmac_ctx EVP_MAC_CTX * #define libssh2_hmac_ctx EVP_MAC_CTX *
#define libssh2_hmac_ctx_init(ctx) #elif defined(HAVE_OPAQUE_STRUCTS)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
_libssh2_hmac_init(ctx, (void *)key, keylen, OSSL_DIGEST_NAME_SHA1)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
_libssh2_hmac_init(ctx, (void *)key, keylen, OSSL_DIGEST_NAME_MD5)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
_libssh2_hmac_init(ctx, (void *)key, keylen, OSSL_DIGEST_NAME_RIPEMD160)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
_libssh2_hmac_init(ctx, (void *)key, keylen, OSSL_DIGEST_NAME_SHA2_256)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
_libssh2_hmac_init(ctx, (void *)key, keylen, OSSL_DIGEST_NAME_SHA2_512)
#define libssh2_hmac_update(ctx, data, datalen) \
EVP_MAC_update(ctx, data, datalen)
#define libssh2_hmac_final(ctx, data) EVP_MAC_final(ctx, data, NULL, \
MAX_MACSIZE)
#define libssh2_hmac_cleanup(ctx) EVP_MAC_CTX_free(*(ctx))
int _libssh2_hmac_init(libssh2_hmac_ctx *ctx, void *key, size_t keylen,
const char *digest_name);
#else /* USE_OPENSSL_3 */
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_hmac_ctx HMAC_CTX * #define libssh2_hmac_ctx HMAC_CTX *
#define libssh2_hmac_ctx_init(ctx) ctx = HMAC_CTX_new()
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha1(), NULL)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_md5(), NULL)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_ripemd160(), NULL)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha256(), NULL)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha512(), NULL)
#ifdef LIBSSH2_WOLFSSL
/* FIXME: upstream bug as of v5.6.0: datalen is int instead of size_t */
#define libssh2_hmac_update(ctx, data, datalen) \
HMAC_Update(ctx, data, (int)datalen)
#else /* !LIBSSH2_WOLFSSL */
#define libssh2_hmac_update(ctx, data, datalen) \
HMAC_Update(ctx, data, datalen)
#endif /* LIBSSH2_WOLFSSL */
#define libssh2_hmac_final(ctx, data) HMAC_Final(ctx, data, NULL)
#define libssh2_hmac_cleanup(ctx) HMAC_CTX_free(*(ctx))
#else /* !HAVE_OPAQUE_STRUCTS */ #else /* !HAVE_OPAQUE_STRUCTS */
#define libssh2_hmac_ctx HMAC_CTX #define libssh2_hmac_ctx HMAC_CTX
#define libssh2_hmac_ctx_init(ctx) \
HMAC_CTX_init(&ctx)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha1(), NULL)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, (int)keylen, EVP_md5(), NULL)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, (int)keylen, EVP_ripemd160(), NULL)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha256(), NULL)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha512(), NULL)
#define libssh2_hmac_update(ctx, data, datalen) \
HMAC_Update(&(ctx), data, datalen)
#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL)
#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
#endif /* HAVE_OPAQUE_STRUCTS */
#endif /* USE_OPENSSL_3 */ #endif /* USE_OPENSSL_3 */
extern void _libssh2_openssl_crypto_init(void); extern void _libssh2_openssl_crypto_init(void);

View File

@ -1003,51 +1003,104 @@ libssh2_os400qc3_hash(const unsigned char *message, unsigned long len,
return 0; return 0;
} }
void static int
libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *ctx, libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *ctx,
int algo, size_t minkeylen, void *key, int keylen) int algo, size_t minkeylen, void *key, int keylen)
{ {
Qus_EC_t errcode;
if(keylen < minkeylen) { if(keylen < minkeylen) {
char *lkey = alloca(minkeylen); char *lkey = alloca(minkeylen);
/* Pad key with zeroes if too short. */ /* Pad key with zeroes if too short. */
if(!lkey) if(!lkey)
return; return 0;
memcpy(lkey, (char *) key, keylen); memcpy(lkey, (char *) key, keylen);
memset(lkey + keylen, 0, minkeylen - keylen); memset(lkey + keylen, 0, minkeylen - keylen);
key = (void *) lkey; key = (void *) lkey;
keylen = minkeylen; keylen = minkeylen;
} }
libssh2_os400qc3_hash_init(&ctx->hash, algo); if(!libssh2_os400qc3_hash_init(&ctx->hash, algo))
return 0;
set_EC_length(errcode, sizeof(errcode));
Qc3CreateKeyContext((char *) key, &keylen, binstring, &algo, qc3clear, Qc3CreateKeyContext((char *) key, &keylen, binstring, &algo, qc3clear,
NULL, NULL, ctx->key.Key_Context_Token, NULL, NULL, ctx->key.Key_Context_Token,
(char *) &ecnull); (char *) &errcode);
return errcode.Bytes_Available? 0: 1;
} }
void int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx, {
unsigned char *data, int len) memset((char *) ctx, 0, sizeof(libssh2_hmac_ctx));
return 1;
}
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return libssh2_os400qc3_hmac_init(ctx, Qc3_MD5, \
MD5_DIGEST_LENGTH, \
key, keylen);
}
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return libssh2_os400qc3_hmac_init(ctx, Qc3_SHA1, \
SHA_DIGEST_LENGTH, \
key, keylen);
}
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return libssh2_os400qc3_hmac_init(ctx, Qc3_SHA256, \
SHA256_DIGEST_LENGTH, \
key, keylen);
}
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
return libssh2_os400qc3_hmac_init(ctx, Qc3_SHA512, \
SHA512_DIGEST_LENGTH, \
key, keylen);
}
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen)
{ {
char dummy[64]; char dummy[64];
int len = (int) datalen;
Qus_EC_t errcode;
ctx->hash.Final_Op_Flag = Qc3_Continue; ctx->hash.Final_Op_Flag = Qc3_Continue;
set_EC_length(errcode, sizeof(errcode));
Qc3CalculateHMAC((char *) data, &len, Qc3_Data, (char *) &ctx->hash, Qc3CalculateHMAC((char *) data, &len, Qc3_Data, (char *) &ctx->hash,
Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token,
anycsp, NULL, dummy, (char *) &ecnull); anycsp, NULL, dummy, (char *) &errcode);
return errcode.Bytes_Available? 0: 1;
} }
void int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *out)
libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx,
unsigned char *out)
{ {
char data; char data;
Qus_EC_t errcode;
ctx->hash.Final_Op_Flag = Qc3_Final; ctx->hash.Final_Op_Flag = Qc3_Final;
set_EC_length(errcode, sizeof(errcode));
Qc3CalculateHMAC((char *) data, &zero, Qc3_Data, (char *) &ctx->hash, Qc3CalculateHMAC((char *) data, &zero, Qc3_Data, (char *) &ctx->hash,
Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token,
anycsp, NULL, (char *) out, (char *) &ecnull); anycsp, NULL, (char *) out, (char *) &errcode);
return errcode.Bytes_Available? 0: 1;
} }
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
{
_libssh2_os400qc3_crypto_dtor(ctx);
}
/******************************************************************* /*******************************************************************
* *
@ -1425,6 +1478,11 @@ pbkdf2(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase,
if(!mac) if(!mac)
return -1; return -1;
/* Create an HMAC context for our computations. */
if(!libssh2_os400qc3_hmac_init(&hctx, pkcs5->hash, pkcs5->hashlen,
(void *) passphrase, strlen(passphrase)))
return -1;
/* Allocate the derived key buffer. */ /* Allocate the derived key buffer. */
l = t; l = t;
buf = LIBSSH2_ALLOC(session, l * pkcs5->hashlen); buf = LIBSSH2_ALLOC(session, l * pkcs5->hashlen);
@ -1432,20 +1490,26 @@ pbkdf2(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase,
return -1; return -1;
*dk = buf; *dk = buf;
/* Create an HMAC context for our computations. */
libssh2_os400qc3_hmac_init(&hctx, pkcs5->hash, pkcs5->hashlen,
(void *) passphrase, strlen(passphrase));
/* Process each hLen-size blocks. */ /* Process each hLen-size blocks. */
for(i = 1; i <= l; i++) { for(i = 1; i <= l; i++) {
ni = htonl(i); ni = htonl(i);
libssh2_os400qc3_hmac_update(&hctx, pkcs5->salt, pkcs5->saltlen); if(!_libssh2_hmac_update(&hctx, pkcs5->salt, pkcs5->saltlen) ||
libssh2_os400qc3_hmac_update(&hctx, (char *) &ni, sizeof(ni)); !_libssh2_hmac_update(&hctx, &ni, sizeof(ni)) ||
libssh2_os400qc3_hmac_final(&hctx, mac); !_libssh2_hmac_final(&hctx, mac)) {
LIBSSH2_FREE(session, buf);
*dk = NULL;
_libssh2_os400qc3_crypto_dtor(&hctx);
return -1;
}
memcpy(buf, mac, pkcs5->hashlen); memcpy(buf, mac, pkcs5->hashlen);
for(j = 1; j < pkcs5->itercount; j++) { for(j = 1; j < pkcs5->itercount; j++) {
libssh2_os400qc3_hmac_update(&hctx, mac, pkcs5->hashlen); if(!_libssh2_hmac_update(&hctx, mac, pkcs5->hashlen) ||
libssh2_os400qc3_hmac_final(&hctx, mac); !_libssh2_hmac_final(&hctx, mac)) {
LIBSSH2_FREE(session, buf);
*dk = NULL;
_libssh2_os400qc3_crypto_dtor(&hctx);
return -1;
}
for(k = 0; k < pkcs5->hashlen; k++) for(k = 0; k < pkcs5->hashlen; k++)
buf[k] ^= mac[k]; buf[k] ^= mac[k];
} }

View File

@ -285,33 +285,6 @@ typedef struct { /* Diffie-Hellman context. */
libssh2_os400qc3_hash_update(&(ctx), data, len) libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) \ #define libssh2_md5_final(ctx, out) \
libssh2_os400qc3_hash_final(&(ctx), out) libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_hmac_ctx_init(ctx) \
memset((char *) &(ctx), 0, \
sizeof(libssh2_hmac_ctx))
#define libssh2_hmac_md5_init(ctx, key, keylen) \
libssh2_os400qc3_hmac_init(ctx, Qc3_MD5, \
MD5_DIGEST_LENGTH, \
key, keylen)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
libssh2_os400qc3_hmac_init(ctx, Qc3_SHA1, \
SHA_DIGEST_LENGTH, \
key, keylen)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
libssh2_os400qc3_hmac_init(ctx, Qc3_SHA256, \
SHA256_DIGEST_LENGTH, \
key, keylen)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
libssh2_os400qc3_hmac_init(ctx, Qc3_SHA512, \
SHA512_DIGEST_LENGTH, \
key, keylen)
#define libssh2_hmac_update(ctx, data, datalen) \
libssh2_os400qc3_hmac_update(&(ctx), \
data, datalen)
#define libssh2_hmac_final(ctx, data) \
libssh2_os400qc3_hmac_final(&(ctx), data)
#define libssh2_hmac_cleanup(ctx) \
_libssh2_os400qc3_crypto_dtor(ctx)
#define _libssh2_bn_ctx int /* Not used. */ #define _libssh2_bn_ctx int /* Not used. */
@ -397,14 +370,6 @@ extern void libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx,
extern int libssh2_os400qc3_hash(const unsigned char *message, extern int libssh2_os400qc3_hash(const unsigned char *message,
unsigned long len, unsigned char *out, unsigned long len, unsigned char *out,
unsigned int algo); unsigned int algo);
extern void libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *x,
int algo, size_t minkeylen,
void *key, int keylen);
extern void libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx,
const unsigned char *data,
int len);
extern void libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx,
unsigned char *out);
extern int _libssh2_os400qc3_rsa_signv(LIBSSH2_SESSION *session, int algo, extern int _libssh2_os400qc3_rsa_signv(LIBSSH2_SESSION *session, int algo,
unsigned char **signature, unsigned char **signature,
size_t *signature_len, size_t *signature_len,

View File

@ -1028,10 +1028,12 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
INTEGRATED_MAC case, where the crypto algorithm also does its INTEGRATED_MAC case, where the crypto algorithm also does its
own hash. */ own hash. */
if(!etm && !CRYPT_FLAG_R(session, INTEGRATED_MAC)) { if(!etm && !CRYPT_FLAG_R(session, INTEGRATED_MAC)) {
session->local.mac->hash(session, p->outbuf + packet_length, if(session->local.mac->hash(session, p->outbuf + packet_length,
session->local.seqno, p->outbuf, session->local.seqno, p->outbuf,
packet_length, NULL, 0, packet_length, NULL, 0,
&session->local.mac_abstract); &session->local.mac_abstract))
return _libssh2_error(session, LIBSSH2_ERROR_MAC_FAILURE,
"Failed to calculate MAC");
} }
/* Encrypt the whole packet data, one block size at a time. /* Encrypt the whole packet data, one block size at a time.
@ -1090,10 +1092,12 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
calculated on the entire packet (length plain the rest calculated on the entire packet (length plain the rest
encrypted), including all fields except the MAC field encrypted), including all fields except the MAC field
itself. */ itself. */
session->local.mac->hash(session, p->outbuf + packet_length, if(session->local.mac->hash(session, p->outbuf + packet_length,
session->local.seqno, p->outbuf, session->local.seqno, p->outbuf,
packet_length, NULL, 0, packet_length, NULL, 0,
&session->local.mac_abstract); &session->local.mac_abstract))
return _libssh2_error(session, LIBSSH2_ERROR_MAC_FAILURE,
"Failed to calculate MAC");
} }
} }

View File

@ -536,11 +536,11 @@ _libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx,
int int
_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, _libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx,
const unsigned char *data, ULONG datalen) const void *data, ULONG datalen)
{ {
int ret; int ret;
ret = BCryptHashData(ctx->hHash, (unsigned char *)data, datalen, 0); ret = BCryptHashData(ctx->hHash, (PUCHAR)data, datalen, 0);
return BCRYPT_SUCCESS(ret) ? 0 : -1; return BCRYPT_SUCCESS(ret) ? 0 : -1;
} }
@ -586,19 +586,70 @@ _libssh2_wincng_hash(const unsigned char *data, ULONG datalen,
* Windows CNG backend: HMAC functions * Windows CNG backend: HMAC functions
*/ */
int int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx,
unsigned char *hash)
{ {
int ret; memset(ctx, 0, sizeof(*ctx));
return 1;
ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0);
return BCRYPT_SUCCESS(ret) ? 0 : -1;
} }
void #if LIBSSH2_MD5
_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx) int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
int ret = _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacMD5,
MD5_DIGEST_LENGTH,
key, (ULONG) keylen);
return ret == 0 ? 1 : 0;
}
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
int ret = _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1,
SHA_DIGEST_LENGTH,
key, (ULONG) keylen);
return ret == 0 ? 1 : 0;
}
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
int ret = _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA256,
SHA256_DIGEST_LENGTH,
key, (ULONG) keylen);
return ret == 0 ? 1 : 0;
}
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
int ret = _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA512,
SHA512_DIGEST_LENGTH,
key, (ULONG) keylen);
return ret == 0 ? 1 : 0;
}
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen)
{
int ret = _libssh2_wincng_hash_update(ctx, data, (ULONG) datalen);
return ret == 0 ? 1 : 0;
}
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
{
int ret = BCryptFinishHash(ctx->hHash, data, ctx->cbHash, 0);
return BCRYPT_SUCCESS(ret) ? 1 : 0;
}
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
{ {
BCryptDestroyHash(ctx->hHash); BCryptDestroyHash(ctx->hHash);
ctx->hHash = NULL; ctx->hHash = NULL;

View File

@ -158,8 +158,7 @@ typedef struct __libssh2_wincng_hash_ctx {
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \
SHA_DIGEST_LENGTH, NULL, 0) == 0) SHA_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha1_update(ctx, data, datalen) \ #define libssh2_sha1_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, \ _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen)
(const unsigned char *) data, (ULONG) datalen)
#define libssh2_sha1_final(ctx, hash) \ #define libssh2_sha1_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash) _libssh2_wincng_hash_final(&ctx, hash)
#define libssh2_sha1(data, datalen, hash) \ #define libssh2_sha1(data, datalen, hash) \
@ -171,8 +170,7 @@ typedef struct __libssh2_wincng_hash_ctx {
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \
SHA256_DIGEST_LENGTH, NULL, 0) == 0) SHA256_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha256_update(ctx, data, datalen) \ #define libssh2_sha256_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, \ _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen)
(const unsigned char *) data, (ULONG) datalen)
#define libssh2_sha256_final(ctx, hash) \ #define libssh2_sha256_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash) _libssh2_wincng_hash_final(&ctx, hash)
#define libssh2_sha256(data, datalen, hash) \ #define libssh2_sha256(data, datalen, hash) \
@ -184,8 +182,7 @@ typedef struct __libssh2_wincng_hash_ctx {
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA384, \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA384, \
SHA384_DIGEST_LENGTH, NULL, 0) == 0) SHA384_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha384_update(ctx, data, datalen) \ #define libssh2_sha384_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, \ _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen)
(const unsigned char *) data, (ULONG) datalen)
#define libssh2_sha384_final(ctx, hash) \ #define libssh2_sha384_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash) _libssh2_wincng_hash_final(&ctx, hash)
#define libssh2_sha384(data, datalen, hash) \ #define libssh2_sha384(data, datalen, hash) \
@ -197,8 +194,7 @@ typedef struct __libssh2_wincng_hash_ctx {
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \
SHA512_DIGEST_LENGTH, NULL, 0) == 0) SHA512_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha512_update(ctx, data, datalen) \ #define libssh2_sha512_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, \ _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen)
(const unsigned char *) data, (ULONG) datalen)
#define libssh2_sha512_final(ctx, hash) \ #define libssh2_sha512_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash) _libssh2_wincng_hash_final(&ctx, hash)
#define libssh2_sha512(data, datalen, hash) \ #define libssh2_sha512(data, datalen, hash) \
@ -211,8 +207,7 @@ typedef struct __libssh2_wincng_hash_ctx {
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \
MD5_DIGEST_LENGTH, NULL, 0) == 0) MD5_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_md5_update(ctx, data, datalen) \ #define libssh2_md5_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, \ _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen)
(const unsigned char *) data, (ULONG) datalen)
#define libssh2_md5_final(ctx, hash) \ #define libssh2_md5_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash) _libssh2_wincng_hash_final(&ctx, hash)
#define libssh2_md5(data, datalen, hash) \ #define libssh2_md5(data, datalen, hash) \
@ -225,30 +220,6 @@ typedef struct __libssh2_wincng_hash_ctx {
*/ */
#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx #define libssh2_hmac_ctx _libssh2_wincng_hash_ctx
#define libssh2_hmac_ctx_init(ctx)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1, \
SHA_DIGEST_LENGTH, key, (ULONG) keylen)
#if LIBSSH2_MD5
#define libssh2_hmac_md5_init(ctx, key, keylen) \
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacMD5, \
MD5_DIGEST_LENGTH, key, (ULONG) keylen)
#endif
#define libssh2_hmac_ripemd160_init(ctx, key, keylen)
/* not implemented */
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA256, \
SHA256_DIGEST_LENGTH, key, (ULONG) keylen)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA512, \
SHA512_DIGEST_LENGTH, key, (ULONG) keylen)
#define libssh2_hmac_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, \
(const unsigned char *) data, (ULONG) datalen)
#define libssh2_hmac_final(ctx, hash) \
_libssh2_wincng_hmac_final(&ctx, hash)
#define libssh2_hmac_cleanup(ctx) \
_libssh2_wincng_hmac_cleanup(ctx)
/*******************************************************************/ /*******************************************************************/
@ -466,7 +437,7 @@ _libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx,
unsigned char *key, ULONG keylen); unsigned char *key, ULONG keylen);
int int
_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, _libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx,
const unsigned char *data, ULONG datalen); const void *data, ULONG datalen);
int int
_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, _libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx,
unsigned char *hash); unsigned char *hash);
@ -475,12 +446,6 @@ _libssh2_wincng_hash(const unsigned char *data, ULONG datalen,
BCRYPT_ALG_HANDLE hAlg, BCRYPT_ALG_HANDLE hAlg,
unsigned char *hash, ULONG hashlen); unsigned char *hash, ULONG hashlen);
int
_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx,
unsigned char *hash);
void
_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx);
void void
_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa); _libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa);