+
+/*
+ * Helper functions for HMAC access with legacy support included.
+ */
+SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx)
+{
+ SSL_HMAC *ret = OPENSSL_zalloc(sizeof(*ret));
+ EVP_MAC *mac = NULL;
+
+ if (ret == NULL)
+ return NULL;
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->ext.ticket_key_evp_cb == NULL
+ && ctx->ext.ticket_key_cb != NULL) {
+ ret->old_ctx = HMAC_CTX_new();
+ if (ret->old_ctx == NULL)
+ goto err;
+ return ret;
+ }
+#endif
+ mac = EVP_MAC_fetch(ctx->libctx, "HMAC", NULL);
+ if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL)
+ goto err;
+ EVP_MAC_free(mac);
+ return ret;
+ err:
+ EVP_MAC_CTX_free(ret->ctx);
+ EVP_MAC_free(mac);
+ OPENSSL_free(ret);
+ return NULL;
+}
+
+void ssl_hmac_free(SSL_HMAC *ctx)
+{
+ if (ctx != NULL) {
+ EVP_MAC_CTX_free(ctx->ctx);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ HMAC_CTX_free(ctx->old_ctx);
+#endif
+ OPENSSL_free(ctx);
+ }
+}
+
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx)
+{
+ return ctx->old_ctx;
+}
+#endif
+
+EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx)
+{
+ return ctx->ctx;
+}
+
+int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md)
+{
+ OSSL_PARAM params[3], *p = params;
+
+ if (ctx->ctx != NULL) {
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key, len);
+ *p = OSSL_PARAM_construct_end();
+ if (EVP_MAC_CTX_set_params(ctx->ctx, params) && EVP_MAC_init(ctx->ctx))
+ return 1;
+ }
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->old_ctx != NULL)
+ return HMAC_Init_ex(ctx->old_ctx, key, len,
+ EVP_get_digestbyname(md), NULL);
+#endif
+ return 0;
+}
+
+int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len)
+{
+ if (ctx->ctx != NULL)
+ return EVP_MAC_update(ctx->ctx, data, len);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->old_ctx != NULL)
+ return HMAC_Update(ctx->old_ctx, data, len);
+#endif
+ return 0;
+}
+
+int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len,
+ size_t max_size)
+{
+ if (ctx->ctx != NULL)
+ return EVP_MAC_final(ctx->ctx, md, len, max_size);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->old_ctx != NULL) {
+ unsigned int l;
+
+ if (HMAC_Final(ctx->old_ctx, md, &l) > 0) {
+ if (len != NULL)
+ *len = l;
+ return 1;
+ }
+ }
+#endif
+ return 0;
+}
+
+size_t ssl_hmac_size(const SSL_HMAC *ctx)
+{
+ if (ctx->ctx != NULL)
+ return EVP_MAC_size(ctx->ctx);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->old_ctx != NULL)
+ return HMAC_size(ctx->old_ctx);
+#endif
+ return 0;
+}
+