1 /********************************************************************** 2 Copyright(c) 2011-2016 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 _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 ISAL_SHA512_HASH_CTX_MGR and 43 * ISAL_SHA512_HASH_CTX objects. Numerous ISAL_SHA512_HASH_CTX objects may be instantiated by the 44 * application for use with a single ISAL_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 ISAL_HASH_ENTIRE flag, or as partial 51 * jobs which can be started using the ISAL_HASH_FIRST flag, and later resumed or finished 52 * using the ISAL_HASH_UPDATE and ISAL_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 ISAL_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 ISAL_SHA512_HASH_CTX_MGR object will be used to schedule processor 66 * resources, with up to 2 ISAL_SHA512_HASH_CTX objects (or 4 in the AVX2 case, 8 in the AVX512 67 * case) being processed at a time. 68 * 69 * Each ISAL_SHA512_HASH_CTX must be initialized before first use by the isal_hash_ctx_init macro 70 * defined in multi_buffer.h. After initialization, the application may begin computing 71 * a hash by giving the ISAL_SHA512_HASH_CTX to a ISAL_SHA512_HASH_CTX_MGR using the submit 72 * functions sha512_ctx_mgr_submit*() with the ISAL_HASH_FIRST flag set. When the 73 * ISAL_SHA512_HASH_CTX is returned to the application (via this or a later call to 74 * sha512_ctx_mgr_submit*() or sha512_ctx_mgr_flush*()), the application can then re-submit it with 75 * another call to sha512_ctx_mgr_submit*(), but without the ISAL_HASH_FIRST flag set. 76 * 77 * Ideally, on the last buffer for that hash, sha512_ctx_mgr_submit is called with 78 * ISAL_HASH_LAST, although it is also possible to submit the hash with ISAL_HASH_LAST and a zero 79 * length if necessary. When a ISAL_SHA512_HASH_CTX is returned after having been submitted with 80 * ISAL_HASH_LAST, it will contain a valid hash. The ISAL_SHA512_HASH_CTX can be reused immediately 81 * by submitting with ISAL_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: ISAL_HASH_FIRST | ISAL_HASH_LAST (or, equivalently, ISAL_HASH_ENTIRE) 87 * <li> two buffers: ISAL_HASH_FIRST, ISAL_HASH_LAST 88 * <li> three buffers: ISAL_HASH_FIRST, ISAL_HASH_UPDATE, ISAL_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 ISAL_SHA512_HASH_CTX_MGR. (Note: 99 * This error case is not applicable to the single buffer SSE4 version) 100 * <li> Submitting a context after ISAL_HASH_LAST is used but before ISAL_HASH_FIRST is set. 101 * </ul> 102 * 103 * These error conditions are reported by returning the ISAL_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 ISAL_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 <string.h> 112 #include "multi_buffer.h" 113 #include "types.h" 114 115 #ifndef _MSC_VER 116 #include <stdbool.h> 117 #endif 118 119 #ifdef __cplusplus 120 extern "C" { 121 #endif 122 123 /* 124 * Define enums from API v2.24, so applications that were using this version 125 * will still be compiled successfully. 126 * This list does not need to be extended for new definitions. 127 */ 128 #ifndef NO_COMPAT_ISAL_CRYPTO_API_2_24 129 /***** Previous hash constants and typedefs *****/ 130 #define SHA512_DIGEST_NWORDS ISAL_SHA512_DIGEST_NWORDS 131 #define SHA512_PADLENGTHFIELD_SIZE ISAL_SHA512_PADLENGTHFIELD_SIZE 132 #define SHA512_MAX_LANES ISAL_SHA512_MAX_LANES 133 #define SHA512_MIN_LANES ISAL_SHA512_MIN_LANES 134 #define SHA512_BLOCK_SIZE ISAL_SHA512_BLOCK_SIZE 135 #define SHA512_WORD_T ISAL_SHA512_WORD_T 136 137 /***** Previous structure definitions *****/ 138 #define SHA512_JOB ISAL_SHA512_JOB 139 #define SHA512_MB_ARGS_X8 ISAL_SHA512_MB_ARGS_X8 140 #define SHA512_LANE_DATA ISAL_SHA512_LANE_DATA 141 #define SHA512_MB_JOB_MGR ISAL_SHA512_MB_JOB_MGR 142 #define SHA512_HASH_CTX_MGR ISAL_SHA512_HASH_CTX_MGR 143 #define SHA512_HASH_CTX ISAL_SHA512_HASH_CTX 144 #endif /* !NO_COMPAT_ISAL_CRYPTO_API_2_24 */ 145 146 // Hash Constants and Typedefs 147 #define ISAL_SHA512_DIGEST_NWORDS 8 148 #define ISAL_SHA512_MAX_LANES 8 149 #define ISAL_SHA512_MIN_LANES 2 150 #define ISAL_SHA512_BLOCK_SIZE 128 151 #define ISAL_SHA512_PADLENGTHFIELD_SIZE 16 152 153 typedef uint64_t sha512_digest_array[ISAL_SHA512_DIGEST_NWORDS][ISAL_SHA512_MAX_LANES]; 154 typedef uint64_t ISAL_SHA512_WORD_T; 155 156 /** @brief Scheduler layer - Holds info describing a single SHA512 job for the multi-buffer manager 157 */ 158 159 typedef struct { 160 uint8_t *buffer; //!< pointer to data buffer for this job 161 uint64_t len; //!< length of buffer for this job in blocks. 162 DECLARE_ALIGNED(uint64_t result_digest[ISAL_SHA512_DIGEST_NWORDS], 64); 163 ISAL_JOB_STS status; //!< output job status 164 void *user_data; //!< pointer for user's job-related data 165 } ISAL_SHA512_JOB; 166 167 /** @brief Scheduler layer - Holds arguments for submitted SHA512 job */ 168 169 typedef struct { 170 sha512_digest_array digest; 171 uint8_t *data_ptr[ISAL_SHA512_MAX_LANES]; 172 } ISAL_SHA512_MB_ARGS_X8; 173 174 /** @brief Scheduler layer - Lane data */ 175 176 typedef struct { 177 ISAL_SHA512_JOB *job_in_lane; 178 } ISAL_SHA512_LANE_DATA; 179 180 /** @brief Scheduler layer - Holds state for multi-buffer SHA512 jobs */ 181 182 typedef struct { 183 ISAL_SHA512_MB_ARGS_X8 args; 184 uint64_t lens[ISAL_SHA512_MAX_LANES]; 185 uint64_t unused_lanes; //!< each byte is index (00, 01 or 00...03) of unused lanes, byte 2 186 //!< or 4 is set to FF as a flag 187 ISAL_SHA512_LANE_DATA ldata[ISAL_SHA512_MAX_LANES]; 188 uint32_t num_lanes_inuse; 189 } ISAL_SHA512_MB_JOB_MGR; 190 191 /** @brief Context layer - Holds state for multi-buffer SHA512 jobs */ 192 193 typedef struct { 194 ISAL_SHA512_MB_JOB_MGR mgr; 195 } ISAL_SHA512_HASH_CTX_MGR; 196 197 /** @brief Context layer - Holds info describing a single SHA512 job for the multi-buffer CTX 198 * manager */ 199 200 typedef struct { 201 ISAL_SHA512_JOB job; // Must be at struct offset 0. 202 ISAL_HASH_CTX_STS status; //!< Context status flag 203 ISAL_HASH_CTX_ERROR error; //!< Context error flag 204 uint64_t total_length; //!< Running counter of length processed for this CTX's job 205 const void *incoming_buffer; //!< pointer to data input buffer for this CTX's job 206 uint32_t incoming_buffer_length; //!< length of buffer for this job in bytes. 207 uint8_t partial_block_buffer[ISAL_SHA512_BLOCK_SIZE * 2]; //!< CTX partial blocks 208 uint32_t partial_block_buffer_length; 209 void *user_data; //!< pointer for user to keep any job-related data 210 } ISAL_SHA512_HASH_CTX; 211 212 /******************** multibinary function prototypes **********************/ 213 214 /** 215 * @brief Initialize the SHA512 multi-buffer manager structure. 216 * @requires SSE4.1 or AVX or AVX2 or AVX512 217 * @deprecated Please use isal_sha512_ctx_mgr_init() instead. 218 * 219 * @param mgr Structure holding context level state info 220 * @returns void 221 */ 222 ISAL_DEPRECATED("Please use isal_sha512_ctx_mgr_init() instead") 223 void 224 sha512_ctx_mgr_init(ISAL_SHA512_HASH_CTX_MGR *mgr); 225 226 /** 227 * @brief Submit a new SHA512 job to the multi-buffer manager. 228 * @requires SSE4.1 or AVX or AVX2 or AVX512 229 * @deprecated Please use isal_sha512_ctx_mgr_submit() instead. 230 * 231 * @param mgr Structure holding context level state info 232 * @param ctx Structure holding ctx job info 233 * @param buffer Pointer to buffer to be processed 234 * @param len Length of buffer (in bytes) to be processed 235 * @param flags Input flag specifying job type (first, update, last or entire) 236 * @returns NULL if no jobs complete or pointer to jobs structure. 237 */ 238 ISAL_DEPRECATED("Please use isal_sha512_ctx_mgr_submit() instead") 239 ISAL_SHA512_HASH_CTX * 240 sha512_ctx_mgr_submit(ISAL_SHA512_HASH_CTX_MGR *mgr, ISAL_SHA512_HASH_CTX *ctx, const void *buffer, 241 uint32_t len, ISAL_HASH_CTX_FLAG flags); 242 243 /** 244 * @brief Finish all submitted SHA512 jobs and return when complete. 245 * @requires SSE4.1 or AVX or AVX2 or AVX512 246 * @deprecated Please use isal_sha512_ctx_mgr_flush() instead. 247 * 248 * @param mgr Structure holding context level state info 249 * @returns NULL if no jobs to complete or pointer to jobs structure. 250 */ 251 ISAL_DEPRECATED("Please use isal_sha512_ctx_mgr_flush() instead") 252 ISAL_SHA512_HASH_CTX * 253 sha512_ctx_mgr_flush(ISAL_SHA512_HASH_CTX_MGR *mgr); 254 255 /** 256 * @brief Initialize the SHA512 multi-buffer manager structure. 257 * @requires SSE4.1 for x86 or ASIMD for ARM 258 * 259 * @param[in] mgr Structure holding context level state info 260 * @return Operation status 261 * @retval 0 on success 262 * @retval Non-zero \a ISAL_CRYPTO_ERR on failure 263 */ 264 int 265 isal_sha512_ctx_mgr_init(ISAL_SHA512_HASH_CTX_MGR *mgr); 266 267 /** 268 * @brief Submit a new SHA512 job to the multi-buffer manager. 269 * @requires SSE4.1 for x86 or ASIMD for ARM 270 * 271 * @param[in] mgr Structure holding context level state info 272 * @param[in] ctx_in Structure holding ctx job info 273 * @param[out] ctx_out Pointer address to output job ctx info. 274 * Modified to point to completed job structure or 275 * NULL if no jobs completed. 276 * @param[in] buffer Pointer to buffer to be processed 277 * @param[in] len Length of buffer (in bytes) to be processed 278 * @param[in] flags Input flag specifying job type (first, update, last or entire) 279 * @return Operation status 280 * @retval 0 on success 281 * @retval Non-zero \a ISAL_CRYPTO_ERR on failure 282 */ 283 int 284 isal_sha512_ctx_mgr_submit(ISAL_SHA512_HASH_CTX_MGR *mgr, ISAL_SHA512_HASH_CTX *ctx_in, 285 ISAL_SHA512_HASH_CTX **ctx_out, const void *buffer, const uint32_t len, 286 const ISAL_HASH_CTX_FLAG flags); 287 288 /** 289 * @brief Finish all submitted SHA512 jobs and return when complete. 290 * @requires SSE4.1 for x86 or ASIMD for ARM 291 * 292 * @param[in] mgr Structure holding context level state info 293 * @param[out] ctx_out Pointer address to output job ctx info. 294 * Modified to point to completed job structure or 295 * NULL if no jobs completed. 296 * @return Operation status 297 * @retval 0 on success 298 * @retval Non-zero \a ISAL_CRYPTO_ERR on failure 299 */ 300 int 301 isal_sha512_ctx_mgr_flush(ISAL_SHA512_HASH_CTX_MGR *mgr, ISAL_SHA512_HASH_CTX **ctx_out); 302 #ifdef __cplusplus 303 } 304 #endif 305 306 #endif // _SHA512_MB_H_ 307