Browse Source

[core] algo_hmac.[ch] wrapper (portability)

hash-based message authentication code (HMAC) wrapper
master
Glenn Strauss 10 months ago
parent
commit
c5003c26c8
  1. 2
      src/CMakeLists.txt
  2. 3
      src/Makefile.am
  3. 2
      src/SConscript
  4. 208
      src/algo_hmac.c
  5. 26
      src/algo_hmac.h
  6. 1
      src/meson.build

2
src/CMakeLists.txt

@ -750,7 +750,7 @@ set(COMMON_SRC
stat_cache.c plugin.c http_etag.c array.c
data_string.c data_array.c
data_integer.c
algo_md5.c algo_sha1.c algo_splaytree.c
algo_hmac.c algo_md5.c algo_sha1.c algo_splaytree.c
fdevent_select.c fdevent_libev.c
fdevent_poll.c fdevent_linux_sysepoll.c
fdevent_solaris_devpoll.c fdevent_solaris_port.c

3
src/Makefile.am

@ -75,7 +75,7 @@ common_src=base64.c buffer.c burl.c log.c \
stat_cache.c plugin.c http_etag.c array.c \
data_string.c data_array.c \
data_integer.c \
algo_md5.c algo_sha1.c algo_splaytree.c \
algo_hmac.c algo_md5.c algo_sha1.c algo_splaytree.c \
fdevent_select.c fdevent_libev.c \
fdevent_poll.c fdevent_linux_sysepoll.c \
fdevent_solaris_devpoll.c fdevent_solaris_port.c \
@ -462,6 +462,7 @@ mod_wstunnel_la_LIBADD = $(common_libadd) $(CRYPTO_LIB)
hdr = base64.h buffer.h burl.h network.h log.h http_kv.h keyvalue.h \
response.h request.h reqpool.h chunk.h h2.h \
first.h http_chunk.h \
algo_hmac.h \
algo_md.h algo_md5.h algo_sha1.h algo_splaytree.h algo_xxhash.h \
http_auth.h http_date.h http_header.h http_vhostdb.h stream.h \
fdevent.h gw_backend.h connections.h base.h base_decls.h stat_cache.h \

2
src/SConscript

@ -61,7 +61,7 @@ common_src = Split("base64.c buffer.c burl.c log.c \
stat_cache.c plugin.c http_etag.c array.c \
data_string.c data_array.c \
data_integer.c \
algo_md5.c algo_sha1.c algo_splaytree.c \
algo_hmac.c algo_md5.c algo_sha1.c algo_splaytree.c \
fdevent_select.c fdevent_libev.c \
fdevent_poll.c fdevent_linux_sysepoll.c \
fdevent_solaris_devpoll.c fdevent_solaris_port.c \

208
src/algo_hmac.c

@ -0,0 +1,208 @@
/* algo_hmac - hash-based message authentication code (HMAC) wrapper
*
* Copyright(c) 2021 Glenn Strauss gstrauss()gluelogic.com All rights reserved
* License: BSD 3-clause (same as lighttpd)
*/
#include "first.h"
#include "algo_hmac.h"
#include "sys-crypto-md.h"
#ifdef USE_LIB_CRYPTO
#if defined(USE_NETTLE_CRYPTO)
#include <nettle/hmac.h>
#elif defined(USE_MBEDTLS_CRYPTO)
#include <mbedtls/md.h>
#elif defined(USE_WOLFSSL_CRYPTO)
#include <wolfssl/wolfcrypt/hmac.h>
#elif defined(USE_OPENSSL_CRYPTO)
#include <openssl/evp.h>
#include <openssl/hmac.h>
#elif defined(USE_GNUTLS_CRYPTO)
#include <gnutls/crypto.h>
#elif defined(USE_NSS_CRYPTO)
#if 0 /*(nss/alghmac.h might not be present)*/
#ifdef NSS_VER_INCLUDE
#include <nss3/alghmac.h>
#else
#include <nss/alghmac.h>
#endif
#endif
#endif
#endif
#if defined(USE_OPENSSL_CRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
#define HMAC EVP_HMAC
static unsigned char *
EVP_HMAC (const EVP_MD *evp_md, const void *key,
int key_len, const unsigned char *d, int n,
unsigned char *md, size_t *md_len)
{
EVP_PKEY * const pkey =
EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, key_len);
if (NULL == pkey) return NULL;
EVP_MD_CTX * const ctx = EVP_MD_CTX_new();
if (NULL == ctx) {
EVP_PKEY_free(pkey);
return NULL;
}
int rc = (1 == EVP_DigestSignInit(ctx, NULL, evp_md, NULL, pkey))
&& (1 == EVP_DigestSignUpdate(ctx, d, n))
&& (1 == EVP_DigestSignFinal(ctx, md, md_len));
EVP_MD_CTX_free(ctx);
EVP_PKEY_free(pkey);
return (1 == rc) ? md : NULL;
}
#endif
int
li_hmac_md5 (unsigned char digest[MD5_DIGEST_LENGTH],
const void * const secret, const uint32_t slen,
const unsigned char * const msg, const uint32_t mlen)
{
li_MD5_CTX Md5Ctx;
li_MD5_Init(&Md5Ctx);
li_MD5_Update(&Md5Ctx, secret, slen);
li_MD5_Update(&Md5Ctx, msg, mlen);
li_MD5_Final(digest, &Md5Ctx);
return 1;
}
int
li_hmac_sha1 (unsigned char digest[SHA_DIGEST_LENGTH],
const void * const secret, const uint32_t slen,
const unsigned char * const msg, const uint32_t mlen)
{
#ifdef USE_LIB_CRYPTO
#if defined(USE_NETTLE_CRYPTO)
struct hmac_sha1_ctx ctx;
hmac_sha1_set_key(&ctx, slen, (const uint8_t *)secret);
hmac_sha1_update(&ctx, mlen, (const uint8_t *)msg);
hmac_sha1_digest(&ctx, SHA_DIGEST_LENGTH, (uint8_t *)digest);
return 1;
#elif defined(USE_MBEDTLS_CRYPTO) \
&& defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA1_C)
return 0 ==
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1),
(const unsigned char *)secret, slen,
(const unsigned char *)msg, mlen, digest);
#elif defined(USE_WOLFSSL_CRYPTO)
Hmac hmac;
if (0 != wc_HmacInit(&hmac, NULL, INVALID_DEVID)
|| wc_HmacSetKey(&hmac, WC_SHA, (const byte *)secret, (word32)slen) < 0
|| wc_HmacUpdate(&hmac, (const byte *)msg, (word32)mlen) < 0
|| wc_HmacFinal(&hmac, (byte *)digest) < 0)
return 0;
return 1;
#elif defined(USE_OPENSSL_CRYPTO)
return (NULL != HMAC(EVP_sha1(),
(const unsigned char *)secret, (int)slen,
(const unsigned char *)msg, mlen,
digest, NULL));
#elif defined(USE_GNUTLS_CRYPTO)
return 0 ==
gnutls_hmac_fast(GNUTLS_MAC_SHA1,
(const unsigned char *)secret, slen,
(const unsigned char *)msg, mlen, digest);
#elif defined(USE_NSS_CRYPTO)
/*(HMAC* funcs not public export of libfreebl3.so,
* even though nss3/alghmac.h is public (WTH?!))*/
#if 0
HMACContext *hmac =
HMAC_Create(HASH_GetHashObject(HASH_AlgSHA1),
(const unsigned char *)secret, slen, PR_FALSE);
if (NULL == hmac)
return 0;
HMAC_Begin(hmac);
HMAC_Update(hmac, (const unsigned char *)msg, mlen);
unsigned int dlen;
int rc = HMAC_Finish(hmac, digest, &dlen, SHA_DIGEST_LENGTH);
HMAC_Destroy(hmac, PR_TRUE);
return (SECSuccess == rc);
#else
return 0;
#endif
#else
#error "unexpected; crypto lib not configured for HMAC SHA1"
#endif
#else
UNUSED(digest);
UNUSED(secret);
UNUSED(slen);
UNUSED(msg);
UNUSED(mlen);
return 0;
#endif
}
int
li_hmac_sha256 (unsigned char digest[SHA256_DIGEST_LENGTH],
const void * const secret, const uint32_t slen,
const unsigned char * const msg, const uint32_t mlen)
{
#ifdef USE_LIB_CRYPTO
#if defined(USE_NETTLE_CRYPTO)
struct hmac_sha256_ctx ctx;
hmac_sha256_set_key(&ctx, slen, (const uint8_t *)secret);
hmac_sha256_update(&ctx, mlen, (const uint8_t *)msg);
hmac_sha256_digest(&ctx, SHA256_DIGEST_LENGTH, (uint8_t *)digest);
return 1;
#elif defined(USE_MBEDTLS_CRYPTO) \
&& defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C)
return 0 ==
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
(const unsigned char *)secret, slen,
(const unsigned char *)msg, mlen, digest);
#elif defined(USE_WOLFSSL_CRYPTO)
Hmac hmac;
if (0 != wc_HmacInit(&hmac, NULL, INVALID_DEVID)
|| wc_HmacSetKey(&hmac, WC_SHA256,(const byte *)secret,(word32)slen) < 0
|| wc_HmacUpdate(&hmac, (const byte *)msg, (word32)mlen) < 0
|| wc_HmacFinal(&hmac, (byte *)digest) < 0)
return 0;
return 1;
#elif defined(USE_OPENSSL_CRYPTO)
return (NULL != HMAC(EVP_sha256(),
(const unsigned char *)secret, (int)slen,
(const unsigned char *)msg, mlen,
digest, NULL));
#elif defined(USE_GNUTLS_CRYPTO)
return 0 ==
gnutls_hmac_fast(GNUTLS_MAC_SHA256,
(const unsigned char *)secret, slen,
(const unsigned char *)msg, mlen, digest);
#elif defined(USE_NSS_CRYPTO)
/*(HMAC* funcs not public export of libfreebl3.so,
* even though nss3/alghmac.h is public (WTH?!))*/
#if 0
HMACContext *hmac =
HMAC_Create(HASH_GetHashObject(HASH_AlgSHA256),
(const unsigned char *)secret, slen, PR_FALSE);
if (NULL == hmac)
return 0;
HMAC_Begin(hmac);
HMAC_Update(hmac, (const unsigned char *)msg, mlen);
unsigned int dlen;
int rc = HMAC_Finish(hmac, digest, &dlen, SHA256_DIGEST_LENGTH);
HMAC_Destroy(hmac, PR_TRUE);
return (SECSuccess == rc);
#else
return 0;
#endif
#else
#error "unexpected; crypto lib not configured for HMAC SHA256"
#endif
#else
UNUSED(digest);
UNUSED(secret);
UNUSED(slen);
UNUSED(msg);
UNUSED(mlen);
return 0;
#endif
}

26
src/algo_hmac.h

@ -0,0 +1,26 @@
/* algo_hmac - hash-based message authentication code (HMAC) wrapper
*
* Copyright(c) 2021 Glenn Strauss gstrauss()gluelogic.com All rights reserved
* License: BSD 3-clause (same as lighttpd)
*/
#ifndef INCLUDED_ALGO_HMAC_H
#define INCLUDED_ALGO_HMAC_H
#include "first.h"
int
li_hmac_md5 (unsigned char digest[16], /* [MD5_DIGEST_LENGTH] */
const void * const secret, const uint32_t slen,
const unsigned char * const msg, const uint32_t mlen);
int
li_hmac_sha1 (unsigned char digest[20], /* [SHA_DIGEST_LENGTH] */
const void * const secret, const uint32_t slen,
const unsigned char * const msg, const uint32_t mlen);
int
li_hmac_sha256 (unsigned char digest[32], /* [SHA256_DIGEST_LENGTH] */
const void * const secret, const uint32_t slen,
const unsigned char * const msg, const uint32_t mlen);
#endif /* INCLUDED_ALGO_HMAC_H */

1
src/meson.build

@ -704,6 +704,7 @@ configure_file(
)
common_src = [
'algo_hmac.c',
'algo_md5.c',
'algo_sha1.c',
'algo_splaytree.c',

Loading…
Cancel
Save