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:
@ -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.
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
21
src/crypto.h
21
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
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
126
src/mac.c
126
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
|
174
src/openssl.c
174
src/openssl.c
@ -44,9 +44,149 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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),
|
||||
|
@ -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);
|
||||
|
106
src/os400qc3.c
106
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];
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
if(session->local.mac->hash(session, p->outbuf + packet_length,
|
||||
session->local.seqno, p->outbuf,
|
||||
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.
|
||||
@ -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,
|
||||
if(session->local.mac->hash(session, p->outbuf + packet_length,
|
||||
session->local.seqno, p->outbuf,
|
||||
packet_length, NULL, 0,
|
||||
&session->local.mac_abstract);
|
||||
&session->local.mac_abstract))
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_MAC_FAILURE,
|
||||
"Failed to calculate MAC");
|
||||
}
|
||||
}
|
||||
|
||||
|
75
src/wincng.c
75
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;
|
||||
|
47
src/wincng.h
47
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);
|
||||
|
||||
|
Reference in New Issue
Block a user