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 10 #include "crypto/slh_dsa.h" 11 #include "slh_hash.h" 12 #include "slh_params.h" 13 14 /* 15 * Maximum size of the security parameter |n| in FIPS 205 Section 11. Table 2. 16 * This indicates the length in bytes of a message that can be signed. 17 * It is the size used by WOTS+ public and private key elements as well as 18 * signature elements. 19 */ 20 #define SLH_MAX_N 32 21 /* 22 * For the given standard w=16 for all parameter sets. 23 * A n byte message is converted into 2 * n base 16 Integers followed 24 * by 3 Integers for the checksum of these values. 25 */ 26 #define SLH_WOTS_LEN(n) (2 * (n) + 3) 27 28 /* 29 * FIPS 205 SLH-DSA algorithms have many different parameters which includes 30 * the following constants that are stored into a |key|: 31 * - A set of constants (Section 11. contains 12 parameter sets) 32 * such as tree heights and security parameters associated with a algorithm 33 * name such as SLH-DSA-SHA2-128s. 34 * - ADRS functions (such as set_layer_address() in Section 4.3 & 11.2) 35 * - Hash Functions (such as H_MSG() & PRF()) See Sections 11.1, 11.2.1 & 11.2.2. 36 * - prefetched EVP_MD objects used for hashing. 37 * 38 * When performing operations multiple Hash related objects are also needed 39 * such as EVP_MD_CTX and EVP_MAC_CTX (these are independent of the |key|) 40 * 41 * SLH_DSA_HASH_CTX is a container to hold all of these objects. This object is 42 * resolved early and is then passed to most SLH_DSA related functions, since 43 * there are many nested layers of calls that require these values. 44 * 45 * NOTE: Any changes to this structure will need updating in 46 * ossl_slh_dsa_hash_ctx_dup(). 47 */ 48 struct slh_dsa_hash_ctx_st { 49 const SLH_DSA_KEY *key; /* This key is not owned by this object */ 50 EVP_MD_CTX *md_ctx; /* Either SHAKE OR SHA-256 */ 51 EVP_MD_CTX *md_big_ctx; /* Either SHA-512 or points to |md_ctx| for SHA-256*/ 52 EVP_MAC_CTX *hmac_ctx; /* required by SHA algorithms for PRFmsg() */ 53 int hmac_digest_used; /* Used for lazy init of hmac_ctx digest */ 54 }; 55 56 __owur int ossl_slh_wots_pk_gen(SLH_DSA_HASH_CTX *ctx, const uint8_t *sk_seed, 57 const uint8_t *pk_seed, uint8_t *adrs, 58 uint8_t *pk_out, size_t pk_out_len); 59 __owur int ossl_slh_wots_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, 60 const uint8_t *sk_seed, const uint8_t *pk_seed, 61 uint8_t *adrs, WPACKET *sig_wpkt); 62 __owur int ossl_slh_wots_pk_from_sig(SLH_DSA_HASH_CTX *ctx, 63 PACKET *sig_rpkt, const uint8_t *msg, 64 const uint8_t *pk_seed, uint8_t *adrs, 65 uint8_t *pk_out, size_t pk_out_len); 66 67 __owur int ossl_slh_xmss_node(SLH_DSA_HASH_CTX *ctx, const uint8_t *sk_seed, 68 uint32_t node_id, uint32_t height, 69 const uint8_t *pk_seed, uint8_t *adrs, 70 uint8_t *pk_out, size_t pk_out_len); 71 __owur int ossl_slh_xmss_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, 72 const uint8_t *sk_seed, uint32_t node_id, 73 const uint8_t *pk_seed, uint8_t *adrs, 74 WPACKET *sig_wpkt); 75 __owur int ossl_slh_xmss_pk_from_sig(SLH_DSA_HASH_CTX *ctx, uint32_t node_id, 76 PACKET *sig_rpkt, const uint8_t *msg, 77 const uint8_t *pk_seed, uint8_t *adrs, 78 uint8_t *pk_out, size_t pk_out_len); 79 80 __owur int ossl_slh_ht_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, 81 const uint8_t *sk_seed, const uint8_t *pk_seed, 82 uint64_t tree_id, uint32_t leaf_id, 83 WPACKET *sig_wpkt); 84 __owur int ossl_slh_ht_verify(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, 85 PACKET *sig_rpkt, const uint8_t *pk_seed, 86 uint64_t tree_id, uint32_t leaf_id, 87 const uint8_t *pk_root); 88 89 __owur int ossl_slh_fors_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *md, 90 const uint8_t *sk_seed, const uint8_t *pk_seed, 91 uint8_t *adrs, WPACKET *sig_wpkt); 92 __owur int ossl_slh_fors_pk_from_sig(SLH_DSA_HASH_CTX *ctx, PACKET *sig_rpkt, 93 const uint8_t *md, const uint8_t *pk_seed, 94 uint8_t *adrs, 95 uint8_t *pk_out, size_t pk_out_len); 96