diff --git a/cmake/lws_config.h.in b/cmake/lws_config.h.in index 9136a8a04..a33f55dc0 100644 --- a/cmake/lws_config.h.in +++ b/cmake/lws_config.h.in @@ -46,6 +46,7 @@ #cmakedefine LWS_HAVE_EVP_aes_256_cfb8 #cmakedefine LWS_HAVE_EVP_aes_256_cfb128 #cmakedefine LWS_HAVE_EVP_aes_128_xts +#cmakedefine LWS_HAVE_EVP_PKEY_new_raw_private_key #cmakedefine LWS_HAVE_EXECVPE #cmakedefine LWS_HAVE_LIBCAP #cmakedefine LWS_HAVE_HMAC_CTX_new diff --git a/include/libwebsockets/lws-genhash.h b/include/libwebsockets/lws-genhash.h index 292a1ff62..8407d2f03 100644 --- a/include/libwebsockets/lws-genhash.h +++ b/include/libwebsockets/lws-genhash.h @@ -74,11 +74,18 @@ struct lws_genhmac_ctx { mbedtls_md_context_t ctx; #else const EVP_MD *evp_type; + +#if defined(LWS_HAVE_EVP_PKEY_new_raw_private_key) + EVP_MD_CTX *ctx; + EVP_PKEY *key; +#else #if defined(LWS_HAVE_HMAC_CTX_new) HMAC_CTX *ctx; #else HMAC_CTX ctx; #endif +#endif + #endif }; diff --git a/lib/tls/CMakeLists.txt b/lib/tls/CMakeLists.txt index 3a502d075..0c48f5d4c 100644 --- a/lib/tls/CMakeLists.txt +++ b/lib/tls/CMakeLists.txt @@ -298,6 +298,7 @@ CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_xts LWS_HAVE_EVP_aes_128_xts PARENT_SC CHECK_FUNCTION_EXISTS(${VARIA}RSA_verify_pss_mgf1 LWS_HAVE_RSA_verify_pss_mgf1 PARENT_SCOPE) CHECK_FUNCTION_EXISTS(${VARIA}HMAC_CTX_new LWS_HAVE_HMAC_CTX_new PARENT_SCOPE) CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_set_ciphersuites LWS_HAVE_SSL_CTX_set_ciphersuites PARENT_SCOPE) +CHECK_FUNCTION_EXISTS(${VARIA}EVP_PKEY_new_raw_private_key LWS_HAVE_EVP_PKEY_new_raw_private_key PARENT_SCOPE) if (LWS_WITH_SSL AND NOT LWS_WITH_MBEDTLS) # we don't want to confuse what's in or out of the wrapper with diff --git a/lib/tls/openssl/lws-genhash.c b/lib/tls/openssl/lws-genhash.c index 04d881fdd..7ff52186d 100644 --- a/lib/tls/openssl/lws-genhash.c +++ b/lib/tls/openssl/lws-genhash.c @@ -93,6 +93,78 @@ lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result) return ret; } +#if defined(LWS_HAVE_EVP_PKEY_new_raw_private_key) + +int +lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type, + const uint8_t *key, size_t key_len) +{ + ctx->ctx = EVP_MD_CTX_create(); + if (!ctx->ctx) + return -1; + + ctx->evp_type = 0; + ctx->type = type; + + switch (type) { + case LWS_GENHMAC_TYPE_SHA256: + ctx->evp_type = EVP_sha256(); + break; + case LWS_GENHMAC_TYPE_SHA384: + ctx->evp_type = EVP_sha384(); + break; + case LWS_GENHMAC_TYPE_SHA512: + ctx->evp_type = EVP_sha512(); + break; + default: + lwsl_err("%s: unknown HMAC type %d\n", __func__, type); + goto bail; + } + + ctx->key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, key, key_len); + if (!ctx->key) + goto bail; + + if (EVP_DigestSignInit(ctx->ctx, NULL, ctx->evp_type, NULL, ctx->key) != 1) + goto bail1; + + return 0; + +bail1: + EVP_PKEY_free(ctx->key); +bail: + EVP_MD_CTX_free(ctx->ctx); + + return -1; +} + +int +lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len) +{ + + if (EVP_DigestSignUpdate(ctx->ctx, in, len) != 1) + return -1; + + return 0; +} + +int +lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result) +{ + size_t size = (size_t)lws_genhmac_size(ctx->type); + int n; + + n = EVP_DigestSignFinal(ctx->ctx, result, &size); + EVP_MD_CTX_free(ctx->ctx); + EVP_PKEY_free(ctx->key); + + if (n != 1) + return -1; + + return 0; +} + +#else int lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type, @@ -172,3 +244,5 @@ lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result) return 0; } + +#endif