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