aboutsummaryrefslogtreecommitdiff
path: root/src/openvpn/crypto_openssl.c
diff options
context:
space:
mode:
authorArne Schwabe2021-10-19 20:31:07 +0200
committerGert Doering2021-10-27 20:21:22 +0200
commit7865ffdcbc603894f268d892d638b111e8b61c36 (patch)
treef390107c005f3e3f774a9c9ccdf0b192c64ce583 /src/openvpn/crypto_openssl.c
parent14e4f3b1583749adf104be362a3e2422e0c9e524 (diff)
downloadopenvpn-7865ffdcbc603894f268d892d638b111e8b61c36.zip
openvpn-7865ffdcbc603894f268d892d638b111e8b61c36.tar.gz
Use new EVP_MAC API for HMAC implementation
The old API is deprecated in OpenSSL 3.0 and the new API does not yet exist in OpenSSL 1.1. Emulating the new API would be more complex than just having two implementations. So this switches to a new hmac implementation for OpenSSL 3.0. Unfortunately the new API does not have an easy to reset an HMAC, so we need to keep the key around to emulate a reset functionality. Signed-off-by: Arne Schwabe <arne@rfc2549.org> Acked-by: Max Fillinger <maximilian.fillinger@foxcrypto.com> Message-Id: <20211019183127.614175-2-arne@rfc2549.org> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg23013.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'src/openvpn/crypto_openssl.c')
-rw-r--r--src/openvpn/crypto_openssl.c96
1 files changed, 94 insertions, 2 deletions
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index d4792f4..6b18551 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -989,7 +989,7 @@ md_ctx_final(EVP_MD_CTX *ctx, uint8_t *dst)
* Generic HMAC functions
*
*/
-
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
HMAC_CTX *
hmac_ctx_new(void)
{
@@ -1027,7 +1027,7 @@ hmac_ctx_cleanup(HMAC_CTX *ctx)
}
int
-hmac_ctx_size(const HMAC_CTX *ctx)
+hmac_ctx_size(HMAC_CTX *ctx)
{
return HMAC_size(ctx);
}
@@ -1054,6 +1054,98 @@ hmac_ctx_final(HMAC_CTX *ctx, uint8_t *dst)
HMAC_Final(ctx, dst, &in_hmac_len);
}
+#else
+hmac_ctx_t *
+hmac_ctx_new(void)
+{
+ hmac_ctx_t *ctx;
+ ALLOC_OBJ_CLEAR(ctx, hmac_ctx_t);
+ EVP_MAC *hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ ctx->ctx = EVP_MAC_CTX_new(hmac);
+ check_malloc_return(ctx->ctx);
+ return ctx;
+}
+
+void
+hmac_ctx_free(hmac_ctx_t *ctx)
+{
+ EVP_MAC_CTX_free(ctx->ctx);
+ secure_memzero(ctx, sizeof(hmac_ctx_t));
+ free(ctx);
+}
+
+void
+hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, int key_len,
+ const EVP_MD *kt)
+{
+ ASSERT(NULL != kt && NULL != ctx && ctx->ctx != NULL);
+ ASSERT(key_len <= EVP_MAX_KEY_LENGTH);
+
+ /* We need to make a copy of the key since the OSSL parameters
+ * only reference it */
+ memcpy(ctx->key, key, key_len);
+
+ /* Lookup/setting of parameters in OpenSSL 3.0 are string based
+ *
+ * The OSSL_PARAM_construct_utf8_string needs a non const str but this
+ * only used for lookup so we cast (as OpenSSL also does internally)
+ * the constness away here.
+ */
+ ctx->params[0] = OSSL_PARAM_construct_utf8_string("digest",
+ (char *) EVP_MD_get0_name(kt), 0);
+ ctx->params[1] = OSSL_PARAM_construct_octet_string("key",
+ ctx->key, key_len);
+ ctx->params[2] = OSSL_PARAM_construct_end();
+
+ if (!EVP_MAC_init(ctx->ctx, NULL, 0, ctx->params))
+ {
+ crypto_msg(M_FATAL, "EVP_MAC_init failed");
+ }
+
+ /* make sure we used a big enough key */
+ ASSERT(EVP_MAC_CTX_get_mac_size(ctx->ctx) <= key_len);
+}
+
+void
+hmac_ctx_cleanup(hmac_ctx_t *ctx)
+{
+ EVP_MAC_init(ctx->ctx, NULL, 0, NULL);
+}
+
+int
+hmac_ctx_size(hmac_ctx_t *ctx)
+{
+ return (int)EVP_MAC_CTX_get_mac_size(ctx->ctx);
+}
+
+void
+hmac_ctx_reset(hmac_ctx_t *ctx)
+{
+ /* The OpenSSL MAC API lacks a reset method and passing NULL as params
+ * does not reset it either, so use the params array to reinitialise it the
+ * same way as before */
+ if (!EVP_MAC_init(ctx->ctx, NULL, 0, ctx->params))
+ {
+ crypto_msg(M_FATAL, "EVP_MAC_init failed");
+ }
+}
+
+void
+hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
+{
+ EVP_MAC_update(ctx->ctx, src, src_len);
+}
+
+void
+hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
+{
+ /* The calling code always gives us a buffer that has the size of our
+ * algorithm */
+ size_t in_hmac_len = EVP_MAC_CTX_get_mac_size(ctx->ctx);
+
+ EVP_MAC_final(ctx->ctx, dst, &in_hmac_len, in_hmac_len);
+}
+#endif
int
memcmp_constant_time(const void *a, const void *b, size_t size)