xref: /freebsd/crypto/openssl/crypto/slh_dsa/slh_dsa_hash_ctx.c (revision e7be843b4a162e68651d3911f0357ed464915629)
1 /*
2  * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 #include <stddef.h>
10 #include <openssl/crypto.h>
11 #include "slh_dsa_local.h"
12 #include "slh_dsa_key.h"
13 #include <openssl/evp.h>
14 
15 /**
16  * @brief Create a SLH_DSA_HASH_CTX that contains parameters, functions, and
17  * pre-fetched HASH related objects for a SLH_DSA algorithm.This context is passed
18  * to most SLH-DSA functions.
19  *
20  * @param alg An SLH-DSA algorithm name such as "SLH-DSA-SHA2-128s"
21  * @param lib_ctx A library context used for fetching. Can be NULL
22  * @param propq A propqery query to use for algorithm fetching. Can be NULL.
23  *
24  * @returns The created SLH_DSA_HASH_CTX object or NULL on failure.
25  */
ossl_slh_dsa_hash_ctx_new(const SLH_DSA_KEY * key)26 SLH_DSA_HASH_CTX *ossl_slh_dsa_hash_ctx_new(const SLH_DSA_KEY *key)
27 {
28     SLH_DSA_HASH_CTX *ret = OPENSSL_zalloc(sizeof(*ret));
29 
30     if (ret == NULL)
31         return NULL;
32 
33     ret->key = key;
34     ret->md_ctx = EVP_MD_CTX_new();
35     if (ret->md_ctx == NULL)
36         goto err;
37     if (EVP_DigestInit_ex2(ret->md_ctx, key->md, NULL) != 1)
38         goto err;
39     if (key->md_big != NULL) {
40         /* Gets here for SHA2 algorithms */
41         if (key->md_big == key->md) {
42             ret->md_big_ctx = ret->md_ctx;
43         } else {
44             /* Only gets here for SHA2 */
45             ret->md_big_ctx = EVP_MD_CTX_new();
46             if (ret->md_big_ctx == NULL)
47                 goto err;
48             if (EVP_DigestInit_ex2(ret->md_big_ctx, key->md_big, NULL) != 1)
49                 goto err;
50         }
51         if (key->hmac != NULL) {
52             ret->hmac_ctx = EVP_MAC_CTX_new(key->hmac);
53             if (ret->hmac_ctx == NULL)
54                 goto err;
55         }
56     }
57     return ret;
58  err:
59     ossl_slh_dsa_hash_ctx_free(ret);
60     return NULL;
61 }
62 
63 /**
64  * @brief Duplicate a SLH_DSA_HASH_CTX
65  *
66  * @param ctx The SLH_DSA_HASH_CTX object to duplicate.
67  */
ossl_slh_dsa_hash_ctx_dup(const SLH_DSA_HASH_CTX * src)68 SLH_DSA_HASH_CTX *ossl_slh_dsa_hash_ctx_dup(const SLH_DSA_HASH_CTX *src)
69 {
70     SLH_DSA_HASH_CTX *ret = OPENSSL_zalloc(sizeof(*ret));
71 
72     if (ret == NULL)
73         return NULL;
74 
75     ret->hmac_digest_used = src->hmac_digest_used;
76     /* Note that the key is not ref counted, since it does not own the key */
77     ret->key = src->key;
78 
79     if (src->md_ctx != NULL
80             && (ret->md_ctx = EVP_MD_CTX_dup(src->md_ctx)) == NULL)
81         goto err;
82     if (src->md_big_ctx != NULL) {
83         if (src->md_big_ctx != src->md_ctx) {
84             if ((ret->md_big_ctx = EVP_MD_CTX_dup(src->md_big_ctx)) == NULL)
85                 goto err;
86         } else {
87             ret->md_big_ctx = ret->md_ctx;
88         }
89     }
90     if (src->hmac_ctx != NULL
91             && (ret->hmac_ctx = EVP_MAC_CTX_dup(src->hmac_ctx)) == NULL)
92         goto err;
93     return ret;
94  err:
95     ossl_slh_dsa_hash_ctx_free(ret);
96     return NULL;
97 }
98 
99 /**
100  * @brief Destroy a SLH_DSA_HASH_CTX
101  *
102  * @param ctx The SLH_DSA_HASH_CTX object to destroy.
103  */
ossl_slh_dsa_hash_ctx_free(SLH_DSA_HASH_CTX * ctx)104 void ossl_slh_dsa_hash_ctx_free(SLH_DSA_HASH_CTX *ctx)
105 {
106     if (ctx == NULL)
107         return;
108     EVP_MD_CTX_free(ctx->md_ctx);
109     if (ctx->md_big_ctx != ctx->md_ctx)
110         EVP_MD_CTX_free(ctx->md_big_ctx);
111     EVP_MAC_CTX_free(ctx->hmac_ctx);
112     OPENSSL_free(ctx);
113 }
114