1 /****************************************************************************** 2 * Copyright (c) 2022-2023 Texas Instruments Incorporated 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2) Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * 3) Neither the name of the copyright holder nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 ******************************************************************************/ 31 #ifndef SHA256SW_H_ 32 #define SHA256SW_H_ 33 34 /** ============================================================================ 35 * @file sha256sw.h 36 */ 37 /*! 38 * @addtogroup sw_libraries_group 39 * @{ 40 * 41 * @addtogroup sha2sw_api 42 * @{ 43 * @brief SHA2 256/224 SW APIs. 44 * 45 * 46 * @anchor ti_SHA256_SW_LIBRARY_Overview 47 * # Overview # 48 * Provides top-level general purpose SHA2 256/224 APIs. SHA2 algorithm is 49 * implemented in SW with no HW acceleration. The implementation is highly 50 * optimized for speed and code size. These functions reside in ROM, and are 51 * exposed through HAPI, and also through the function prototypes and macros below. 52 * 53 * 54 * Availability of SHA2 224 depends on build configuration. 55 * See file @ref sha2sw_config.h. 56 * 57 * ## Limitations ## 58 * @li A maximum of 512MiB may be hashed by this implementation. (SHA2 59 * standard supports 2 million Terabytes for 224/256) 60 * @li Input data may be 8-bit aligned. However, output digest must be 61 * 32-bit aligned. 62 * @li Intermediate values, input data, and final digest value may be 63 * left behind on the stack. 64 * 65 * <hr> 66 * @anchor ti_SHA256_SW_LIBRARY_Usage 67 * # Usage # 68 * 69 * There are two general ways to execute a SHA2 operation: 70 * 71 * - one-step, using #SHA256SWHashData() 72 * - multi-step, using #SHA256SWStart(), #SHA256SWAddData(), and 73 * #SHA256SWFinalize() 74 * 75 * The multi-step approach allows the hash to be extended by adding 76 * more data. 77 * 78 * All input data is to be in little-endian (LE) format and the resulting 79 * hash values produced by these APIs are in LE format. 80 * 81 * @anchor ti_SHA256_SW_LIBRARY_Synopsis 82 * ## Synopsis 83 * 84 * The following is a quick overview of one-step hashing. 85 * 86 * @anchor ti_SHA256_SW_LIBRARY_Synopsis_Code 87 * @code 88 * // Import SHA2 SW Driver definitions 89 * #include <sha256sw.h> 90 * 91 * // Create an object and handle 92 * SHA256SW_Object sha256SWObject; 93 * SHA256SW_Handle sha256SWHandle = &sha256SWObject; 94 * 95 * // Allocate space for digest output 96 * uint32_t actualDigest[8]; 97 * 98 * result = SHA256SWHashData(sha256SWHandle, SHA2SW_HASH_TYPE_256, 99 * message, strlen(message), actualDigest); 100 * @endcode 101 * 102 * <hr> 103 * @anchor ti_SHA256_SW_LIBRARY_Examples 104 * # Examples 105 * @li @ref ti_SHA256_SW_LIBRARY_Example_hashData "Hashing data in one call" 106 * @li @ref ti_SHA256_SW_LIBRARY_Example_addData "Hashing data in multiple calls" 107 * 108 * @anchor ti_SHA256_SW_LIBRARY_Example_hashData 109 * ## Hashing data in one call 110 * 111 * @code 112 * SHA256SW_Object sha256SWObject; 113 * SHA256SW_Handle sha256SWHandle = &sha256SWObject; 114 * int_fast16_t sha2SWresult; 115 * uint32_t finalDigest[8]; 116 * int notsame; 117 * 118 * char message[] = 119 * "abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn1234"; 120 * uint8_t expectedDigest[] = 121 * { 0x60, 0x06, 0x00, 0x24, 0x13, 0xe4, 0x27, 0x0d, 122 * 0x4d, 0xdb, 0x66, 0x93, 0x42, 0xa9, 0xe2, 0xdb, 123 * 0x66, 0x5e, 0xc8, 0x70, 0x73, 0xc4, 0x2e, 0xb5, 124 * 0x44, 0x99, 0x62, 0xf1, 0x2a, 0xb2, 0xe8, 0x60 }; 125 * 126 * sha2SWresult = SHA256SWHashData(sha256SWHandle, SHA2SW_HASH_TYPE_256, 127 * message, strlen(message), finalDigest); 128 * 129 * if (sha2SWresult != SHA2SW_STATUS_SUCCESS) 130 * { 131 * while(1); 132 * } 133 * 134 * // NOTE: If expectedDigest is a secret value, a timing constant comparison 135 * // routine shall be used instead of memcmp. 136 * notsame = memcmp(finalDigest, expectedDigest, sizeof(finalDigest)); 137 * 138 * if (notsame) 139 * { 140 * while(1); 141 * } 142 * @endcode 143 * 144 * 145 * @anchor ti_SHA256_SW_LIBRARY_Example_addData 146 * ## Hashing data in multiple calls 147 * 148 * @code 149 * SHA256SW_Object sha256SWObject; 150 * SHA256SW_Handle sha256SWHandle = &sha256SWObject; 151 * int_fast16_t sha2SWresult; 152 * uint32_t finalDigest[8]; 153 * int notsame; 154 * 155 * char message[] = 156 * "abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn1234"; 157 * uint8_t expectedDigest[] = 158 * { 0x60, 0x06, 0x00, 0x24, 0x13, 0xe4, 0x27, 0x0d, 159 * 0x4d, 0xdb, 0x66, 0x93, 0x42, 0xa9, 0xe2, 0xdb, 160 * 0x66, 0x5e, 0xc8, 0x70, 0x73, 0xc4, 0x2e, 0xb5, 161 * 0x44, 0x99, 0x62, 0xf1, 0x2a, 0xb2, 0xe8, 0x60, }; 162 * 163 * 164 * sha2SWresult = SHA256SWStart(sha256SWHandle, SHA2SW_HASH_TYPE_256); 165 * 166 * if (sha2SWresult == SHA2SW_STATUS_SUCCESS) { 167 * sha2SWresult = SHA256SWAddData(sha256SWHandle, message, 20); 168 * } 169 * 170 * if (sha2SWresult == SHA2SW_STATUS_SUCCESS) { 171 * sha2SWresult = SHA256SWAddData(sha256SWHandle, &message[20], strlen(message) - 20); 172 * } 173 * 174 * if (sha2SWresult == SHA2SW_STATUS_SUCCESS) { 175 * sha2SWresult = SHA256SWFinalize(sha256SWHandle, finalDigest); 176 * } 177 * 178 * if (sha2SWresult != SHA2SW_STATUS_SUCCESS) 179 * { 180 * while(1); 181 * } 182 * 183 * // NOTE: If expectedDigest is a secret value, a timing constant comparison 184 * // routine shall be used instead of memcmp. 185 * notsame = memcmp(finalDigest, expectedDigest, sizeof(finalDigest)); 186 * 187 * if (notsame) 188 * { 189 * while(1); 190 * } 191 * @endcode 192 * 193 * 194 * <hr> 195 * @anchor ti_SHA256_SW_LIBRARY_configuration 196 * # Configuration 197 * 198 * See file @ref sha2sw_config.h for full configuration information. 199 * 200 * If #SHA2SW_VALIDATE_INPUTS is not defined then: 201 * @li the caller is responsible for ensuring all inputs are valid, and 202 * @li the module's functions will only return #SHA2SW_STATUS_SUCCESS 203 * 204 */ 205 206 #include <stddef.h> 207 #include <stdint.h> 208 209 #include "sha2sw_common.h" 210 #include "sha2sw_config.h" 211 212 /*! 213 * @brief SHA256SW Object 214 * 215 * The application must not access any member variables of this structure! 216 */ 217 typedef struct 218 { 219 uint32_t bitsProcessed; // Only 2^32 bits (512 MiBytes) are supported 220 int8_t offsetWb; // Byte offset into Ws, used to load message 221 uint8_t reserved1; 222 uint8_t reserved2; 223 uint8_t reserved3; 224 uint32_t digest32[8]; // Holds intermediate/final digest 225 uint32_t Ws32[16]; // Message schedule, indexed by (s & 0xF), 226 // where s = 63 - t, and t is NIST 180-4's 227 // message schedule index 228 } SHA256SW_Object; 229 230 /*! 231 * @brief A handle to a SHA256SW_Object. 232 */ 233 typedef SHA256SW_Object *SHA256SW_Handle; 234 235 /* Include this file after the type definitions above, to break cyclic dependency between hapi.h and sha256sw.h */ 236 #include "hapi.h" 237 238 /*! 239 * @brief Performs a complete hash operation, producing a final digest 240 * for the data. 241 * 242 * This function wraps #SHA256SWStart(), #SHA256SWAddData(), and 243 * #SHA256SWFinalize(). 244 * 245 * There is no need to call #SHA256SWStart() prior to calling this function. 246 * 247 * The total length of data that can be hashed by this implementation 248 * is 512MiB (0x20000000 bytes.) 249 * 250 * @param[in] handle A #SHA256SW_Handle. 251 * 252 * @param[in] hashType The type of hash (256 or 224) to perform. 253 * 254 * @param[in] data data (message) to hash. May point to zero. 255 * 256 * @param[in] length the number of bytes (pointed to by @c data parameter) 257 * to add to the hash. 258 * 259 * @param[out] digest Output location for the final digest. Must be 260 * able to hold 32 bytes of output and be 32-bit aligned. 261 * 262 * @retval #SHA2SW_STATUS_SUCCESS The hash operation succeeded. 263 * @retval #SHA2SW_STATUS_ERROR The hash operation failed. 264 * @retval #SHA2SW_STATUS_UNSUPPORTED Requested Hash Type is unsupported. 265 * @retval #SHA2SW_STATUS_LENGTH_TOO_LARGE The requested length of data to hash 266 * is more than the implementation 267 * supports. 268 * @retval #SHA2SW_STATUS_NULL_INPUT One or more of the pointer inputs is 269 * NULL. 270 * 271 */ 272 extern int_fast16_t SHA256SWHashData(SHA256SW_Handle handle, 273 SHA2SW_HashType hashType, 274 const void *data, 275 size_t length, 276 uint32_t digest[8]); 277 278 #define SHA256SWHashData HAPI_TABLE_POINTER->sha256SwHashData 279 280 /*! 281 * @brief Initialize a SHA256SW_Handle, preparing for hashing data. 282 * 283 * @param[in] handle A #SHA256SW_Handle. 284 * 285 * @param[in] hashType The type of hash (256 or 224) to perform. 286 * 287 * @retval #SHA2SW_STATUS_SUCCESS The hash operation succeeded. 288 * @retval #SHA2SW_STATUS_UNSUPPORTED Requested Hash Type is unsupported. 289 * @retval #SHA2SW_STATUS_NULL_INPUT One or more of the pointer inputs is 290 * NULL. 291 * 292 * @sa #SHA256SWAddData() 293 * @sa #SHA256SWFinalize() 294 */ 295 extern int_fast16_t SHA256SWStart(SHA256SW_Handle handle, SHA2SW_HashType hashType); 296 297 #define SHA256SWStart HAPI_TABLE_POINTER->sha256SwStart 298 299 /*! 300 * @brief Add data to a SHA256/224 operation. 301 * 302 * Adds data to a hash operation. The @c handle must have been 303 * initialized by a call to SHA256SWStart first. 304 * 305 * The total length of data that can be hashed by this implementation 306 * is 512MiB (0x20000000 bytes.) 307 * 308 * After passing in all data to be hashed, call #SHA256SWFinalize() 309 * to obtain the final digest. 310 * 311 * @pre handle was previously passed to #SHA256SWStart(). 312 * 313 * @param[in] handle A #SHA256SW_Handle. 314 * 315 * @param[in] data data (message) to add to the hash. May point to zero. 316 * 317 * @param[in] length the number of bytes (pointed to by @c data parameter) 318 * to add to the hash. 319 * 320 * @retval #SHA2SW_STATUS_SUCCESS The hash operation succeeded. 321 * @retval #SHA2SW_STATUS_LENGTH_TOO_LARGE The requested length of data to hash 322 * is more than the implementation 323 * supports. 324 * @retval #SHA2SW_STATUS_NULL_INPUT One or more of the pointer inputs is 325 * NULL. 326 * 327 * @sa #SHA256SWStart() 328 * @sa #SHA256SWFinalize() 329 */ 330 extern int_fast16_t SHA256SWAddData(SHA256SW_Handle handle, const void *data, size_t length); 331 332 #define SHA256SWAddData HAPI_TABLE_POINTER->sha256SwAddData 333 334 /*! 335 * @brief Finalize a SHA256/224 operation, creating the final digest. 336 * 337 * After calling this function, @c handle should not be used again 338 * until it has been reinitialized via a call to #SHA256SWStart(). 339 * 340 * @pre handle was previously passed to #SHA256SWStart() and data to 341 * be hashed was passed to #SHA256SWAddData() 342 * 343 * @param[in] handle A #SHA256SW_Handle. 344 * 345 * @param[out] digest Output location for the final digest. Must be 346 * able to hold 32 bytes of output and be 32-bit aligned. 347 * 348 * @retval #SHA2SW_STATUS_SUCCESS The hash operation succeeded. 349 * @retval #SHA2SW_STATUS_NULL_INPUT One or more of the pointer inputs is 350 * NULL. 351 * 352 * @sa #SHA256SWStart() 353 * @sa #SHA256SWAddData() 354 */ 355 extern int_fast16_t SHA256SWFinalize(SHA256SW_Handle handle, uint32_t digest[8]); 356 357 #define SHA256SWFinalize HAPI_TABLE_POINTER->sha256SwFinalize 358 359 /*! @}*/ 360 /*! @}*/ 361 362 #endif /* SHA256SW_H_ */ 363