]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /********************************************************************** |
2 | Copyright(c) 2011-2016 Intel Corporation All rights reserved. | |
3 | ||
4 | Redistribution and use in source and binary forms, with or without | |
1e59de90 | 5 | modification, are permitted provided that the following conditions |
7c673cae FG |
6 | are met: |
7 | * Redistributions of source code must retain the above copyright | |
8 | notice, this list of conditions and the following disclaimer. | |
9 | * Redistributions in binary form must reproduce the above copyright | |
10 | notice, this list of conditions and the following disclaimer in | |
11 | the documentation and/or other materials provided with the | |
12 | distribution. | |
13 | * Neither the name of Intel Corporation nor the names of its | |
14 | contributors may be used to endorse or promote products derived | |
15 | from this software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | **********************************************************************/ | |
29 | ||
30 | #ifndef _SHA512_MB_H_ | |
31 | #define _SHA512_MB_H_ | |
32 | ||
33 | /** | |
34 | * @file sha512_mb.h | |
35 | * @brief Single/Multi-buffer CTX API SHA512 function prototypes and structures | |
36 | * | |
37 | * Interface for single and multi-buffer SHA512 functions | |
38 | * | |
39 | * <b> Single/Multi-buffer SHA512 Entire or First-Update..Update-Last </b> | |
40 | * | |
41 | * The interface to this single/multi-buffer hashing code is carried out through the | |
42 | * context-level (CTX) init, submit and flush functions and the SHA512_HASH_CTX_MGR and | |
43 | * SHA512_HASH_CTX objects. Numerous SHA512_HASH_CTX objects may be instantiated by the | |
44 | * application for use with a single SHA512_HASH_CTX_MGR. | |
45 | * | |
46 | * The CTX interface functions carry out the initialization and padding of the jobs | |
47 | * entered by the user and add them to the multi-buffer manager. The lower level "scheduler" | |
48 | * layer then processes the jobs in an out-of-order manner. The scheduler layer functions | |
49 | * are internal and are not intended to be invoked directly. Jobs can be submitted | |
50 | * to a CTX as a complete buffer to be hashed, using the HASH_ENTIRE flag, or as partial | |
51 | * jobs which can be started using the HASH_FIRST flag, and later resumed or finished | |
52 | * using the HASH_UPDATE and HASH_LAST flags respectively. | |
53 | * | |
54 | * <b>Note:</b> The submit function does not require data buffers to be block sized. | |
55 | * | |
56 | * The SHA512 CTX interface functions are available for 5 architectures: multi-buffer SSE, | |
57 | * AVX, AVX2, AVX512 and single-buffer SSE4 (which is used in the same way as the | |
58 | * multi-buffer code). In addition, a multibinary interface is provided, which selects the | |
59 | * appropriate architecture-specific function at runtime. This multibinary interface | |
60 | * selects the single buffer SSE4 functions when the platform is detected to be Silvermont. | |
61 | * | |
62 | * <b>Usage:</b> The application creates a SHA512_HASH_CTX_MGR object and initializes it | |
63 | * with a call to sha512_ctx_mgr_init*() function, where henceforth "*" stands for the | |
64 | * relevant suffix for each architecture; _sse, _avx, _avx2, _avx512(or no suffix for the | |
65 | * multibinary version). The SHA512_HASH_CTX_MGR object will be used to schedule processor | |
66 | * resources, with up to 2 SHA512_HASH_CTX objects (or 4 in the AVX2 case, 8 in the AVX512 | |
67 | * case) being processed at a time. | |
68 | * | |
69 | * Each SHA512_HASH_CTX must be initialized before first use by the hash_ctx_init macro | |
70 | * defined in multi_buffer.h. After initialization, the application may begin computing | |
71 | * a hash by giving the SHA512_HASH_CTX to a SHA512_HASH_CTX_MGR using the submit functions | |
72 | * sha512_ctx_mgr_submit*() with the HASH_FIRST flag set. When the SHA512_HASH_CTX is | |
73 | * returned to the application (via this or a later call to sha512_ctx_mgr_submit*() or | |
74 | * sha512_ctx_mgr_flush*()), the application can then re-submit it with another call to | |
75 | * sha512_ctx_mgr_submit*(), but without the HASH_FIRST flag set. | |
76 | * | |
77 | * Ideally, on the last buffer for that hash, sha512_ctx_mgr_submit_sse is called with | |
78 | * HASH_LAST, although it is also possible to submit the hash with HASH_LAST and a zero | |
79 | * length if necessary. When a SHA512_HASH_CTX is returned after having been submitted with | |
80 | * HASH_LAST, it will contain a valid hash. The SHA512_HASH_CTX can be reused immediately | |
81 | * by submitting with HASH_FIRST. | |
82 | * | |
83 | * For example, you would submit hashes with the following flags for the following numbers | |
84 | * of buffers: | |
85 | * <ul> | |
86 | * <li> one buffer: HASH_FIRST | HASH_LAST (or, equivalently, HASH_ENTIRE) | |
87 | * <li> two buffers: HASH_FIRST, HASH_LAST | |
88 | * <li> three buffers: HASH_FIRST, HASH_UPDATE, HASH_LAST | |
89 | * etc. | |
90 | * </ul> | |
91 | * | |
92 | * The order in which SHA512_CTX objects are returned is in general different from the order | |
93 | * in which they are submitted. | |
94 | * | |
95 | * A few possible error conditions exist: | |
96 | * <ul> | |
97 | * <li> Submitting flags other than the allowed entire/first/update/last values | |
98 | * <li> Submitting a context that is currently being managed by a SHA512_HASH_CTX_MGR. (Note: | |
99 | * This error case is not applicable to the single buffer SSE4 version) | |
100 | * <li> Submitting a context after HASH_LAST is used but before HASH_FIRST is set. | |
101 | * </ul> | |
102 | * | |
103 | * These error conditions are reported by returning the SHA512_HASH_CTX immediately after | |
104 | * a submit with its error member set to a non-zero error code (defined in | |
105 | * multi_buffer.h). No changes are made to the SHA512_HASH_CTX_MGR in the case of an | |
106 | * error; no processing is done for other hashes. | |
107 | * | |
108 | */ | |
109 | ||
110 | #include <stdint.h> | |
111 | #include "multi_buffer.h" | |
112 | #include "types.h" | |
113 | ||
114 | #ifndef _MSC_VER | |
115 | #include <stdbool.h> | |
116 | #endif | |
117 | ||
118 | #ifdef __cplusplus | |
119 | extern "C" { | |
120 | #endif | |
121 | ||
122 | // Hash Constants and Typedefs | |
123 | #define SHA512_DIGEST_NWORDS 8 | |
124 | #define SHA512_MAX_LANES 8 | |
125 | #define SHA512_X4_LANES 4 | |
126 | #define SHA512_MIN_LANES 2 | |
127 | #define SHA512_BLOCK_SIZE 128 | |
128 | #define SHA512_LOG2_BLOCK_SIZE 7 | |
129 | #define SHA512_PADLENGTHFIELD_SIZE 16 | |
130 | #define SHA512_INITIAL_DIGEST \ | |
131 | 0x6a09e667f3bcc908,0xbb67ae8584caa73b,0x3c6ef372fe94f82b,0xa54ff53a5f1d36f1, \ | |
132 | 0x510e527fade682d1,0x9b05688c2b3e6c1f,0x1f83d9abfb41bd6b,0x5be0cd19137e2179 | |
133 | ||
134 | ||
135 | typedef uint64_t sha512_digest_array[SHA512_DIGEST_NWORDS][SHA512_MAX_LANES]; | |
136 | typedef uint64_t SHA512_WORD_T; | |
137 | ||
138 | /** @brief Scheduler layer - Holds info describing a single SHA512 job for the multi-buffer manager */ | |
139 | ||
140 | typedef struct { | |
141 | uint8_t* buffer; //!< pointer to data buffer for this job | |
142 | uint64_t len; //!< length of buffer for this job in blocks. | |
143 | DECLARE_ALIGNED(uint64_t result_digest[SHA512_DIGEST_NWORDS], 64); | |
144 | JOB_STS status; //!< output job status | |
145 | void* user_data; //!< pointer for user's job-related data | |
146 | } SHA512_JOB; | |
147 | ||
148 | /** @brief Scheduler layer - Holds arguments for submitted SHA512 job */ | |
149 | ||
150 | typedef struct { | |
151 | sha512_digest_array digest; | |
152 | uint8_t* data_ptr[SHA512_MAX_LANES]; | |
153 | } SHA512_MB_ARGS_X8; | |
154 | ||
155 | /** @brief Scheduler layer - Lane data */ | |
156 | ||
157 | typedef struct { | |
158 | SHA512_JOB *job_in_lane; | |
159 | } SHA512_LANE_DATA; | |
160 | ||
161 | /** @brief Scheduler layer - Holds state for multi-buffer SHA512 jobs */ | |
162 | ||
163 | typedef struct { | |
164 | SHA512_MB_ARGS_X8 args; | |
165 | uint64_t lens[SHA512_MAX_LANES]; | |
166 | uint64_t unused_lanes; //!< each byte is index (00, 01 or 00...03) of unused lanes, byte 2 or 4 is set to FF as a flag | |
167 | SHA512_LANE_DATA ldata[SHA512_MAX_LANES]; | |
168 | uint32_t num_lanes_inuse; | |
169 | } SHA512_MB_JOB_MGR; | |
170 | ||
171 | /** @brief Context layer - Holds state for multi-buffer SHA512 jobs */ | |
172 | ||
173 | typedef struct { | |
174 | SHA512_MB_JOB_MGR mgr; | |
175 | } SHA512_HASH_CTX_MGR; | |
176 | ||
177 | /** @brief Context layer - Holds info describing a single SHA512 job for the multi-buffer CTX manager */ | |
178 | ||
179 | typedef struct { | |
180 | SHA512_JOB job; // Must be at struct offset 0. | |
181 | HASH_CTX_STS status; //!< Context status flag | |
182 | HASH_CTX_ERROR error; //!< Context error flag | |
1e59de90 | 183 | uint64_t total_length; //!< Running counter of length processed for this CTX's job |
7c673cae FG |
184 | const void* incoming_buffer; //!< pointer to data input buffer for this CTX's job |
185 | uint32_t incoming_buffer_length; //!< length of buffer for this job in bytes. | |
186 | uint8_t partial_block_buffer[SHA512_BLOCK_SIZE * 2]; //!< CTX partial blocks | |
187 | uint32_t partial_block_buffer_length; | |
188 | void* user_data; //!< pointer for user to keep any job-related data | |
189 | } SHA512_HASH_CTX; | |
190 | ||
191 | /******************************************************************* | |
192 | * Context level API function prototypes | |
193 | ******************************************************************/ | |
194 | ||
195 | /** | |
196 | * @brief Initialize the context level SHA512 multi-buffer manager structure. | |
197 | * @requires SSE4.1 | |
198 | * | |
199 | * @param mgr Structure holding context level state info | |
200 | * @returns void | |
201 | */ | |
202 | void sha512_ctx_mgr_init_sse (SHA512_HASH_CTX_MGR* mgr); | |
203 | ||
204 | /** | |
205 | * @brief Submit a new SHA512 job to the context level multi-buffer manager. | |
206 | * @requires SSE4.1 | |
207 | * | |
208 | * @param mgr Structure holding context level state info | |
209 | * @param ctx Structure holding ctx job info | |
210 | * @param buffer Pointer to buffer to be processed | |
211 | * @param len Length of buffer (in bytes) to be processed | |
212 | * @param flags Input flag specifying job type (first, update, last or entire) | |
213 | * @returns NULL if no jobs complete or pointer to jobs structure. | |
214 | */ | |
215 | SHA512_HASH_CTX* sha512_ctx_mgr_submit_sse (SHA512_HASH_CTX_MGR* mgr, SHA512_HASH_CTX* ctx, | |
216 | const void* buffer, uint32_t len, HASH_CTX_FLAG flags); | |
217 | ||
218 | /** | |
219 | * @brief Finish all submitted SHA512 jobs and return when complete. | |
220 | * @requires SSE4.1 | |
221 | * | |
222 | * @param mgr Structure holding context level state info | |
223 | * @returns NULL if no jobs to complete or pointer to jobs structure. | |
224 | */ | |
225 | SHA512_HASH_CTX* sha512_ctx_mgr_flush_sse (SHA512_HASH_CTX_MGR* mgr); | |
226 | ||
227 | /** | |
228 | * @brief Initialize the SHA512 multi-buffer manager structure. | |
229 | * @requires AVX | |
230 | * | |
231 | * @param mgr Structure holding context level state info | |
232 | * @returns void | |
233 | */ | |
234 | void sha512_ctx_mgr_init_avx (SHA512_HASH_CTX_MGR* mgr); | |
235 | ||
236 | /** | |
237 | * @brief Submit a new SHA512 job to the multi-buffer manager. | |
238 | * @requires AVX | |
239 | * | |
240 | * @param mgr Structure holding context level state info | |
241 | * @param ctx Structure holding ctx job info | |
242 | * @param buffer Pointer to buffer to be processed | |
243 | * @param len Length of buffer (in bytes) to be processed | |
244 | * @param flags Input flag specifying job type (first, update, last or entire) | |
245 | * @returns NULL if no jobs complete or pointer to jobs structure. | |
246 | */ | |
247 | SHA512_HASH_CTX* sha512_ctx_mgr_submit_avx (SHA512_HASH_CTX_MGR* mgr, SHA512_HASH_CTX* ctx, | |
248 | const void* buffer, uint32_t len, HASH_CTX_FLAG flags); | |
249 | ||
250 | /** | |
251 | * @brief Finish all submitted SHA512 jobs and return when complete. | |
252 | * @requires AVX | |
253 | * | |
254 | * @param mgr Structure holding context level state info | |
255 | * @returns NULL if no jobs to complete or pointer to jobs structure. | |
256 | */ | |
257 | SHA512_HASH_CTX* sha512_ctx_mgr_flush_avx (SHA512_HASH_CTX_MGR* mgr); | |
258 | ||
259 | /** | |
260 | * @brief Initialize the SHA512 multi-buffer manager structure. | |
261 | * @requires AVX2 | |
262 | * | |
263 | * @param mgr Structure holding context level state info | |
264 | * @returns void | |
265 | */ | |
266 | void sha512_ctx_mgr_init_avx2 (SHA512_HASH_CTX_MGR* mgr); | |
267 | ||
268 | /** | |
269 | * @brief Submit a new SHA512 job to the multi-buffer manager. | |
270 | * @requires AVX2 | |
271 | * | |
272 | * @param mgr Structure holding context level state info | |
273 | * @param ctx Structure holding ctx job info | |
274 | * @param buffer Pointer to buffer to be processed | |
275 | * @param len Length of buffer (in bytes) to be processed | |
276 | * @param flags Input flag specifying job type (first, update, last or entire) | |
277 | * @returns NULL if no jobs complete or pointer to jobs structure. | |
278 | */ | |
279 | SHA512_HASH_CTX* sha512_ctx_mgr_submit_avx2 (SHA512_HASH_CTX_MGR* mgr, SHA512_HASH_CTX* ctx, | |
280 | const void* buffer, uint32_t len, HASH_CTX_FLAG flags); | |
281 | ||
282 | /** | |
283 | * @brief Finish all submitted SHA512 jobs and return when complete. | |
284 | * @requires AVX2 | |
285 | * | |
286 | * @param mgr Structure holding context level state info | |
287 | * @returns NULL if no jobs to complete or pointer to jobs structure. | |
288 | */ | |
289 | SHA512_HASH_CTX* sha512_ctx_mgr_flush_avx2 (SHA512_HASH_CTX_MGR* mgr); | |
290 | ||
291 | /** | |
292 | * @brief Initialize the SHA512 multi-buffer manager structure. | |
293 | * @requires AVX512 | |
294 | * | |
295 | * @param mgr Structure holding context level state info | |
296 | * @returns void | |
297 | */ | |
298 | void sha512_ctx_mgr_init_avx512 (SHA512_HASH_CTX_MGR* mgr); | |
299 | ||
300 | /** | |
301 | * @brief Submit a new SHA512 job to the multi-buffer manager. | |
302 | * @requires AVX512 | |
303 | * | |
304 | * @param mgr Structure holding context level state info | |
305 | * @param ctx Structure holding ctx job info | |
306 | * @param buffer Pointer to buffer to be processed | |
307 | * @param len Length of buffer (in bytes) to be processed | |
308 | * @param flags Input flag specifying job type (first, update, last or entire) | |
309 | * @returns NULL if no jobs complete or pointer to jobs structure. | |
310 | */ | |
311 | SHA512_HASH_CTX* sha512_ctx_mgr_submit_avx512 (SHA512_HASH_CTX_MGR* mgr, SHA512_HASH_CTX* ctx, | |
312 | const void* buffer, uint32_t len, HASH_CTX_FLAG flags); | |
313 | ||
314 | /** | |
315 | * @brief Finish all submitted SHA512 jobs and return when complete. | |
316 | * @requires AVX512 | |
317 | * | |
318 | * @param mgr Structure holding context level state info | |
319 | * @returns NULL if no jobs to complete or pointer to jobs structure. | |
320 | */ | |
321 | SHA512_HASH_CTX* sha512_ctx_mgr_flush_avx512 (SHA512_HASH_CTX_MGR* mgr); | |
322 | ||
323 | /** | |
324 | * @brief Initialize the SHA512 multi-buffer manager structure. | |
325 | * @requires SSE4 | |
326 | * | |
327 | * @param mgr Structure holding context level state info | |
328 | * @returns void | |
329 | */ | |
330 | void sha512_ctx_mgr_init_sb_sse4 (SHA512_HASH_CTX_MGR* mgr); | |
331 | ||
332 | /** | |
333 | * @brief Submit a new SHA512 job to the multi-buffer manager. | |
334 | * @requires SSE4 | |
335 | * | |
336 | * @param mgr Structure holding context level state info | |
337 | * @param ctx Structure holding ctx job info | |
338 | * @param buffer Pointer to buffer to be processed | |
339 | * @param len Length of buffer (in bytes) to be processed | |
340 | * @param flags Input flag specifying job type (first, update, last or entire) | |
341 | * @returns NULL if no jobs complete or pointer to jobs structure. | |
342 | */ | |
343 | SHA512_HASH_CTX* sha512_ctx_mgr_submit_sb_sse4 (SHA512_HASH_CTX_MGR* mgr, SHA512_HASH_CTX* ctx, | |
344 | const void* buffer, uint32_t len, HASH_CTX_FLAG flags); | |
345 | ||
346 | /** | |
347 | * @brief Finish all submitted SHA512 jobs and return when complete. | |
348 | * @requires SSE4 | |
349 | * | |
350 | * @param mgr Structure holding context level state info | |
351 | * @returns NULL if no jobs to complete or pointer to jobs structure. | |
352 | */ | |
353 | SHA512_HASH_CTX* sha512_ctx_mgr_flush_sb_sse4 (SHA512_HASH_CTX_MGR* mgr); | |
354 | ||
355 | /******************** multibinary function prototypes **********************/ | |
356 | ||
357 | /** | |
358 | * @brief Initialize the SHA512 multi-buffer manager structure. | |
359 | * @requires SSE4.1 or AVX or AVX2 or AVX512 | |
360 | * | |
361 | * @param mgr Structure holding context level state info | |
362 | * @returns void | |
363 | */ | |
364 | void sha512_ctx_mgr_init (SHA512_HASH_CTX_MGR* mgr); | |
365 | ||
366 | /** | |
367 | * @brief Submit a new SHA512 job to the multi-buffer manager. | |
368 | * @requires SSE4.1 or AVX or AVX2 or AVX512 | |
369 | * | |
370 | * @param mgr Structure holding context level state info | |
371 | * @param ctx Structure holding ctx job info | |
372 | * @param buffer Pointer to buffer to be processed | |
373 | * @param len Length of buffer (in bytes) to be processed | |
374 | * @param flags Input flag specifying job type (first, update, last or entire) | |
375 | * @returns NULL if no jobs complete or pointer to jobs structure. | |
376 | */ | |
377 | SHA512_HASH_CTX* sha512_ctx_mgr_submit (SHA512_HASH_CTX_MGR* mgr, SHA512_HASH_CTX* ctx, | |
378 | const void* buffer, uint32_t len, HASH_CTX_FLAG flags); | |
379 | ||
380 | /** | |
381 | * @brief Finish all submitted SHA512 jobs and return when complete. | |
382 | * @requires SSE4.1 or AVX or AVX2 or AVX512 | |
383 | * | |
384 | * @param mgr Structure holding context level state info | |
385 | * @returns NULL if no jobs to complete or pointer to jobs structure. | |
386 | */ | |
387 | SHA512_HASH_CTX* sha512_ctx_mgr_flush (SHA512_HASH_CTX_MGR* mgr); | |
388 | ||
389 | /******************************************************************* | |
390 | * Scheduler (internal) level out-of-order function prototypes | |
391 | ******************************************************************/ | |
392 | ||
393 | void sha512_mb_mgr_init_sse (SHA512_MB_JOB_MGR *state); | |
394 | SHA512_JOB* sha512_mb_mgr_submit_sse (SHA512_MB_JOB_MGR *state, SHA512_JOB* job); | |
395 | SHA512_JOB* sha512_mb_mgr_flush_sse (SHA512_MB_JOB_MGR *state); | |
396 | ||
397 | #define sha512_mb_mgr_init_avx sha512_mb_mgr_init_sse | |
398 | SHA512_JOB* sha512_mb_mgr_submit_avx (SHA512_MB_JOB_MGR *state, SHA512_JOB* job); | |
399 | SHA512_JOB* sha512_mb_mgr_flush_avx (SHA512_MB_JOB_MGR *state); | |
400 | ||
401 | void sha512_mb_mgr_init_avx2 (SHA512_MB_JOB_MGR *state); | |
402 | SHA512_JOB* sha512_mb_mgr_submit_avx2 (SHA512_MB_JOB_MGR *state, SHA512_JOB* job); | |
403 | SHA512_JOB* sha512_mb_mgr_flush_avx2 (SHA512_MB_JOB_MGR *state); | |
404 | ||
405 | void sha512_mb_mgr_init_avx512 (SHA512_MB_JOB_MGR *state); | |
406 | SHA512_JOB* sha512_mb_mgr_submit_avx512 (SHA512_MB_JOB_MGR *state, SHA512_JOB* job); | |
407 | SHA512_JOB* sha512_mb_mgr_flush_avx512 (SHA512_MB_JOB_MGR *state); | |
408 | ||
409 | // Single buffer SHA512 APIs, optimized for SLM. | |
410 | void sha512_sse4 (const void* M, void* D, uint64_t L); | |
411 | // Note that these APIs comply with multi-buffer APIs' high level usage | |
412 | void sha512_sb_mgr_init_sse4 (SHA512_MB_JOB_MGR *state); | |
413 | SHA512_JOB* sha512_sb_mgr_submit_sse4 (SHA512_MB_JOB_MGR *state, SHA512_JOB* job); | |
414 | SHA512_JOB* sha512_sb_mgr_flush_sse4 (SHA512_MB_JOB_MGR *state); | |
415 | ||
416 | #ifdef __cplusplus | |
417 | } | |
418 | #endif | |
419 | ||
420 | #endif // _SHA512_MB_H_ | |
421 | ||
422 |