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)26SLH_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)68SLH_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)104void 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