xref: /freebsd/crypto/openssl/crypto/slh_dsa/slh_adrs.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 <string.h>
10 #include <openssl/byteorder.h>
11 #include "slh_adrs.h"
12 
13 /* See FIPS 205 - Section 4.3 Table 1  Uncompressed Addresses */
14 #define SLH_ADRS_OFF_LAYER_ADR      0
15 #define SLH_ADRS_OFF_TREE_ADR       4
16 #define SLH_ADRS_OFF_TYPE           16
17 #define SLH_ADRS_OFF_KEYPAIR_ADDR   20
18 #define SLH_ADRS_OFF_CHAIN_ADDR     24
19 #define SLH_ADRS_OFF_HASH_ADDR      28
20 #define SLH_ADRS_OFF_TREE_INDEX     SLH_ADRS_OFF_HASH_ADDR
21 #define SLH_ADRS_SIZE_TYPE          4
22 /* Number of bytes after type to clear */
23 #define SLH_ADRS_SIZE_TYPECLEAR     SLH_ADRS_SIZE - (SLH_ADRS_OFF_TYPE + SLH_ADRS_SIZE_TYPE)
24 #define SLH_ADRS_SIZE_KEYPAIR_ADDR  4
25 
26 /* See FIPS 205 - Section 11.2 Table 3 Compressed Addresses */
27 #define SLH_ADRSC_OFF_LAYER_ADR     0
28 #define SLH_ADRSC_OFF_TREE_ADR      1
29 #define SLH_ADRSC_OFF_TYPE          9
30 #define SLH_ADRSC_OFF_KEYPAIR_ADDR  10
31 #define SLH_ADRSC_OFF_CHAIN_ADDR    14
32 #define SLH_ADRSC_OFF_HASH_ADDR     18
33 #define SLH_ADRSC_OFF_TREE_INDEX    SLH_ADRSC_OFF_HASH_ADDR
34 #define SLH_ADRSC_SIZE_TYPE         1
35 #define SLH_ADRSC_SIZE_TYPECLEAR    SLH_ADRS_SIZE_TYPECLEAR
36 #define SLH_ADRSC_SIZE_KEYPAIR_ADDR SLH_ADRS_SIZE_KEYPAIR_ADDR
37 
38 #define slh_adrs_set_tree_height slh_adrs_set_chain_address
39 #define slh_adrs_set_tree_index slh_adrs_set_hash_address
40 
41 #define slh_adrsc_set_tree_height slh_adrsc_set_chain_address
42 #define slh_adrsc_set_tree_index slh_adrsc_set_hash_address
43 
44 static OSSL_SLH_ADRS_FUNC_set_layer_address slh_adrs_set_layer_address;
45 static OSSL_SLH_ADRS_FUNC_set_tree_address slh_adrs_set_tree_address;
46 static OSSL_SLH_ADRS_FUNC_set_type_and_clear slh_adrs_set_type_and_clear;
47 static OSSL_SLH_ADRS_FUNC_set_keypair_address slh_adrs_set_keypair_address;
48 static OSSL_SLH_ADRS_FUNC_copy_keypair_address slh_adrs_copy_keypair_address;
49 static OSSL_SLH_ADRS_FUNC_set_chain_address slh_adrs_set_chain_address;
50 static OSSL_SLH_ADRS_FUNC_set_hash_address slh_adrs_set_hash_address;
51 static OSSL_SLH_ADRS_FUNC_zero slh_adrs_zero;
52 static OSSL_SLH_ADRS_FUNC_copy slh_adrs_copy;
53 
54 static OSSL_SLH_ADRS_FUNC_set_layer_address slh_adrsc_set_layer_address;
55 static OSSL_SLH_ADRS_FUNC_set_tree_address slh_adrsc_set_tree_address;
56 static OSSL_SLH_ADRS_FUNC_set_type_and_clear slh_adrsc_set_type_and_clear;
57 static OSSL_SLH_ADRS_FUNC_set_keypair_address slh_adrsc_set_keypair_address;
58 static OSSL_SLH_ADRS_FUNC_copy_keypair_address slh_adrsc_copy_keypair_address;
59 static OSSL_SLH_ADRS_FUNC_set_chain_address slh_adrsc_set_chain_address;
60 static OSSL_SLH_ADRS_FUNC_set_hash_address slh_adrsc_set_hash_address;
61 static OSSL_SLH_ADRS_FUNC_zero slh_adrsc_zero;
62 static OSSL_SLH_ADRS_FUNC_copy slh_adrsc_copy;
63 
64 /*
65  * The non compressed versions of the ADRS functions use 32 bytes
66  * This is only used by SHAKE.
67  */
slh_adrs_set_layer_address(uint8_t * adrs,uint32_t layer)68 static void slh_adrs_set_layer_address(uint8_t *adrs, uint32_t layer)
69 {
70     OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_LAYER_ADR, layer);
71 }
slh_adrs_set_tree_address(uint8_t * adrs,uint64_t address)72 static void slh_adrs_set_tree_address(uint8_t *adrs, uint64_t address)
73 {
74     /*
75      * There are 12 bytes reserved for this - but the largest number
76      * used by the parameter sets is only 64 bits. Because this is BE the
77      * first 4 of the 12 bytes will be zeros. This assumes that the 4 bytes
78      * are zero initially.
79      */
80     OPENSSL_store_u64_be(adrs + SLH_ADRS_OFF_TREE_ADR + 4, address);
81 }
slh_adrs_set_type_and_clear(uint8_t * adrs,uint32_t type)82 static void slh_adrs_set_type_and_clear(uint8_t *adrs, uint32_t type)
83 {
84     OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_TYPE, type);
85     memset(adrs + SLH_ADRS_OFF_TYPE + SLH_ADRS_SIZE_TYPE, 0, SLH_ADRS_SIZE_TYPECLEAR);
86 }
slh_adrs_set_keypair_address(uint8_t * adrs,uint32_t in)87 static void slh_adrs_set_keypair_address(uint8_t *adrs, uint32_t in)
88 {
89     OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_KEYPAIR_ADDR, in);
90 }
slh_adrs_copy_keypair_address(uint8_t * dst,const uint8_t * src)91 static void slh_adrs_copy_keypair_address(uint8_t *dst, const uint8_t *src)
92 {
93     memcpy(dst + SLH_ADRS_OFF_KEYPAIR_ADDR, src + SLH_ADRS_OFF_KEYPAIR_ADDR,
94            SLH_ADRS_SIZE_KEYPAIR_ADDR);
95 }
slh_adrs_set_chain_address(uint8_t * adrs,uint32_t in)96 static void slh_adrs_set_chain_address(uint8_t *adrs, uint32_t in)
97 {
98     OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_CHAIN_ADDR, in);
99 }
slh_adrs_set_hash_address(uint8_t * adrs,uint32_t in)100 static void slh_adrs_set_hash_address(uint8_t *adrs, uint32_t in)
101 {
102     OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_HASH_ADDR, in);
103 }
slh_adrs_zero(uint8_t * adrs)104 static void slh_adrs_zero(uint8_t *adrs)
105 {
106     memset(adrs, 0, SLH_ADRS_SIZE);
107 }
slh_adrs_copy(uint8_t * dst,const uint8_t * src)108 static void slh_adrs_copy(uint8_t *dst, const uint8_t *src)
109 {
110     memcpy(dst, src, SLH_ADRS_SIZE);
111 }
112 
113 /* Compressed versions of ADRS functions See Table 3 */
slh_adrsc_set_layer_address(uint8_t * adrsc,uint32_t layer)114 static void slh_adrsc_set_layer_address(uint8_t *adrsc, uint32_t layer)
115 {
116     adrsc[SLH_ADRSC_OFF_LAYER_ADR] = (uint8_t)layer;
117 }
slh_adrsc_set_tree_address(uint8_t * adrsc,uint64_t in)118 static void slh_adrsc_set_tree_address(uint8_t *adrsc, uint64_t in)
119 {
120     OPENSSL_store_u64_be(adrsc + SLH_ADRSC_OFF_TREE_ADR, in);
121 }
slh_adrsc_set_type_and_clear(uint8_t * adrsc,uint32_t type)122 static void slh_adrsc_set_type_and_clear(uint8_t *adrsc, uint32_t type)
123 {
124     adrsc[SLH_ADRSC_OFF_TYPE] = (uint8_t)type;
125     memset(adrsc + SLH_ADRSC_OFF_TYPE + SLH_ADRSC_SIZE_TYPE, 0, SLH_ADRSC_SIZE_TYPECLEAR);
126 }
slh_adrsc_set_keypair_address(uint8_t * adrsc,uint32_t in)127 static void slh_adrsc_set_keypair_address(uint8_t *adrsc, uint32_t in)
128 {
129     OPENSSL_store_u32_be(adrsc + SLH_ADRSC_OFF_KEYPAIR_ADDR, in);
130 }
slh_adrsc_copy_keypair_address(uint8_t * dst,const uint8_t * src)131 static void slh_adrsc_copy_keypair_address(uint8_t *dst, const uint8_t *src)
132 {
133     memcpy(dst + SLH_ADRSC_OFF_KEYPAIR_ADDR, src + SLH_ADRSC_OFF_KEYPAIR_ADDR,
134            SLH_ADRSC_SIZE_KEYPAIR_ADDR);
135 }
slh_adrsc_set_chain_address(uint8_t * adrsc,uint32_t in)136 static void slh_adrsc_set_chain_address(uint8_t *adrsc, uint32_t in)
137 {
138     OPENSSL_store_u32_be(adrsc + SLH_ADRSC_OFF_CHAIN_ADDR, in);
139 }
slh_adrsc_set_hash_address(uint8_t * adrsc,uint32_t in)140 static void slh_adrsc_set_hash_address(uint8_t *adrsc, uint32_t in)
141 {
142     OPENSSL_store_u32_be(adrsc + SLH_ADRSC_OFF_HASH_ADDR, in);
143 }
slh_adrsc_zero(uint8_t * adrsc)144 static void slh_adrsc_zero(uint8_t *adrsc)
145 {
146     memset(adrsc, 0, SLH_ADRSC_SIZE);
147 }
slh_adrsc_copy(uint8_t * dst,const uint8_t * src)148 static void slh_adrsc_copy(uint8_t *dst, const uint8_t *src)
149 {
150     memcpy(dst, src, SLH_ADRSC_SIZE);
151 }
152 
ossl_slh_get_adrs_fn(int is_compressed)153 const SLH_ADRS_FUNC *ossl_slh_get_adrs_fn(int is_compressed)
154 {
155     static const SLH_ADRS_FUNC methods[] = {
156         {
157             slh_adrs_set_layer_address,
158             slh_adrs_set_tree_address,
159             slh_adrs_set_type_and_clear,
160             slh_adrs_set_keypair_address,
161             slh_adrs_copy_keypair_address,
162             slh_adrs_set_chain_address,
163             slh_adrs_set_tree_height,
164             slh_adrs_set_hash_address,
165             slh_adrs_set_tree_index,
166             slh_adrs_zero,
167             slh_adrs_copy,
168         },
169         {
170             slh_adrsc_set_layer_address,
171             slh_adrsc_set_tree_address,
172             slh_adrsc_set_type_and_clear,
173             slh_adrsc_set_keypair_address,
174             slh_adrsc_copy_keypair_address,
175             slh_adrsc_set_chain_address,
176             slh_adrsc_set_tree_height,
177             slh_adrsc_set_hash_address,
178             slh_adrsc_set_tree_index,
179             slh_adrsc_zero,
180             slh_adrsc_copy,
181         }
182     };
183     return &methods[is_compressed == 0 ? 0 : 1];
184 }
185