/src/boringssl/crypto/fipsmodule/keccak/internal.h
Line | Count | Source |
1 | | // Copyright 2023 The BoringSSL Authors |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_KECCAK_INTERNAL_H |
16 | | #define OPENSSL_HEADER_CRYPTO_FIPSMODULE_KECCAK_INTERNAL_H |
17 | | |
18 | | #include <openssl/base.h> |
19 | | |
20 | | #include "../../internal.h" |
21 | | |
22 | | |
23 | | BSSL_NAMESPACE_BEGIN |
24 | | |
25 | | #define BITS_TO_BYTES(BITS) ((BITS) / 8) |
26 | | #define SHA3_256_DIGEST_LENGTH BITS_TO_BYTES(256) |
27 | | #define SHA3_384_DIGEST_LENGTH BITS_TO_BYTES(384) |
28 | | #define SHA3_512_DIGEST_LENGTH BITS_TO_BYTES(512) |
29 | | #define SHA3_BLOCK_SIZE(BITS) BITS_TO_BYTES(1600 - 2 * (BITS)) |
30 | | #define SHA3_256_CBLOCK SHA3_BLOCK_SIZE(256) |
31 | | #define SHA3_384_CBLOCK SHA3_BLOCK_SIZE(384) |
32 | | #define SHA3_512_CBLOCK SHA3_BLOCK_SIZE(512) |
33 | | |
34 | | enum boringssl_keccak_config_t : int32_t { |
35 | | boringssl_sha3_256, |
36 | | boringssl_sha3_384, |
37 | | boringssl_sha3_512, |
38 | | boringssl_shake128, |
39 | | boringssl_shake256, |
40 | | boringssl_turboshake128, |
41 | | boringssl_turboshake256, |
42 | | boringssl_cshake128, |
43 | | boringssl_cshake256, |
44 | | }; |
45 | | |
46 | | enum boringssl_keccak_phase_t : int32_t { |
47 | | boringssl_keccak_phase_absorb, |
48 | | boringssl_keccak_phase_squeeze, |
49 | | }; |
50 | | |
51 | | struct BORINGSSL_keccak_st { |
52 | | // Note: the state with 64-bit integers comes first so that the size of this |
53 | | // struct is easy to compute on all architectures without padding surprises |
54 | | // due to alignment. |
55 | | uint64_t state[25]; |
56 | | enum boringssl_keccak_config_t config; |
57 | | enum boringssl_keccak_phase_t phase; |
58 | | size_t required_out_len; |
59 | | size_t rate_bytes; |
60 | | size_t absorb_offset; |
61 | | size_t squeeze_offset; |
62 | | }; |
63 | | |
64 | | // BORINGSSL_keccak hashes `in_len` bytes from `in` and writes `out_len` bytes |
65 | | // of output to `out`. If the `config` specifies a fixed-output function, like |
66 | | // SHA3-256, then `out_len` must be the correct length for that function. The |
67 | | // cSHAKE configurations are only valid with the BORINGSSL_cshake functions. |
68 | | OPENSSL_EXPORT void BORINGSSL_keccak(uint8_t *out, size_t out_len, |
69 | | const uint8_t *in, size_t in_len, |
70 | | enum boringssl_keccak_config_t config); |
71 | | |
72 | | // BORINGSSL_keccak_init prepares `ctx` for absorbing. If the `config` specifies |
73 | | // a fixed-output function, like SHA3-256, then the output must be squeezed in a |
74 | | // single call to `BORINGSSL_keccak_squeeze`. In that case, it is recommended to |
75 | | // use `BORINGSSL_keccak` if the input can be absorbed in a single call. |
76 | | OPENSSL_EXPORT void BORINGSSL_keccak_init( |
77 | | struct BORINGSSL_keccak_st *ctx, enum boringssl_keccak_config_t config); |
78 | | |
79 | | // BORINGSSL_cshake_init prepares `ctx` for cSHAKE, including absorbing the |
80 | | // function-name and customization strings. `config` must be |
81 | | // `boringssl_cshake128` or `boringssl_cshake256`. The message may then be |
82 | | // absorbed and output squeezed with the usual Keccak functions. |
83 | | OPENSSL_EXPORT void BORINGSSL_cshake_init(struct BORINGSSL_keccak_st *ctx, |
84 | | enum boringssl_keccak_config_t config, |
85 | | const uint8_t *function_name, |
86 | | size_t function_name_len, |
87 | | const uint8_t *customization, |
88 | | size_t customization_len); |
89 | | |
90 | | // BORINGSSL_cshake is the one-shot form of BORINGSSL_cshake_init. |
91 | | OPENSSL_EXPORT void BORINGSSL_cshake(uint8_t *out, size_t out_len, |
92 | | const uint8_t *in, size_t in_len, |
93 | | enum boringssl_keccak_config_t config, |
94 | | const uint8_t *function_name, |
95 | | size_t function_name_len, |
96 | | const uint8_t *customization, |
97 | | size_t customization_len); |
98 | | |
99 | | // BORINGSSL_keccak_absorb absorbs `in_len` bytes from `in`. |
100 | | OPENSSL_EXPORT void BORINGSSL_keccak_absorb(struct BORINGSSL_keccak_st *ctx, |
101 | | const uint8_t *in, size_t in_len); |
102 | | |
103 | | // BORINGSSL_keccak_squeeze writes `out_len` bytes to `out` from `ctx`. If the |
104 | | // configuration previously passed in `BORINGSSL_keccak_init` specifies a |
105 | | // fixed-output function, then a single call to `BORINGSSL_keccak_squeeze` is |
106 | | // allowed, where `out_len` must be the correct length for that function. |
107 | | OPENSSL_EXPORT void BORINGSSL_keccak_squeeze(struct BORINGSSL_keccak_st *ctx, |
108 | | uint8_t *out, size_t out_len); |
109 | | |
110 | | #if defined(__has_attribute) |
111 | | #if __has_attribute(vector_size) |
112 | | |
113 | | #define HAVE_KECCAK_X2 |
114 | | |
115 | | #if defined(OPENSSL_AARCH64) |
116 | | #define HAVE_KECCAK_X4 |
117 | | #define KECCAK_X4_TARGET |
118 | | #endif |
119 | | |
120 | | #if defined(OPENSSL_X86_64) |
121 | | #define HAVE_KECCAK_X4 |
122 | | #define KECCAK_X4_TARGET __attribute__((target("avx2"))) |
123 | | #endif |
124 | | |
125 | | #endif // vector_size |
126 | | #endif // __has_attribute |
127 | | |
128 | | #if defined(HAVE_KECCAK_X2) |
129 | | // BORINGSSL_keccak_squeeze_x2 performs BORINGSSL_keccak_squeeze in parallel |
130 | | // with two same-length outputs. The contexts must be in equivalent state (i.e. |
131 | | // same config, same amount of bytes absorbed and squeezed). |
132 | | // This function is not compatible with cSHAKE nor TurboSHAKE. |
133 | | OPENSSL_EXPORT void BORINGSSL_keccak_squeeze_x2( |
134 | | struct BORINGSSL_keccak_st ctx[2], uint8_t *outs[2], size_t out_len); |
135 | | |
136 | | // BORINGSSL_keccak_short_x2 performs BORINGSSL_keccak in parallel on two |
137 | | // same-length strings with same-length outputs. `in_len` must be less than 72 |
138 | | // (or actually `rate_bytes`). |
139 | | // This function is not compatible with cSHAKE nor TurboSHAKE. |
140 | | OPENSSL_EXPORT void BORINGSSL_keccak_short_x2( |
141 | | uint8_t *outs[2], size_t out_len, const uint8_t *ins[2], size_t in_len, |
142 | | enum boringssl_keccak_config_t config); |
143 | | #endif |
144 | | |
145 | | #if defined(HAVE_KECCAK_X4) |
146 | | // BORINGSSL_have_keccak_x4 needs to return true before using any of the _x4 |
147 | | // variants here, as they may require additional CPU features. |
148 | | // This function is not compatible with cSHAKE nor TurboSHAKE. |
149 | 158k | inline bool BORINGSSL_have_keccak_x4() { |
150 | 158k | #if defined(OPENSSL_X86_64) |
151 | 158k | return CRYPTO_is_AVX2_capable(); |
152 | | #else |
153 | | return true; |
154 | | #endif |
155 | 158k | } |
156 | | |
157 | | // BORINGSSL_keccak_squeeze_x4 performs BORINGSSL_keccak_squeeze in parallel |
158 | | // with four same-length outputs. The contexts must be in equivalent state (i.e. |
159 | | // same config, same amount of bytes absorbed and squeezed). |
160 | | // This function is not compatible with cSHAKE nor TurboSHAKE. |
161 | | OPENSSL_EXPORT void BORINGSSL_keccak_squeeze_x4( |
162 | | struct BORINGSSL_keccak_st ctx[4], uint8_t *outs[4], size_t out_len); |
163 | | |
164 | | // BORINGSSL_keccak_short_x4 performs BORINGSSL_keccak in parallel on four |
165 | | // same-length strings with same-length outputs. in_len must be less than 72 |
166 | | // (or actually `rate_bytes`). |
167 | | // This function is not compatible with cSHAKE nor TurboSHAKE. |
168 | | OPENSSL_EXPORT void BORINGSSL_keccak_short_x4( |
169 | | uint8_t *outs[4], size_t out_len, const uint8_t *ins[4], size_t in_len, |
170 | | enum boringssl_keccak_config_t config); |
171 | | #endif |
172 | | |
173 | | BSSL_NAMESPACE_END |
174 | | |
175 | | #endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_KECCAK_INTERNAL_H |