/src/openssl/crypto/slh_dsa/slh_adrs.c
Line | Count | Source |
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 | 3.57k | #define SLH_ADRS_OFF_LAYER_ADR 0 |
15 | 3.61k | #define SLH_ADRS_OFF_TREE_ADR 4 |
16 | 54.8M | #define SLH_ADRS_OFF_TYPE 16 |
17 | 25.0M | #define SLH_ADRS_OFF_KEYPAIR_ADDR 20 |
18 | 40.0M | #define SLH_ADRS_OFF_CHAIN_ADDR 24 |
19 | 152M | #define SLH_ADRS_OFF_HASH_ADDR 28 |
20 | | #define SLH_ADRS_OFF_TREE_INDEX SLH_ADRS_OFF_HASH_ADDR |
21 | 42.1M | #define SLH_ADRS_SIZE_TYPE 4 |
22 | | /* Number of bytes after type to clear */ |
23 | 29.4M | #define SLH_ADRS_SIZE_TYPECLEAR SLH_ADRS_SIZE - (SLH_ADRS_OFF_TYPE + SLH_ADRS_SIZE_TYPE) |
24 | 28.6M | #define SLH_ADRS_SIZE_KEYPAIR_ADDR 4 |
25 | | |
26 | | /* See FIPS 205 - Section 11.2 Table 3 Compressed Addresses */ |
27 | 7.13k | #define SLH_ADRSC_OFF_LAYER_ADR 0 |
28 | 7.22k | #define SLH_ADRSC_OFF_TREE_ADR 1 |
29 | 33.3M | #define SLH_ADRSC_OFF_TYPE 9 |
30 | 32.6M | #define SLH_ADRSC_OFF_KEYPAIR_ADDR 10 |
31 | 56.2M | #define SLH_ADRSC_OFF_CHAIN_ADDR 14 |
32 | 230M | #define SLH_ADRSC_OFF_HASH_ADDR 18 |
33 | | #define SLH_ADRSC_OFF_TREE_INDEX SLH_ADRSC_OFF_HASH_ADDR |
34 | 16.6M | #define SLH_ADRSC_SIZE_TYPE 1 |
35 | 16.6M | #define SLH_ADRSC_SIZE_TYPECLEAR SLH_ADRS_SIZE_TYPECLEAR |
36 | 16.2M | #define SLH_ADRSC_SIZE_KEYPAIR_ADDR SLH_ADRS_SIZE_KEYPAIR_ADDR |
37 | | |
38 | 79.4k | #define slh_adrs_set_tree_height slh_adrs_set_chain_address |
39 | 79.4k | #define slh_adrs_set_tree_index slh_adrs_set_hash_address |
40 | | |
41 | 79.4k | #define slh_adrsc_set_tree_height slh_adrsc_set_chain_address |
42 | 79.4k | #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 | | */ |
68 | | static void slh_adrs_set_layer_address(uint8_t *adrs, uint32_t layer) |
69 | 3.57k | { |
70 | 3.57k | OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_LAYER_ADR, layer); |
71 | 3.57k | } |
72 | | static void slh_adrs_set_tree_address(uint8_t *adrs, uint64_t address) |
73 | 3.61k | { |
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 | 3.61k | OPENSSL_store_u64_be(adrs + SLH_ADRS_OFF_TREE_ADR + 4, address); |
81 | 3.61k | } |
82 | | static void slh_adrs_set_type_and_clear(uint8_t *adrs, uint32_t type) |
83 | 12.7M | { |
84 | 12.7M | OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_TYPE, type); |
85 | 12.7M | memset(adrs + SLH_ADRS_OFF_TYPE + SLH_ADRS_SIZE_TYPE, 0, SLH_ADRS_SIZE_TYPECLEAR); |
86 | 12.7M | } |
87 | | static void slh_adrs_set_keypair_address(uint8_t *adrs, uint32_t in) |
88 | 144k | { |
89 | 144k | OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_KEYPAIR_ADDR, in); |
90 | 144k | } |
91 | | static void slh_adrs_copy_keypair_address(uint8_t *dst, const uint8_t *src) |
92 | 12.4M | { |
93 | 12.4M | memcpy(dst + SLH_ADRS_OFF_KEYPAIR_ADDR, src + SLH_ADRS_OFF_KEYPAIR_ADDR, |
94 | 12.4M | SLH_ADRS_SIZE_KEYPAIR_ADDR); |
95 | 12.4M | } |
96 | | static void slh_adrs_set_chain_address(uint8_t *adrs, uint32_t in) |
97 | 40.0M | { |
98 | 40.0M | OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_CHAIN_ADDR, in); |
99 | 40.0M | } |
100 | | static void slh_adrs_set_hash_address(uint8_t *adrs, uint32_t in) |
101 | 152M | { |
102 | 152M | OPENSSL_store_u32_be(adrs + SLH_ADRS_OFF_HASH_ADDR, in); |
103 | 152M | } |
104 | | static void slh_adrs_zero(uint8_t *adrs) |
105 | 590 | { |
106 | 590 | memset(adrs, 0, SLH_ADRS_SIZE); |
107 | 590 | } |
108 | | static void slh_adrs_copy(uint8_t *dst, const uint8_t *src) |
109 | 12.4M | { |
110 | 12.4M | memcpy(dst, src, SLH_ADRS_SIZE); |
111 | 12.4M | } |
112 | | |
113 | | /* Compressed versions of ADRS functions See Table 3 */ |
114 | | static void slh_adrsc_set_layer_address(uint8_t *adrsc, uint32_t layer) |
115 | 7.13k | { |
116 | 7.13k | adrsc[SLH_ADRSC_OFF_LAYER_ADR] = (uint8_t)layer; |
117 | 7.13k | } |
118 | | static void slh_adrsc_set_tree_address(uint8_t *adrsc, uint64_t in) |
119 | 7.22k | { |
120 | 7.22k | OPENSSL_store_u64_be(adrsc + SLH_ADRSC_OFF_TREE_ADR, in); |
121 | 7.22k | } |
122 | | static void slh_adrsc_set_type_and_clear(uint8_t *adrsc, uint32_t type) |
123 | 16.6M | { |
124 | 16.6M | adrsc[SLH_ADRSC_OFF_TYPE] = (uint8_t)type; |
125 | 16.6M | memset(adrsc + SLH_ADRSC_OFF_TYPE + SLH_ADRSC_SIZE_TYPE, 0, SLH_ADRSC_SIZE_TYPECLEAR); |
126 | 16.6M | } |
127 | | static void slh_adrsc_set_keypair_address(uint8_t *adrsc, uint32_t in) |
128 | 251k | { |
129 | 251k | OPENSSL_store_u32_be(adrsc + SLH_ADRSC_OFF_KEYPAIR_ADDR, in); |
130 | 251k | } |
131 | | static void slh_adrsc_copy_keypair_address(uint8_t *dst, const uint8_t *src) |
132 | 16.2M | { |
133 | 16.2M | memcpy(dst + SLH_ADRSC_OFF_KEYPAIR_ADDR, src + SLH_ADRSC_OFF_KEYPAIR_ADDR, |
134 | 16.2M | SLH_ADRSC_SIZE_KEYPAIR_ADDR); |
135 | 16.2M | } |
136 | | static void slh_adrsc_set_chain_address(uint8_t *adrsc, uint32_t in) |
137 | 56.2M | { |
138 | 56.2M | OPENSSL_store_u32_be(adrsc + SLH_ADRSC_OFF_CHAIN_ADDR, in); |
139 | 56.2M | } |
140 | | static void slh_adrsc_set_hash_address(uint8_t *adrsc, uint32_t in) |
141 | 230M | { |
142 | 230M | OPENSSL_store_u32_be(adrsc + SLH_ADRSC_OFF_HASH_ADDR, in); |
143 | 230M | } |
144 | | static void slh_adrsc_zero(uint8_t *adrsc) |
145 | 1.12k | { |
146 | 1.12k | memset(adrsc, 0, SLH_ADRSC_SIZE); |
147 | 1.12k | } |
148 | | static void slh_adrsc_copy(uint8_t *dst, const uint8_t *src) |
149 | 16.2M | { |
150 | 16.2M | memcpy(dst, src, SLH_ADRSC_SIZE); |
151 | 16.2M | } |
152 | | |
153 | | const SLH_ADRS_FUNC *ossl_slh_get_adrs_fn(int is_compressed) |
154 | 79.4k | { |
155 | 79.4k | static const SLH_ADRS_FUNC methods[] = { |
156 | 79.4k | { |
157 | 79.4k | slh_adrs_set_layer_address, |
158 | 79.4k | slh_adrs_set_tree_address, |
159 | 79.4k | slh_adrs_set_type_and_clear, |
160 | 79.4k | slh_adrs_set_keypair_address, |
161 | 79.4k | slh_adrs_copy_keypair_address, |
162 | 79.4k | slh_adrs_set_chain_address, |
163 | 79.4k | slh_adrs_set_tree_height, |
164 | 79.4k | slh_adrs_set_hash_address, |
165 | 79.4k | slh_adrs_set_tree_index, |
166 | 79.4k | slh_adrs_zero, |
167 | 79.4k | slh_adrs_copy, |
168 | 79.4k | }, |
169 | 79.4k | { |
170 | 79.4k | slh_adrsc_set_layer_address, |
171 | 79.4k | slh_adrsc_set_tree_address, |
172 | 79.4k | slh_adrsc_set_type_and_clear, |
173 | 79.4k | slh_adrsc_set_keypair_address, |
174 | 79.4k | slh_adrsc_copy_keypair_address, |
175 | 79.4k | slh_adrsc_set_chain_address, |
176 | 79.4k | slh_adrsc_set_tree_height, |
177 | 79.4k | slh_adrsc_set_hash_address, |
178 | 79.4k | slh_adrsc_set_tree_index, |
179 | 79.4k | slh_adrsc_zero, |
180 | 79.4k | slh_adrsc_copy, |
181 | 79.4k | } |
182 | 79.4k | }; |
183 | 79.4k | return &methods[is_compressed == 0 ? 0 : 1]; |
184 | 79.4k | } |