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