xref: /isa-l_crypto/include/md5_mb.h (revision 2d00dcb6f8eedd5c7eff746d841010e30d1dba3d)
1 /**********************************************************************
2   Copyright(c) 2011-2024 Intel Corporation All rights reserved.
3 
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions
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 _MD5_MB_H_
31 #define _MD5_MB_H_
32 
33 /**
34  *  @file md5_mb.h
35  *  @brief Multi-buffer CTX API MD5 function prototypes and structures
36  *  @warning: MD5 is considered unsafe, so it is recommended to use SHA256 instead.
37  *
38  * Interface for multi-buffer MD5 functions
39  *
40  * <b> Multi-buffer MD5  Entire or First-Update..Update-Last </b>
41  *
42  * The interface to this multi-buffer hashing code is carried out through the
43  * context-level (CTX) init, submit and flush functions and the ISAL_MD5_HASH_CTX_MGR and
44  * ISAL_MD5_HASH_CTX objects. Numerous ISAL_MD5_HASH_CTX objects may be instantiated by the
45  * application for use with a single ISAL_MD5_HASH_CTX_MGR.
46  *
47  * The CTX interface functions carry out the initialization and padding of the jobs
48  * entered by the user and add them to the multi-buffer manager. The lower level "scheduler"
49  * layer then processes the jobs in an out-of-order manner. The scheduler layer functions
50  * are internal and are not intended to be invoked directly. Jobs can be submitted
51  * to a CTX as a complete buffer to be hashed, using the ISAL_HASH_ENTIRE flag, or as partial
52  * jobs which can be started using the ISAL_HASH_FIRST flag, and later resumed or finished
53  * using the ISAL_HASH_UPDATE and ISAL_HASH_LAST flags respectively.
54  *
55  * <b>Note:</b> The submit function does not require data buffers to be block sized.
56  *
57  * The MD5 CTX interface functions are available for 4 architectures: SSE, AVX, AVX2 and
58  * AVX512. In addition, a multibinary interface is provided, which selects the appropriate
59  * architecture-specific function at runtime.
60  *
61  * <b>Usage:</b> The application creates a ISAL_MD5_HASH_CTX_MGR object and initializes it
62  * with a call to md5_ctx_mgr_init*() function, where henceforth "*" stands for the
63  * relevant suffix for each architecture; _sse, _avx, _avx2, _avx512 (or no suffix for the
64  * multibinary version). The ISAL_MD5_HASH_CTX_MGR object will be used to schedule processor
65  * resources, with up to 8 ISAL_MD5_HASH_CTX objects (or 16 in AVX2 case, 32 in AVX512 case)
66  * being processed at a time.
67  *
68  * Each ISAL_MD5_HASH_CTX must be initialized before first use by the isal_hash_ctx_init macro
69  * defined in multi_buffer.h. After initialization, the application may begin computing
70  * a hash by giving the ISAL_MD5_HASH_CTX to a ISAL_MD5_HASH_CTX_MGR using the submit functions
71  * md5_ctx_mgr_submit*() with the ISAL_HASH_FIRST flag set. When the ISAL_MD5_HASH_CTX is
72  * returned to the application (via this or a later call to md5_ctx_mgr_submit*() or
73  * md5_ctx_mgr_flush*()), the application can then re-submit it with another call to
74  * md5_ctx_mgr_submit*(), but without the ISAL_HASH_FIRST flag set.
75  *
76  * Ideally, on the last buffer for that hash, md5_ctx_mgr_submit_sse is called with
77  * ISAL_HASH_LAST, although it is also possible to submit the hash with ISAL_HASH_LAST and a zero
78  * length if necessary. When a ISAL_MD5_HASH_CTX is returned after having been submitted with
79  * ISAL_HASH_LAST, it will contain a valid hash. The ISAL_MD5_HASH_CTX can be reused immediately
80  * by submitting with ISAL_HASH_FIRST.
81  *
82  * For example, you would submit hashes with the following flags for the following numbers
83  * of buffers:
84  * <ul>
85  *  <li> one buffer: ISAL_HASH_FIRST | ISAL_HASH_LAST  (or, equivalently, ISAL_HASH_ENTIRE)
86  *  <li> two buffers: ISAL_HASH_FIRST, ISAL_HASH_LAST
87  *  <li> three buffers: ISAL_HASH_FIRST, ISAL_HASH_UPDATE, ISAL_HASH_LAST
88  * etc.
89  * </ul>
90  *
91  * The order in which MD5_CTX objects are returned is in general different from the order
92  * in which they are submitted.
93  *
94  * A few possible error conditions exist:
95  * <ul>
96  *  <li> Submitting flags other than the allowed entire/first/update/last values
97  *  <li> Submitting a context that is currently being managed by a ISAL_MD5_HASH_CTX_MGR.
98  *  <li> Submitting a context after ISAL_HASH_LAST is used but before ISAL_HASH_FIRST is set.
99  * </ul>
100  *
101  *  These error conditions are reported by returning the ISAL_MD5_HASH_CTX immediately after
102  *  a submit with its error member set to a non-zero error code (defined in
103  *  multi_buffer.h). No changes are made to the ISAL_MD5_HASH_CTX_MGR in the case of an
104  *  error; no processing is done for other hashes.
105  *
106  */
107 
108 #include <stdint.h>
109 #include <string.h>
110 #include "multi_buffer.h"
111 #include "types.h"
112 
113 #ifdef __cplusplus
114 extern "C" {
115 #endif
116 
117 /*
118  * Define enums from API v2.24, so applications that were using this version
119  * will still be compiled successfully.
120  * This list does not need to be extended for new definitions.
121  */
122 #ifndef NO_COMPAT_ISAL_CRYPTO_API_2_24
123 /***** Previous hash constants and typedefs *****/
124 #define MD5_DIGEST_NWORDS       ISAL_MD5_DIGEST_NWORDS
125 #define MD5_MAX_LANES           ISAL_MD5_MAX_LANES
126 #define MD5_MIN_LANES           ISAL_MD5_MIN_LANES
127 #define MD5_BLOCK_SIZE          ISAL_MD5_BLOCK_SIZE
128 #define MD5_PADLENGTHFIELD_SIZE ISAL_MD5_PADLENGTHFIELD_SIZE
129 
130 #define MD5_HASH_CTX     ISAL_MD5_HASH_CTX
131 #define md5_digest_array isal_md5_digest_array
132 
133 #define MD5_HASH_CTX_MGR ISAL_MD5_HASH_CTX_MGR
134 #define MD5_JOB          ISAL_MD5_JOB
135 #define MD5_WORD_T       ISAL_MD5_WORD_T
136 #define MD5_MB_ARGS_X32  ISAL_MD5_MB_ARGS_X32
137 #define MD5_LANE_DATA    ISAL_MD5_LANE_DATA
138 #define MD5_MB_JOB_MGR   ISAL_MD5_MB_JOB_MGR
139 #endif /* !NO_COMPAT_ISAL_CRYPTO_API_2_24 */
140 
141 // Hash Constants and Typedefs
142 #define ISAL_MD5_DIGEST_NWORDS       4
143 #define ISAL_MD5_MAX_LANES           32
144 #define ISAL_MD5_MIN_LANES           8
145 #define ISAL_MD5_BLOCK_SIZE          64
146 #define ISAL_MD5_PADLENGTHFIELD_SIZE 8
147 
148 typedef uint32_t isal_md5_digest_array[ISAL_MD5_DIGEST_NWORDS][ISAL_MD5_MAX_LANES];
149 typedef uint32_t ISAL_MD5_WORD_T;
150 
151 /** @brief Scheduler layer - Holds info describing a single MD5 job for the multi-buffer manager */
152 
153 typedef struct {
154         uint8_t *buffer; //!< pointer to data buffer for this job
155         uint32_t len;    //!< length of buffer for this job in blocks.
156         DECLARE_ALIGNED(uint32_t result_digest[ISAL_MD5_DIGEST_NWORDS], 64);
157         //!< Digest output (in array of little-endian double words, different than SHA's).
158         ISAL_JOB_STS status; //!< output job status
159         void *user_data;     //!< pointer for user's job-related data
160 } ISAL_MD5_JOB;
161 
162 /** @brief Scheduler layer -  Holds arguments for submitted MD5 job */
163 
164 typedef struct {
165         isal_md5_digest_array digest;
166         uint8_t *data_ptr[ISAL_MD5_MAX_LANES];
167 } ISAL_MD5_MB_ARGS_X32;
168 
169 /** @brief Scheduler layer - Lane data */
170 
171 typedef struct {
172         ISAL_MD5_JOB *job_in_lane;
173 } ISAL_MD5_LANE_DATA;
174 
175 /** @brief Scheduler layer - Holds state for multi-buffer MD5 jobs */
176 
177 typedef struct {
178         ISAL_MD5_MB_ARGS_X32 args;
179         uint32_t lens[ISAL_MD5_MAX_LANES];
180         uint64_t unused_lanes[4]; //!< each byte or nibble is index (0...31 or 15) of unused lanes.
181         ISAL_MD5_LANE_DATA ldata[ISAL_MD5_MAX_LANES];
182         uint32_t num_lanes_inuse;
183 } ISAL_MD5_MB_JOB_MGR;
184 
185 /** @brief Context layer - Holds state for multi-buffer MD5 jobs */
186 
187 typedef struct {
188         ISAL_MD5_MB_JOB_MGR mgr;
189 } ISAL_MD5_HASH_CTX_MGR;
190 
191 /** @brief Context layer - Holds info describing a single MD5 job for the multi-buffer CTX manager
192  */
193 
194 typedef struct {
195         ISAL_MD5_JOB job;                // Must be at struct offset 0.
196         ISAL_HASH_CTX_STS status;        //!< Context status flag
197         ISAL_HASH_CTX_ERROR error;       //!< Context error flag
198         uint64_t total_length;           //!< Running counter of length processed for this CTX's job
199         const void *incoming_buffer;     //!< pointer to data input buffer for this CTX's job
200         uint32_t incoming_buffer_length; //!< length of buffer for this job in bytes.
201         uint8_t partial_block_buffer[ISAL_MD5_BLOCK_SIZE * 2]; //!< CTX partial blocks
202         uint32_t partial_block_buffer_length;
203         void *user_data; //!< pointer for user to keep any job-related data
204 } ISAL_MD5_HASH_CTX;
205 
206 /******************** multibinary function prototypes **********************/
207 
208 /**
209  * @brief Initialize the MD5 multi-buffer manager structure.
210  * @requires SSE4.1 or AVX or AVX2 or AVX512
211  * @deprecated Please use isal_md5_ctx_mgr_init() instead.
212  *
213  * @param mgr	Structure holding context level state info
214  * @returns void
215  */
216 ISAL_DEPRECATED("Please use isal_md5_ctx_mgr_init() instead")
217 void
218 md5_ctx_mgr_init(ISAL_MD5_HASH_CTX_MGR *mgr);
219 
220 /**
221  * @brief  Submit a new MD5 job to the multi-buffer manager.
222  * @requires SSE4.1 or AVX or AVX2 or AVX512
223  * @deprecated Please use isal_md5_ctx_mgr_submit() instead.
224  *
225  * @param  mgr Structure holding context level state info
226  * @param  ctx Structure holding ctx job info
227  * @param  buffer Pointer to buffer to be processed
228  * @param  len Length of buffer (in bytes) to be processed
229  * @param  flags Input flag specifying job type (first, update, last or entire)
230  * @returns NULL if no jobs complete or pointer to jobs structure.
231  */
232 ISAL_DEPRECATED("Please use isal_md5_ctx_mgr_submit() instead")
233 ISAL_MD5_HASH_CTX *
234 md5_ctx_mgr_submit(ISAL_MD5_HASH_CTX_MGR *mgr, ISAL_MD5_HASH_CTX *ctx, const void *buffer,
235                    uint32_t len, ISAL_HASH_CTX_FLAG flags);
236 
237 /**
238  * @brief Finish all submitted MD5 jobs and return when complete.
239  * @requires SSE4.1 or AVX or AVX2 or AVX512
240  * @deprecated Please use isal_md5_ctx_mgr_submit() instead.
241  *
242  * @param mgr	Structure holding context level state info
243  * @returns NULL if no jobs to complete or pointer to jobs structure.
244  */
245 ISAL_DEPRECATED("Please use isal_md5_ctx_mgr_submit() instead")
246 ISAL_MD5_HASH_CTX *
247 md5_ctx_mgr_flush(ISAL_MD5_HASH_CTX_MGR *mgr);
248 
249 /**
250  * @brief Initialize the MD5 multi-buffer manager structure.
251  * @requires SSE4.1 for x86 or ASIMD for ARM
252  *
253  * @param[in] mgr Structure holding context level state info
254  * @return Operation status
255  * @retval 0 on success
256  * @retval Non-zero \a ISAL_CRYPTO_ERR on failure
257  */
258 int
259 isal_md5_ctx_mgr_init(ISAL_MD5_HASH_CTX_MGR *mgr);
260 
261 /**
262  * @brief Submit a new MD5 job to the multi-buffer manager.
263  * @requires SSE4.1 for x86 or ASIMD for ARM
264  *
265  * @param[in] mgr Structure holding context level state info
266  * @param[in] ctx_in Pointer to structure holding input job ctx info
267  * @param[out] ctx_out Pointer address to output job ctx info.
268  *                     Modified to point to completed job structure or
269  *                     NULL if no jobs completed.
270  * @param[in] buffer Pointer to buffer to be processed
271  * @param[in] len Length of buffer (in bytes) to be processed
272  * @param[in] flags Input flag specifying job type (first, update, last or entire)
273  * @return Operation status
274  * @retval 0 on success
275  * @retval Non-zero \a ISAL_CRYPTO_ERR on failure
276  */
277 int
278 isal_md5_ctx_mgr_submit(ISAL_MD5_HASH_CTX_MGR *mgr, ISAL_MD5_HASH_CTX *ctx_in,
279                         ISAL_MD5_HASH_CTX **ctx_out, const void *buffer, const uint32_t len,
280                         const ISAL_HASH_CTX_FLAG flags);
281 
282 /**
283  * @brief Finish all submitted MD5 jobs and return when complete.
284  * @requires SSE4.1 for x86 or ASIMD for ARM
285  *
286  * @param[in] mgr Structure holding context level state info
287  * @param[out] ctx_out Pointer address to output job ctx info.
288  *                     Modified to point to completed job structure or NULL
289  *                     if no jobs complete.
290  * @return Operation status
291  * @retval 0 on success
292  * @retval Non-zero \a ISAL_CRYPTO_ERR on failure
293  */
294 int
295 isal_md5_ctx_mgr_flush(ISAL_MD5_HASH_CTX_MGR *mgr, ISAL_MD5_HASH_CTX **ctx_out);
296 #ifdef __cplusplus
297 }
298 #endif
299 
300 #endif // _MD5_MB_H_
301