diff --git a/docs/HACKING-CRYPTO b/docs/HACKING-CRYPTO index bce5d215..e075f36b 100644 --- a/docs/HACKING-CRYPTO +++ b/docs/HACKING-CRYPTO @@ -63,27 +63,21 @@ libssh2_hmac_ctx Type of an HMAC computation context. Generally a struct. 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. Called before setting-up the 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. +Must return 1 for success and 0 for failure. -void libssh2_hmac_update(libssh2_hmac_ctx ctx, - const unsigned char *data, - int datalen); +int _libssh2_hmac_update(libssh2_hmac_ctx *ctx, + const void *data, int datalen); 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, - unsigned char output[]); +int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, + void output[]); Get the computed HMAC from context ctx into the output buffer. The 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. diff --git a/include/libssh2.h b/include/libssh2.h index 123a2fdb..7b313bd8 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -587,6 +587,7 @@ typedef struct _LIBSSH2_POLLFD { #define LIBSSH2_ERROR_RANDGEN -49 #define LIBSSH2_ERROR_MISSING_USERAUTH_BANNER -50 #define LIBSSH2_ERROR_ALGO_UNSUPPORTED -51 +#define LIBSSH2_ERROR_MAC_FAILURE -52 /* this is a define to provide the old (<= 1.2.7) name */ #define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV diff --git a/src/crypto.h b/src/crypto.h index 2dda8e50..48744414 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -55,6 +55,27 @@ #error "no cryptography backend selected" #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_PRIVATE_KEY_LEN 64 #define LIBSSH2_ED25519_SIG_LEN 64 diff --git a/src/knownhost.c b/src/knownhost.c index ee23bf20..5eba6a10 100644 --- a/src/knownhost.c +++ b/src/knownhost.c @@ -421,19 +421,23 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, */ unsigned char hash[SHA_DIGEST_LENGTH]; libssh2_hmac_ctx ctx; - libssh2_hmac_ctx_init(ctx); + if(!_libssh2_hmac_ctx_init(&ctx)) + break; if(SHA_DIGEST_LENGTH != node->name_len) { /* the name hash length must be the sha1 size or we can't match it */ break; } - libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt, - node->salt_len); - libssh2_hmac_update(ctx, (unsigned char *)host, - strlen(host)); - libssh2_hmac_final(ctx, hash); - libssh2_hmac_cleanup(&ctx); + if(!_libssh2_hmac_sha1_init(&ctx, + node->salt, node->salt_len)) + break; + if(!_libssh2_hmac_update(&ctx, host, strlen(host)) || + !_libssh2_hmac_final(&ctx, hash)) { + _libssh2_hmac_cleanup(&ctx); + break; + } + _libssh2_hmac_cleanup(&ctx); if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH)) /* this is a node we're interested in */ diff --git a/src/libgcrypt.c b/src/libgcrypt.c index e463d9e3..b0f26b51 100644 --- a/src/libgcrypt.c +++ b/src/libgcrypt.c @@ -40,6 +40,105 @@ #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 int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, diff --git a/src/libgcrypt.h b/src/libgcrypt.h index 22b7724e..09dd91c6 100644 --- a/src/libgcrypt.h +++ b/src/libgcrypt.h @@ -144,30 +144,6 @@ #endif #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_exit() diff --git a/src/mac.c b/src/mac.c index db6f57a4..03ecd329 100644 --- a/src/mac.c +++ b/src/mac.c @@ -124,23 +124,27 @@ mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session, { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; + int res; (void)session; _libssh2_htonu32(seqno_buf, seqno); - libssh2_hmac_ctx_init(ctx); - libssh2_hmac_sha512_init(&ctx, *abstract, 64); - libssh2_hmac_update(ctx, seqno_buf, 4); - libssh2_hmac_update(ctx, packet, packet_len); - if(addtl && addtl_len) { - libssh2_hmac_update(ctx, addtl, addtl_len); - } - libssh2_hmac_final(ctx, buf); - libssh2_hmac_cleanup(&ctx); + if(!_libssh2_hmac_ctx_init(&ctx)) + return 1; + res = _libssh2_hmac_sha512_init(&ctx, *abstract, 64) && + _libssh2_hmac_update(&ctx, seqno_buf, 4) && + _libssh2_hmac_update(&ctx, packet, packet_len); + if(res && addtl && addtl_len) + res = _libssh2_hmac_update(&ctx, addtl, addtl_len); + if(res) + res = _libssh2_hmac_final(&ctx, buf); + _libssh2_hmac_cleanup(&ctx); - return 0; + return !res; } + + static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = { "hmac-sha2-512", 64, @@ -179,21 +183,23 @@ mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session, { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; + int res; (void)session; _libssh2_htonu32(seqno_buf, seqno); - libssh2_hmac_ctx_init(ctx); - libssh2_hmac_sha256_init(&ctx, *abstract, 32); - libssh2_hmac_update(ctx, seqno_buf, 4); - libssh2_hmac_update(ctx, packet, packet_len); - if(addtl && addtl_len) { - libssh2_hmac_update(ctx, addtl, addtl_len); - } - libssh2_hmac_final(ctx, buf); - libssh2_hmac_cleanup(&ctx); + if(!_libssh2_hmac_ctx_init(&ctx)) + return 1; + res = _libssh2_hmac_sha256_init(&ctx, *abstract, 32) && + _libssh2_hmac_update(&ctx, seqno_buf, 4) && + _libssh2_hmac_update(&ctx, packet, packet_len); + if(res && addtl && addtl_len) + res = _libssh2_hmac_update(&ctx, addtl, addtl_len); + if(res) + 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; unsigned char seqno_buf[4]; + int res; (void)session; _libssh2_htonu32(seqno_buf, seqno); - libssh2_hmac_ctx_init(ctx); - libssh2_hmac_sha1_init(&ctx, *abstract, 20); - libssh2_hmac_update(ctx, seqno_buf, 4); - libssh2_hmac_update(ctx, packet, packet_len); - if(addtl && addtl_len) { - libssh2_hmac_update(ctx, addtl, addtl_len); - } - libssh2_hmac_final(ctx, buf); - libssh2_hmac_cleanup(&ctx); + if(!_libssh2_hmac_ctx_init(&ctx)) + return 1; + res = _libssh2_hmac_sha1_init(&ctx, *abstract, 20) && + _libssh2_hmac_update(&ctx, seqno_buf, 4) && + _libssh2_hmac_update(&ctx, packet, packet_len); + if(res && addtl && addtl_len) + res = _libssh2_hmac_update(&ctx, addtl, addtl_len); + if(res) + 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]; - mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, - addtl, addtl_len, abstract); - memcpy(buf, (char *) temp, 96 / 8); + if(mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, + addtl, addtl_len, abstract)) + return 1; + memcpy(buf, (char *) temp, 96 / 8); return 0; } @@ -321,21 +330,23 @@ mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf, { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; + int res; (void)session; _libssh2_htonu32(seqno_buf, seqno); - libssh2_hmac_ctx_init(ctx); - libssh2_hmac_md5_init(&ctx, *abstract, 16); - libssh2_hmac_update(ctx, seqno_buf, 4); - libssh2_hmac_update(ctx, packet, packet_len); - if(addtl && addtl_len) { - libssh2_hmac_update(ctx, addtl, addtl_len); - } - libssh2_hmac_final(ctx, buf); - libssh2_hmac_cleanup(&ctx); + if(!_libssh2_hmac_ctx_init(&ctx)) + return 1; + res = _libssh2_hmac_md5_init(&ctx, *abstract, 16) && + _libssh2_hmac_update(&ctx, seqno_buf, 4) && + _libssh2_hmac_update(&ctx, packet, packet_len); + if(res && addtl && addtl_len) + res = _libssh2_hmac_update(&ctx, addtl, addtl_len); + if(res) + 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) { 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); return 0; } @@ -396,21 +410,23 @@ mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session, { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; + int res; (void)session; _libssh2_htonu32(seqno_buf, seqno); - libssh2_hmac_ctx_init(ctx); - libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); - libssh2_hmac_update(ctx, seqno_buf, 4); - libssh2_hmac_update(ctx, packet, packet_len); - if(addtl && addtl_len) { - libssh2_hmac_update(ctx, addtl, addtl_len); - } - libssh2_hmac_final(ctx, buf); - libssh2_hmac_cleanup(&ctx); + if(!_libssh2_hmac_ctx_init(&ctx)) + return 1; + res = _libssh2_hmac_ripemd160_init(&ctx, *abstract, 20) && + _libssh2_hmac_update(&ctx, seqno_buf, 4) && + _libssh2_hmac_update(&ctx, packet, packet_len); + if(res && addtl && addtl_len) + res = _libssh2_hmac_update(&ctx, addtl, addtl_len); + if(res) + res = _libssh2_hmac_final(&ctx, buf); + _libssh2_hmac_cleanup(&ctx); - return 0; + return !res; } diff --git a/src/mbedtls.c b/src/mbedtls.c index 8d1f7bc3..c7cdae62 100644 --- a/src/mbedtls.c +++ b/src/mbedtls.c @@ -238,6 +238,66 @@ _libssh2_mbedtls_hash(const unsigned char *data, size_t datalen, 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 diff --git a/src/mbedtls.h b/src/mbedtls.h index 05fe86c0..1175c1a9 100644 --- a/src/mbedtls.h +++ b/src/mbedtls.h @@ -147,29 +147,6 @@ #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) - /*******************************************************************/ /* diff --git a/src/openssl.c b/src/openssl.c index 76277845..574be52b 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -44,9 +44,149 @@ #include #include -#ifndef EVP_MAX_BLOCK_LENGTH -#define EVP_MAX_BLOCK_LENGTH 32 +int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx) +{ +#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 +} + +#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 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 -#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 _libssh2_swap_bytes(unsigned char *buf, unsigned long len) { @@ -851,6 +965,10 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h, #endif } +#ifndef EVP_MAX_BLOCK_LENGTH +#define EVP_MAX_BLOCK_LENGTH 32 +#endif + int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, _libssh2_cipher_type(algo), diff --git a/src/openssl.h b/src/openssl.h index a669cc43..a236c1d6 100644 --- a/src/openssl.h +++ b/src/openssl.h @@ -326,74 +326,11 @@ int _libssh2_md5_init(libssh2_md5_ctx *ctx); #endif /* LIBSSH2_MD5 || LIBSSH2_MD5_PEM */ #ifdef USE_OPENSSL_3 - #define libssh2_hmac_ctx EVP_MAC_CTX * -#define libssh2_hmac_ctx_init(ctx) -#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 +#elif defined(HAVE_OPAQUE_STRUCTS) #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 */ #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 */ extern void _libssh2_openssl_crypto_init(void); diff --git a/src/os400qc3.c b/src/os400qc3.c index 1dca2594..44fe60c5 100644 --- a/src/os400qc3.c +++ b/src/os400qc3.c @@ -1003,51 +1003,104 @@ libssh2_os400qc3_hash(const unsigned char *message, unsigned long len, return 0; } -void +static int libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *ctx, int algo, size_t minkeylen, void *key, int keylen) { + Qus_EC_t errcode; + if(keylen < minkeylen) { char *lkey = alloca(minkeylen); /* Pad key with zeroes if too short. */ if(!lkey) - return; + return 0; memcpy(lkey, (char *) key, keylen); memset(lkey + keylen, 0, minkeylen - keylen); key = (void *) lkey; 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, NULL, NULL, ctx->key.Key_Context_Token, - (char *) &ecnull); + (char *) &errcode); + return errcode.Bytes_Available? 0: 1; } -void -libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx, - unsigned char *data, int len) +int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx) +{ + 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]; + int len = (int) datalen; + Qus_EC_t errcode; ctx->hash.Final_Op_Flag = Qc3_Continue; + set_EC_length(errcode, sizeof(errcode)); Qc3CalculateHMAC((char *) data, &len, Qc3_Data, (char *) &ctx->hash, 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 -libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx, - unsigned char *out) +int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *out) { char data; + Qus_EC_t errcode; ctx->hash.Final_Op_Flag = Qc3_Final; + set_EC_length(errcode, sizeof(errcode)); Qc3CalculateHMAC((char *) data, &zero, Qc3_Data, (char *) &ctx->hash, 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) 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. */ l = t; buf = LIBSSH2_ALLOC(session, l * pkcs5->hashlen); @@ -1432,20 +1490,26 @@ pbkdf2(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase, return -1; *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. */ for(i = 1; i <= l; i++) { ni = htonl(i); - libssh2_os400qc3_hmac_update(&hctx, pkcs5->salt, pkcs5->saltlen); - libssh2_os400qc3_hmac_update(&hctx, (char *) &ni, sizeof(ni)); - libssh2_os400qc3_hmac_final(&hctx, mac); + if(!_libssh2_hmac_update(&hctx, pkcs5->salt, pkcs5->saltlen) || + !_libssh2_hmac_update(&hctx, &ni, sizeof(ni)) || + !_libssh2_hmac_final(&hctx, mac)) { + LIBSSH2_FREE(session, buf); + *dk = NULL; + _libssh2_os400qc3_crypto_dtor(&hctx); + return -1; + } memcpy(buf, mac, pkcs5->hashlen); for(j = 1; j < pkcs5->itercount; j++) { - libssh2_os400qc3_hmac_update(&hctx, mac, pkcs5->hashlen); - libssh2_os400qc3_hmac_final(&hctx, mac); + if(!_libssh2_hmac_update(&hctx, mac, pkcs5->hashlen) || + !_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++) buf[k] ^= mac[k]; } diff --git a/src/os400qc3.h b/src/os400qc3.h index 3e3c1f75..c9328ff6 100644 --- a/src/os400qc3.h +++ b/src/os400qc3.h @@ -285,33 +285,6 @@ typedef struct { /* Diffie-Hellman context. */ libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_md5_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. */ @@ -397,14 +370,6 @@ extern void libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, extern int libssh2_os400qc3_hash(const unsigned char *message, unsigned long len, unsigned char *out, 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, unsigned char **signature, size_t *signature_len, diff --git a/src/transport.c b/src/transport.c index a8bb588a..531f5aa1 100644 --- a/src/transport.c +++ b/src/transport.c @@ -1028,10 +1028,12 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session, INTEGRATED_MAC case, where the crypto algorithm also does its own hash. */ if(!etm && !CRYPT_FLAG_R(session, INTEGRATED_MAC)) { - session->local.mac->hash(session, p->outbuf + packet_length, - session->local.seqno, p->outbuf, - packet_length, NULL, 0, - &session->local.mac_abstract); + if(session->local.mac->hash(session, p->outbuf + packet_length, + session->local.seqno, p->outbuf, + packet_length, NULL, 0, + &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. @@ -1090,10 +1092,12 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session, calculated on the entire packet (length plain the rest encrypted), including all fields except the MAC field itself. */ - session->local.mac->hash(session, p->outbuf + packet_length, - session->local.seqno, p->outbuf, - packet_length, NULL, 0, - &session->local.mac_abstract); + if(session->local.mac->hash(session, p->outbuf + packet_length, + session->local.seqno, p->outbuf, + packet_length, NULL, 0, + &session->local.mac_abstract)) + return _libssh2_error(session, LIBSSH2_ERROR_MAC_FAILURE, + "Failed to calculate MAC"); } } diff --git a/src/wincng.c b/src/wincng.c index 6e00f02f..1dcd0bb4 100644 --- a/src/wincng.c +++ b/src/wincng.c @@ -536,11 +536,11 @@ _libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, int _libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, - const unsigned char *data, ULONG datalen) + const void *data, ULONG datalen) { 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; } @@ -586,19 +586,70 @@ _libssh2_wincng_hash(const unsigned char *data, ULONG datalen, * Windows CNG backend: HMAC functions */ -int -_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, - unsigned char *hash) +int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx) { - int ret; - - ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); - - return BCRYPT_SUCCESS(ret) ? 0 : -1; + memset(ctx, 0, sizeof(*ctx)); + return 1; } -void -_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx) +#if LIBSSH2_MD5 +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); ctx->hHash = NULL; diff --git a/src/wincng.h b/src/wincng.h index d88f6085..68407e31 100644 --- a/src/wincng.h +++ b/src/wincng.h @@ -158,8 +158,7 @@ typedef struct __libssh2_wincng_hash_ctx { (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \ SHA_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha1_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, \ - (const unsigned char *) data, (ULONG) datalen) + _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) #define libssh2_sha1_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, 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, \ SHA256_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha256_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, \ - (const unsigned char *) data, (ULONG) datalen) + _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) #define libssh2_sha256_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, 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, \ SHA384_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha384_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, \ - (const unsigned char *) data, (ULONG) datalen) + _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) #define libssh2_sha384_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, 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, \ SHA512_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha512_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, \ - (const unsigned char *) data, (ULONG) datalen) + _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) #define libssh2_sha512_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, 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, \ MD5_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_md5_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, \ - (const unsigned char *) data, (ULONG) datalen) + _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) #define libssh2_md5_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, 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_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); int _libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, - const unsigned char *data, ULONG datalen); + const void *data, ULONG datalen); int _libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, unsigned char *hash); @@ -475,12 +446,6 @@ _libssh2_wincng_hash(const unsigned char *data, ULONG datalen, BCRYPT_ALG_HANDLE hAlg, 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 _libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa);