Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sha3.c
00001 /* sha3.c 00002 * 00003 * Copyright (C) 2006-2017 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfcrypt/settings.h> 00028 00029 #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT) 00030 00031 #if defined(HAVE_FIPS) && \ 00032 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) 00033 00034 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 00035 #define FIPS_NO_WRAPPERS 00036 00037 #ifdef USE_WINDOWS_API 00038 #pragma code_seg(".fipsA$l") 00039 #pragma const_seg(".fipsB$l") 00040 #endif 00041 #endif 00042 00043 #include <wolfcrypt/sha3.h> 00044 #include <wolfcrypt/error-crypt.h> 00045 00046 #ifdef NO_INLINE 00047 #include <wolfcrypt/misc.h> 00048 #else 00049 #define WOLFSSL_MISC_INCLUDED 00050 #include <wolfcrypt/src/misc.c> 00051 #endif 00052 00053 00054 #ifdef WOLFSSL_SHA3_SMALL 00055 /* Rotate a 64-bit value left. 00056 * 00057 * a Number to rotate left. 00058 * r Number od bits to rotate left. 00059 * returns the rotated number. 00060 */ 00061 #define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n)))) 00062 00063 /* An array of values to XOR for block operation. */ 00064 static const word64 hash_keccak_r[24] = 00065 { 00066 0x0000000000000001UL, 0x0000000000008082UL, 00067 0x800000000000808aUL, 0x8000000080008000UL, 00068 0x000000000000808bUL, 0x0000000080000001UL, 00069 0x8000000080008081UL, 0x8000000000008009UL, 00070 0x000000000000008aUL, 0x0000000000000088UL, 00071 0x0000000080008009UL, 0x000000008000000aUL, 00072 0x000000008000808bUL, 0x800000000000008bUL, 00073 0x8000000000008089UL, 0x8000000000008003UL, 00074 0x8000000000008002UL, 0x8000000000000080UL, 00075 0x000000000000800aUL, 0x800000008000000aUL, 00076 0x8000000080008081UL, 0x8000000000008080UL, 00077 0x0000000080000001UL, 0x8000000080008008UL 00078 }; 00079 00080 /* Indeces used in swap and rotate operation. */ 00081 #define K_I_0 10 00082 #define K_I_1 7 00083 #define K_I_2 11 00084 #define K_I_3 17 00085 #define K_I_4 18 00086 #define K_I_5 3 00087 #define K_I_6 5 00088 #define K_I_7 16 00089 #define K_I_8 8 00090 #define K_I_9 21 00091 #define K_I_10 24 00092 #define K_I_11 4 00093 #define K_I_12 15 00094 #define K_I_13 23 00095 #define K_I_14 19 00096 #define K_I_15 13 00097 #define K_I_16 12 00098 #define K_I_17 2 00099 #define K_I_18 20 00100 #define K_I_19 14 00101 #define K_I_20 22 00102 #define K_I_21 9 00103 #define K_I_22 6 00104 #define K_I_23 1 00105 00106 /* Number of bits to rotate in swap and rotate operation. */ 00107 #define K_R_0 1 00108 #define K_R_1 3 00109 #define K_R_2 6 00110 #define K_R_3 10 00111 #define K_R_4 15 00112 #define K_R_5 21 00113 #define K_R_6 28 00114 #define K_R_7 36 00115 #define K_R_8 45 00116 #define K_R_9 55 00117 #define K_R_10 2 00118 #define K_R_11 14 00119 #define K_R_12 27 00120 #define K_R_13 41 00121 #define K_R_14 56 00122 #define K_R_15 8 00123 #define K_R_16 25 00124 #define K_R_17 43 00125 #define K_R_18 62 00126 #define K_R_19 18 00127 #define K_R_20 39 00128 #define K_R_21 61 00129 #define K_R_22 20 00130 #define K_R_23 44 00131 00132 /* Swap and rotate left operation. 00133 * 00134 * s The state. 00135 * t1 Temporary value. 00136 * t2 Second temporary value. 00137 * i The index of the loop. 00138 */ 00139 #define SWAP_ROTL(s, t1, t2, i) \ 00140 do \ 00141 { \ 00142 t2 = s[K_I_##i]; s[K_I_##i] = ROTL64(t1, K_R_##i); \ 00143 } \ 00144 while (0) 00145 00146 /* Mix the XOR of the column's values into each number by column. 00147 * 00148 * s The state. 00149 * b Temporary array of XORed column values. 00150 * x The index of the column. 00151 * t Temporary variable. 00152 */ 00153 #define COL_MIX(s, b, x, t) \ 00154 do \ 00155 { \ 00156 for (x = 0; x < 5; x++) \ 00157 b[x] = s[x + 0] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20]; \ 00158 for (x = 0; x < 5; x++) \ 00159 { \ 00160 t = b[(x + 4) % 5] ^ ROTL64(b[(x + 1) % 5], 1); \ 00161 s[x + 0] ^= t; \ 00162 s[x + 5] ^= t; \ 00163 s[x + 10] ^= t; \ 00164 s[x + 15] ^= t; \ 00165 s[x + 20] ^= t; \ 00166 } \ 00167 } \ 00168 while (0) 00169 00170 #ifdef SHA3_BY_SPEC 00171 /* Mix the row values. 00172 * BMI1 has ANDN instruction ((~a) & b) - Haswell and above. 00173 * 00174 * s The state. 00175 * b Temporary array of XORed row values. 00176 * y The index of the row to work on. 00177 * x The index of the column. 00178 * t0 Temporary variable. 00179 * t1 Temporary variable. 00180 */ 00181 #define ROW_MIX(s, b, y, x, t0, t1) \ 00182 do \ 00183 { \ 00184 for (y = 0; y < 5; y++) \ 00185 { \ 00186 for (x = 0; x < 5; x++) \ 00187 b[x] = s[y * 5 + x]; \ 00188 for (x = 0; x < 5; x++) \ 00189 s[y * 5 + x] = b[x] ^ (~b[(x + 1) % 5] & b[(x + 2) % 5]); \ 00190 } \ 00191 } \ 00192 while (0) 00193 #else 00194 /* Mix the row values. 00195 * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c) 00196 * 00197 * s The state. 00198 * b Temporary array of XORed row values. 00199 * y The index of the row to work on. 00200 * x The index of the column. 00201 * t0 Temporary variable. 00202 * t1 Temporary variable. 00203 */ 00204 #define ROW_MIX(s, b, y, x, t12, t34) \ 00205 do \ 00206 { \ 00207 for (y = 0; y < 5; y++) \ 00208 { \ 00209 for (x = 0; x < 5; x++) \ 00210 b[x] = s[y * 5 + x]; \ 00211 t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \ 00212 s[y * 5 + 0] = b[0] ^ (b[2] & t12); \ 00213 s[y * 5 + 1] = t12 ^ (b[2] | b[3]); \ 00214 s[y * 5 + 2] = b[2] ^ (b[4] & t34); \ 00215 s[y * 5 + 3] = t34 ^ (b[4] | b[0]); \ 00216 s[y * 5 + 4] = b[4] ^ (b[1] & (b[0] ^ b[1])); \ 00217 } \ 00218 } \ 00219 while (0) 00220 #endif /* SHA3_BY_SPEC */ 00221 00222 /* The block operation performed on the state. 00223 * 00224 * s The state. 00225 */ 00226 static void BlockSha3(word64 *s) 00227 { 00228 byte i, x, y; 00229 word64 t0, t1; 00230 word64 b[5]; 00231 00232 for (i = 0; i < 24; i++) 00233 { 00234 COL_MIX(s, b, x, t0); 00235 00236 t0 = s[1]; 00237 SWAP_ROTL(s, t0, t1, 0); 00238 SWAP_ROTL(s, t1, t0, 1); 00239 SWAP_ROTL(s, t0, t1, 2); 00240 SWAP_ROTL(s, t1, t0, 3); 00241 SWAP_ROTL(s, t0, t1, 4); 00242 SWAP_ROTL(s, t1, t0, 5); 00243 SWAP_ROTL(s, t0, t1, 6); 00244 SWAP_ROTL(s, t1, t0, 7); 00245 SWAP_ROTL(s, t0, t1, 8); 00246 SWAP_ROTL(s, t1, t0, 9); 00247 SWAP_ROTL(s, t0, t1, 10); 00248 SWAP_ROTL(s, t1, t0, 11); 00249 SWAP_ROTL(s, t0, t1, 12); 00250 SWAP_ROTL(s, t1, t0, 13); 00251 SWAP_ROTL(s, t0, t1, 14); 00252 SWAP_ROTL(s, t1, t0, 15); 00253 SWAP_ROTL(s, t0, t1, 16); 00254 SWAP_ROTL(s, t1, t0, 17); 00255 SWAP_ROTL(s, t0, t1, 18); 00256 SWAP_ROTL(s, t1, t0, 19); 00257 SWAP_ROTL(s, t0, t1, 20); 00258 SWAP_ROTL(s, t1, t0, 21); 00259 SWAP_ROTL(s, t0, t1, 22); 00260 SWAP_ROTL(s, t1, t0, 23); 00261 00262 ROW_MIX(s, b, y, x, t0, t1); 00263 00264 s[0] ^= hash_keccak_r[i]; 00265 } 00266 } 00267 #else 00268 /* Rotate a 64-bit value left. 00269 * 00270 * a Number to rotate left. 00271 * r Number od bits to rotate left. 00272 * returns the rotated number. 00273 */ 00274 #define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n)))) 00275 00276 /* An array of values to XOR for block operation. */ 00277 static const word64 hash_keccak_r[24] = 00278 { 00279 0x0000000000000001UL, 0x0000000000008082UL, 00280 0x800000000000808aUL, 0x8000000080008000UL, 00281 0x000000000000808bUL, 0x0000000080000001UL, 00282 0x8000000080008081UL, 0x8000000000008009UL, 00283 0x000000000000008aUL, 0x0000000000000088UL, 00284 0x0000000080008009UL, 0x000000008000000aUL, 00285 0x000000008000808bUL, 0x800000000000008bUL, 00286 0x8000000000008089UL, 0x8000000000008003UL, 00287 0x8000000000008002UL, 0x8000000000000080UL, 00288 0x000000000000800aUL, 0x800000008000000aUL, 00289 0x8000000080008081UL, 0x8000000000008080UL, 00290 0x0000000080000001UL, 0x8000000080008008UL 00291 }; 00292 00293 /* Indeces used in swap and rotate operation. */ 00294 #define KI_0 6 00295 #define KI_1 12 00296 #define KI_2 18 00297 #define KI_3 24 00298 #define KI_4 3 00299 #define KI_5 9 00300 #define KI_6 10 00301 #define KI_7 16 00302 #define KI_8 22 00303 #define KI_9 1 00304 #define KI_10 7 00305 #define KI_11 13 00306 #define KI_12 19 00307 #define KI_13 20 00308 #define KI_14 4 00309 #define KI_15 5 00310 #define KI_16 11 00311 #define KI_17 17 00312 #define KI_18 23 00313 #define KI_19 2 00314 #define KI_20 8 00315 #define KI_21 14 00316 #define KI_22 15 00317 #define KI_23 21 00318 00319 /* Number of bits to rotate in swap and rotate operation. */ 00320 #define KR_0 44 00321 #define KR_1 43 00322 #define KR_2 21 00323 #define KR_3 14 00324 #define KR_4 28 00325 #define KR_5 20 00326 #define KR_6 3 00327 #define KR_7 45 00328 #define KR_8 61 00329 #define KR_9 1 00330 #define KR_10 6 00331 #define KR_11 25 00332 #define KR_12 8 00333 #define KR_13 18 00334 #define KR_14 27 00335 #define KR_15 36 00336 #define KR_16 10 00337 #define KR_17 15 00338 #define KR_18 56 00339 #define KR_19 62 00340 #define KR_20 55 00341 #define KR_21 39 00342 #define KR_22 41 00343 #define KR_23 2 00344 00345 /* Mix the XOR of the column's values into each number by column. 00346 * 00347 * s The state. 00348 * b Temporary array of XORed column values. 00349 * x The index of the column. 00350 * t Temporary variable. 00351 */ 00352 #define COL_MIX(s, b, x, t) \ 00353 do \ 00354 { \ 00355 b[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20]; \ 00356 b[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21]; \ 00357 b[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22]; \ 00358 b[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23]; \ 00359 b[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24]; \ 00360 t = b[(0 + 4) % 5] ^ ROTL64(b[(0 + 1) % 5], 1); \ 00361 s[ 0] ^= t; s[ 5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t; \ 00362 t = b[(1 + 4) % 5] ^ ROTL64(b[(1 + 1) % 5], 1); \ 00363 s[ 1] ^= t; s[ 6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t; \ 00364 t = b[(2 + 4) % 5] ^ ROTL64(b[(2 + 1) % 5], 1); \ 00365 s[ 2] ^= t; s[ 7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t; \ 00366 t = b[(3 + 4) % 5] ^ ROTL64(b[(3 + 1) % 5], 1); \ 00367 s[ 3] ^= t; s[ 8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t; \ 00368 t = b[(4 + 4) % 5] ^ ROTL64(b[(4 + 1) % 5], 1); \ 00369 s[ 4] ^= t; s[ 9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t; \ 00370 } \ 00371 while (0) 00372 00373 #define S(s1, i) ROTL64(s1[KI_##i], KR_##i) 00374 00375 #ifdef SHA3_BY_SPEC 00376 /* Mix the row values. 00377 * BMI1 has ANDN instruction ((~a) & b) - Haswell and above. 00378 * 00379 * s2 The new state. 00380 * s1 The current state. 00381 * b Temporary array of XORed row values. 00382 * t0 Temporary variable. (Unused) 00383 * t1 Temporary variable. (Unused) 00384 */ 00385 #define ROW_MIX(s2, s1, b, t0, t1) \ 00386 do \ 00387 { \ 00388 b[0] = s1[0]; \ 00389 b[1] = S(s1, 0); \ 00390 b[2] = S(s1, 1); \ 00391 b[3] = S(s1, 2); \ 00392 b[4] = S(s1, 3); \ 00393 s2[0] = b[0] ^ (~b[1] & b[2]); \ 00394 s2[1] = b[1] ^ (~b[2] & b[3]); \ 00395 s2[2] = b[2] ^ (~b[3] & b[4]); \ 00396 s2[3] = b[3] ^ (~b[4] & b[0]); \ 00397 s2[4] = b[4] ^ (~b[0] & b[1]); \ 00398 b[0] = S(s1, 4); \ 00399 b[1] = S(s1, 5); \ 00400 b[2] = S(s1, 6); \ 00401 b[3] = S(s1, 7); \ 00402 b[4] = S(s1, 8); \ 00403 s2[5] = b[0] ^ (~b[1] & b[2]); \ 00404 s2[6] = b[1] ^ (~b[2] & b[3]); \ 00405 s2[7] = b[2] ^ (~b[3] & b[4]); \ 00406 s2[8] = b[3] ^ (~b[4] & b[0]); \ 00407 s2[9] = b[4] ^ (~b[0] & b[1]); \ 00408 b[0] = S(s1, 9); \ 00409 b[1] = S(s1, 10); \ 00410 b[2] = S(s1, 11); \ 00411 b[3] = S(s1, 12); \ 00412 b[4] = S(s1, 13); \ 00413 s2[10] = b[0] ^ (~b[1] & b[2]); \ 00414 s2[11] = b[1] ^ (~b[2] & b[3]); \ 00415 s2[12] = b[2] ^ (~b[3] & b[4]); \ 00416 s2[13] = b[3] ^ (~b[4] & b[0]); \ 00417 s2[14] = b[4] ^ (~b[0] & b[1]); \ 00418 b[0] = S(s1, 14); \ 00419 b[1] = S(s1, 15); \ 00420 b[2] = S(s1, 16); \ 00421 b[3] = S(s1, 17); \ 00422 b[4] = S(s1, 18); \ 00423 s2[15] = b[0] ^ (~b[1] & b[2]); \ 00424 s2[16] = b[1] ^ (~b[2] & b[3]); \ 00425 s2[17] = b[2] ^ (~b[3] & b[4]); \ 00426 s2[18] = b[3] ^ (~b[4] & b[0]); \ 00427 s2[19] = b[4] ^ (~b[0] & b[1]); \ 00428 b[0] = S(s1, 19); \ 00429 b[1] = S(s1, 20); \ 00430 b[2] = S(s1, 21); \ 00431 b[3] = S(s1, 22); \ 00432 b[4] = S(s1, 23); \ 00433 s2[20] = b[0] ^ (~b[1] & b[2]); \ 00434 s2[21] = b[1] ^ (~b[2] & b[3]); \ 00435 s2[22] = b[2] ^ (~b[3] & b[4]); \ 00436 s2[23] = b[3] ^ (~b[4] & b[0]); \ 00437 s2[24] = b[4] ^ (~b[0] & b[1]); \ 00438 } \ 00439 while (0) 00440 #else 00441 /* Mix the row values. 00442 * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c) 00443 * 00444 * s2 The new state. 00445 * s1 The current state. 00446 * b Temporary array of XORed row values. 00447 * t12 Temporary variable. 00448 * t34 Temporary variable. 00449 */ 00450 #define ROW_MIX(s2, s1, b, t12, t34) \ 00451 do \ 00452 { \ 00453 b[0] = s1[0]; \ 00454 b[1] = S(s1, 0); \ 00455 b[2] = S(s1, 1); \ 00456 b[3] = S(s1, 2); \ 00457 b[4] = S(s1, 3); \ 00458 t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \ 00459 s2[0] = b[0] ^ (b[2] & t12); \ 00460 s2[1] = t12 ^ (b[2] | b[3]); \ 00461 s2[2] = b[2] ^ (b[4] & t34); \ 00462 s2[3] = t34 ^ (b[4] | b[0]); \ 00463 s2[4] = b[4] ^ (b[1] & (b[0] ^ b[1])); \ 00464 b[0] = S(s1, 4); \ 00465 b[1] = S(s1, 5); \ 00466 b[2] = S(s1, 6); \ 00467 b[3] = S(s1, 7); \ 00468 b[4] = S(s1, 8); \ 00469 t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \ 00470 s2[5] = b[0] ^ (b[2] & t12); \ 00471 s2[6] = t12 ^ (b[2] | b[3]); \ 00472 s2[7] = b[2] ^ (b[4] & t34); \ 00473 s2[8] = t34 ^ (b[4] | b[0]); \ 00474 s2[9] = b[4] ^ (b[1] & (b[0] ^ b[1])); \ 00475 b[0] = S(s1, 9); \ 00476 b[1] = S(s1, 10); \ 00477 b[2] = S(s1, 11); \ 00478 b[3] = S(s1, 12); \ 00479 b[4] = S(s1, 13); \ 00480 t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \ 00481 s2[10] = b[0] ^ (b[2] & t12); \ 00482 s2[11] = t12 ^ (b[2] | b[3]); \ 00483 s2[12] = b[2] ^ (b[4] & t34); \ 00484 s2[13] = t34 ^ (b[4] | b[0]); \ 00485 s2[14] = b[4] ^ (b[1] & (b[0] ^ b[1])); \ 00486 b[0] = S(s1, 14); \ 00487 b[1] = S(s1, 15); \ 00488 b[2] = S(s1, 16); \ 00489 b[3] = S(s1, 17); \ 00490 b[4] = S(s1, 18); \ 00491 t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \ 00492 s2[15] = b[0] ^ (b[2] & t12); \ 00493 s2[16] = t12 ^ (b[2] | b[3]); \ 00494 s2[17] = b[2] ^ (b[4] & t34); \ 00495 s2[18] = t34 ^ (b[4] | b[0]); \ 00496 s2[19] = b[4] ^ (b[1] & (b[0] ^ b[1])); \ 00497 b[0] = S(s1, 19); \ 00498 b[1] = S(s1, 20); \ 00499 b[2] = S(s1, 21); \ 00500 b[3] = S(s1, 22); \ 00501 b[4] = S(s1, 23); \ 00502 t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \ 00503 s2[20] = b[0] ^ (b[2] & t12); \ 00504 s2[21] = t12 ^ (b[2] | b[3]); \ 00505 s2[22] = b[2] ^ (b[4] & t34); \ 00506 s2[23] = t34 ^ (b[4] | b[0]); \ 00507 s2[24] = b[4] ^ (b[1] & (b[0] ^ b[1])); \ 00508 } \ 00509 while (0) 00510 #endif /* SHA3_BY_SPEC */ 00511 00512 /* The block operation performed on the state. 00513 * 00514 * s The state. 00515 */ 00516 static void BlockSha3(word64 *s) 00517 { 00518 word64 n[25]; 00519 word64 b[5]; 00520 word64 t0; 00521 #ifndef SHA3_BY_SPEC 00522 word64 t1; 00523 #endif 00524 byte i; 00525 00526 for (i = 0; i < 24; i += 2) 00527 { 00528 COL_MIX(s, b, x, t0); 00529 ROW_MIX(n, s, b, t0, t1); 00530 n[0] ^= hash_keccak_r[i]; 00531 00532 COL_MIX(n, b, x, t0); 00533 ROW_MIX(s, n, b, t0, t1); 00534 s[0] ^= hash_keccak_r[i+1]; 00535 } 00536 } 00537 #endif /* WOLFSSL_SHA3_SMALL */ 00538 00539 /* Convert the array of bytes, in little-endian order, to a 64-bit integer. 00540 * 00541 * a Array of bytes. 00542 * returns a 64-bit integer. 00543 */ 00544 static word64 Load64BitBigEndian(const byte* a) 00545 { 00546 #ifdef BIG_ENDIAN_ORDER 00547 word64 n = 0; 00548 int i; 00549 00550 for (i = 0; i < 8; i++) 00551 n |= (word64)a[i] << (8 * i); 00552 00553 return n; 00554 #else 00555 return *(word64*)a; 00556 #endif 00557 } 00558 00559 /* Initialize the state for a SHA3-224 hash operation. 00560 * 00561 * sha3 wc_Sha3 object holding state. 00562 * returns 0 on success. 00563 */ 00564 static int InitSha3(wc_Sha3* sha3) 00565 { 00566 int i; 00567 00568 for (i = 0; i < 25; i++) 00569 sha3->s[i] = 0; 00570 sha3->i = 0; 00571 00572 return 0; 00573 } 00574 00575 /* Update the SHA-3 hash state with message data. 00576 * 00577 * sha3 wc_Sha3 object holding state. 00578 * data Message data to be hashed. 00579 * len Length of the message data. 00580 * p Number of 64-bit numbers in a block of data to process. 00581 * returns 0 on success. 00582 */ 00583 static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) 00584 { 00585 byte i; 00586 byte l; 00587 byte *t; 00588 00589 if (sha3->i > 0) 00590 { 00591 l = p * 8 - sha3->i; 00592 if (l > len) { 00593 l = (byte)len; 00594 } 00595 00596 t = &sha3->t[sha3->i]; 00597 for (i = 0; i < l; i++) 00598 t[i] = data[i]; 00599 data += i; 00600 len -= i; 00601 sha3->i += i; 00602 00603 if (sha3->i == p * 8) 00604 { 00605 for (i = 0; i < p; i++) 00606 sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i); 00607 BlockSha3(sha3->s); 00608 sha3->i = 0; 00609 } 00610 } 00611 while (len >= ((word32)(p * 8))) 00612 { 00613 for (i = 0; i < p; i++) 00614 sha3->s[i] ^= Load64BitBigEndian(data + 8 * i); 00615 BlockSha3(sha3->s); 00616 len -= p * 8; 00617 data += p * 8; 00618 } 00619 for (i = 0; i < len; i++) 00620 sha3->t[i] = data[i]; 00621 sha3->i += i; 00622 00623 return 0; 00624 } 00625 00626 /* Calculate the SHA-3 hash based on all the message data seen. 00627 * 00628 * sha3 wc_Sha3 object holding state. 00629 * hash Buffer to hold the hash result. 00630 * p Number of 64-bit numbers in a block of data to process. 00631 * len Number of bytes in output. 00632 * returns 0 on success. 00633 */ 00634 static int Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte l) 00635 { 00636 byte i; 00637 byte *s8 = (byte *)sha3->s; 00638 00639 sha3->t[p * 8 - 1] = 0x00; 00640 sha3->t[ sha3->i] = 0x06; 00641 sha3->t[p * 8 - 1] |= 0x80; 00642 for (i=sha3->i + 1; i < p * 8 - 1; i++) 00643 sha3->t[i] = 0; 00644 for (i = 0; i < p; i++) 00645 sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i); 00646 BlockSha3(sha3->s); 00647 #if defined(BIG_ENDIAN_ORDER) 00648 ByteReverseWords64(sha3->s, sha3->s, ((l+7)/8)*8); 00649 #endif 00650 for (i = 0; i < l; i++) 00651 hash[i] = s8[i]; 00652 00653 return 0; 00654 } 00655 00656 /* Initialize the state for a SHA-3 hash operation. 00657 * 00658 * sha3 wc_Sha3 object holding state. 00659 * heap Heap reference for dynamic memory allocation. (Used in async ops.) 00660 * devId Device identifier for asynchronous operation. 00661 * returns 0 on success. 00662 */ 00663 static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId) 00664 { 00665 int ret = 0; 00666 00667 if (sha3 == NULL) 00668 return BAD_FUNC_ARG; 00669 00670 sha3->heap = heap; 00671 ret = InitSha3(sha3); 00672 if (ret != 0) 00673 return ret; 00674 00675 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) 00676 ret = wolfAsync_DevCtxInit(&sha3->asyncDev, 00677 WOLFSSL_ASYNC_MARKER_SHA3, sha3->heap, devId); 00678 #else 00679 (void)devId; 00680 #endif /* WOLFSSL_ASYNC_CRYPT */ 00681 00682 return ret; 00683 } 00684 00685 /* Update the SHA-3 hash state with message data. 00686 * 00687 * sha3 wc_Sha3 object holding state. 00688 * data Message data to be hashed. 00689 * len Length of the message data. 00690 * p Number of 64-bit numbers in a block of data to process. 00691 * returns 0 on success. 00692 */ 00693 static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) 00694 { 00695 int ret = 0; 00696 00697 if (sha3 == NULL || (data == NULL && len > 0)) { 00698 return BAD_FUNC_ARG; 00699 } 00700 00701 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) 00702 if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) { 00703 #if defined(HAVE_INTEL_QA) 00704 return IntelQaSymSha3(&sha3->asyncDev, NULL, data, len); 00705 #endif 00706 } 00707 #endif /* WOLFSSL_ASYNC_CRYPT */ 00708 00709 Sha3Update(sha3, data, len, p); 00710 00711 return ret; 00712 } 00713 00714 /* Calculate the SHA-3 hash based on all the message data seen. 00715 * 00716 * sha3 wc_Sha3 object holding state. 00717 * hash Buffer to hold the hash result. 00718 * p Number of 64-bit numbers in a block of data to process. 00719 * len Number of bytes in output. 00720 * returns 0 on success. 00721 */ 00722 static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) 00723 { 00724 int ret; 00725 00726 if (sha3 == NULL || hash == NULL) { 00727 return BAD_FUNC_ARG; 00728 } 00729 00730 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) 00731 if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) { 00732 #if defined(HAVE_INTEL_QA) 00733 return IntelQaSymSha3(&sha3->asyncDev, hash, NULL, 00734 SHA3_DIGEST_SIZE); 00735 #endif 00736 } 00737 #endif /* WOLFSSL_ASYNC_CRYPT */ 00738 00739 ret = Sha3Final(sha3, hash, p, len); 00740 if (ret != 0) 00741 return ret; 00742 00743 return InitSha3(sha3); /* reset state */ 00744 } 00745 00746 /* Dispose of any dynamically allocated data from the SHA3-384 operation. 00747 * (Required for async ops.) 00748 * 00749 * sha3 wc_Sha3 object holding state. 00750 * returns 0 on success. 00751 */ 00752 static void wc_Sha3Free(wc_Sha3* sha3) 00753 { 00754 (void)sha3; 00755 00756 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) 00757 if (sha3 == NULL) 00758 return; 00759 00760 wolfAsync_DevCtxFree(&sha3->asyncDev, WOLFSSL_ASYNC_MARKER_SHA3); 00761 #endif /* WOLFSSL_ASYNC_CRYPT */ 00762 } 00763 00764 00765 /* Copy the state of the SHA3 operation. 00766 * 00767 * src wc_Sha3 object holding state top copy. 00768 * dst wc_Sha3 object to copy into. 00769 * returns 0 on success. 00770 */ 00771 static int wc_Sha3Copy(wc_Sha3* src, wc_Sha3* dst) 00772 { 00773 int ret = 0; 00774 00775 if (src == NULL || dst == NULL) 00776 return BAD_FUNC_ARG; 00777 00778 XMEMCPY(dst, src, sizeof(wc_Sha3)); 00779 00780 #ifdef WOLFSSL_ASYNC_CRYPT 00781 ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); 00782 #endif 00783 00784 return ret; 00785 } 00786 00787 /* Calculate the SHA3-224 hash based on all the message data so far. 00788 * More message data can be added, after this operation, using the current 00789 * state. 00790 * 00791 * sha3 wc_Sha3 object holding state. 00792 * hash Buffer to hold the hash result. Must be at least 28 bytes. 00793 * p Number of 64-bit numbers in a block of data to process. 00794 * len Number of bytes in output. 00795 * returns 0 on success. 00796 */ 00797 static int wc_Sha3GetHash(wc_Sha3* sha3, byte* hash, byte p, byte len) 00798 { 00799 int ret; 00800 wc_Sha3 tmpSha3; 00801 00802 if (sha3 == NULL || hash == NULL) 00803 return BAD_FUNC_ARG; 00804 00805 ret = wc_Sha3Copy(sha3, &tmpSha3); 00806 if (ret == 0) { 00807 ret = wc_Sha3Final(&tmpSha3, hash, p, len); 00808 } 00809 return ret; 00810 } 00811 00812 00813 /* Initialize the state for a SHA3-224 hash operation. 00814 * 00815 * sha3 wc_Sha3 object holding state. 00816 * heap Heap reference for dynamic memory allocation. (Used in async ops.) 00817 * devId Device identifier for asynchronous operation. 00818 * returns 0 on success. 00819 */ 00820 WOLFSSL_API int wc_InitSha3_224(wc_Sha3* sha3, void* heap, int devId) 00821 { 00822 return wc_InitSha3(sha3, heap, devId); 00823 } 00824 00825 /* Update the SHA3-224 hash state with message data. 00826 * 00827 * sha3 wc_Sha3 object holding state. 00828 * data Message data to be hashed. 00829 * len Length of the message data. 00830 * returns 0 on success. 00831 */ 00832 WOLFSSL_API int wc_Sha3_224_Update(wc_Sha3* sha3, const byte* data, word32 len) 00833 { 00834 return wc_Sha3Update(sha3, data, len, WC_SHA3_224_COUNT); 00835 } 00836 00837 /* Calculate the SHA3-224 hash based on all the message data seen. 00838 * The state is initialized ready for a new message to hash. 00839 * 00840 * sha3 wc_Sha3 object holding state. 00841 * hash Buffer to hold the hash result. Must be at least 28 bytes. 00842 * returns 0 on success. 00843 */ 00844 WOLFSSL_API int wc_Sha3_224_Final(wc_Sha3* sha3, byte* hash) 00845 { 00846 return wc_Sha3Final(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE); 00847 } 00848 00849 /* Dispose of any dynamically allocated data from the SHA3-224 operation. 00850 * (Required for async ops.) 00851 * 00852 * sha3 wc_Sha3 object holding state. 00853 * returns 0 on success. 00854 */ 00855 WOLFSSL_API void wc_Sha3_224_Free(wc_Sha3* sha3) 00856 { 00857 wc_Sha3Free(sha3); 00858 } 00859 00860 /* Calculate the SHA3-224 hash based on all the message data so far. 00861 * More message data can be added, after this operation, using the current 00862 * state. 00863 * 00864 * sha3 wc_Sha3 object holding state. 00865 * hash Buffer to hold the hash result. Must be at least 28 bytes. 00866 * returns 0 on success. 00867 */ 00868 WOLFSSL_API int wc_Sha3_224_GetHash(wc_Sha3* sha3, byte* hash) 00869 { 00870 return wc_Sha3GetHash(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE); 00871 } 00872 00873 /* Copy the state of the SHA3-224 operation. 00874 * 00875 * src wc_Sha3 object holding state top copy. 00876 * dst wc_Sha3 object to copy into. 00877 * returns 0 on success. 00878 */ 00879 WOLFSSL_API int wc_Sha3_224_Copy(wc_Sha3* src, wc_Sha3* dst) 00880 { 00881 return wc_Sha3Copy(src, dst); 00882 } 00883 00884 00885 /* Initialize the state for a SHA3-256 hash operation. 00886 * 00887 * sha3 wc_Sha3 object holding state. 00888 * heap Heap reference for dynamic memory allocation. (Used in async ops.) 00889 * devId Device identifier for asynchronous operation. 00890 * returns 0 on success. 00891 */ 00892 WOLFSSL_API int wc_InitSha3_256(wc_Sha3* sha3, void* heap, int devId) 00893 { 00894 return wc_InitSha3(sha3, heap, devId); 00895 } 00896 00897 /* Update the SHA3-256 hash state with message data. 00898 * 00899 * sha3 wc_Sha3 object holding state. 00900 * data Message data to be hashed. 00901 * len Length of the message data. 00902 * returns 0 on success. 00903 */ 00904 WOLFSSL_API int wc_Sha3_256_Update(wc_Sha3* sha3, const byte* data, word32 len) 00905 { 00906 return wc_Sha3Update(sha3, data, len, WC_SHA3_256_COUNT); 00907 } 00908 00909 /* Calculate the SHA3-256 hash based on all the message data seen. 00910 * The state is initialized ready for a new message to hash. 00911 * 00912 * sha3 wc_Sha3 object holding state. 00913 * hash Buffer to hold the hash result. Must be at least 32 bytes. 00914 * returns 0 on success. 00915 */ 00916 WOLFSSL_API int wc_Sha3_256_Final(wc_Sha3* sha3, byte* hash) 00917 { 00918 return wc_Sha3Final(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE); 00919 } 00920 00921 /* Dispose of any dynamically allocated data from the SHA3-256 operation. 00922 * (Required for async ops.) 00923 * 00924 * sha3 wc_Sha3 object holding state. 00925 * returns 0 on success. 00926 */ 00927 WOLFSSL_API void wc_Sha3_256_Free(wc_Sha3* sha3) 00928 { 00929 wc_Sha3Free(sha3); 00930 } 00931 00932 /* Calculate the SHA3-256 hash based on all the message data so far. 00933 * More message data can be added, after this operation, using the current 00934 * state. 00935 * 00936 * sha3 wc_Sha3 object holding state. 00937 * hash Buffer to hold the hash result. Must be at least 32 bytes. 00938 * returns 0 on success. 00939 */ 00940 WOLFSSL_API int wc_Sha3_256_GetHash(wc_Sha3* sha3, byte* hash) 00941 { 00942 return wc_Sha3GetHash(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE); 00943 } 00944 00945 /* Copy the state of the SHA3-256 operation. 00946 * 00947 * src wc_Sha3 object holding state top copy. 00948 * dst wc_Sha3 object to copy into. 00949 * returns 0 on success. 00950 */ 00951 WOLFSSL_API int wc_Sha3_256_Copy(wc_Sha3* src, wc_Sha3* dst) 00952 { 00953 return wc_Sha3Copy(src, dst); 00954 } 00955 00956 00957 /* Initialize the state for a SHA3-384 hash operation. 00958 * 00959 * sha3 wc_Sha3 object holding state. 00960 * heap Heap reference for dynamic memory allocation. (Used in async ops.) 00961 * devId Device identifier for asynchronous operation. 00962 * returns 0 on success. 00963 */ 00964 WOLFSSL_API int wc_InitSha3_384(wc_Sha3* sha3, void* heap, int devId) 00965 { 00966 return wc_InitSha3(sha3, heap, devId); 00967 } 00968 00969 /* Update the SHA3-384 hash state with message data. 00970 * 00971 * sha3 wc_Sha3 object holding state. 00972 * data Message data to be hashed. 00973 * len Length of the message data. 00974 * returns 0 on success. 00975 */ 00976 WOLFSSL_API int wc_Sha3_384_Update(wc_Sha3* sha3, const byte* data, word32 len) 00977 { 00978 return wc_Sha3Update(sha3, data, len, WC_SHA3_384_COUNT); 00979 } 00980 00981 /* Calculate the SHA3-384 hash based on all the message data seen. 00982 * The state is initialized ready for a new message to hash. 00983 * 00984 * sha3 wc_Sha3 object holding state. 00985 * hash Buffer to hold the hash result. Must be at least 48 bytes. 00986 * returns 0 on success. 00987 */ 00988 WOLFSSL_API int wc_Sha3_384_Final(wc_Sha3* sha3, byte* hash) 00989 { 00990 return wc_Sha3Final(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE); 00991 } 00992 00993 /* Dispose of any dynamically allocated data from the SHA3-384 operation. 00994 * (Required for async ops.) 00995 * 00996 * sha3 wc_Sha3 object holding state. 00997 * returns 0 on success. 00998 */ 00999 WOLFSSL_API void wc_Sha3_384_Free(wc_Sha3* sha3) 01000 { 01001 wc_Sha3Free(sha3); 01002 } 01003 01004 /* Calculate the SHA3-384 hash based on all the message data so far. 01005 * More message data can be added, after this operation, using the current 01006 * state. 01007 * 01008 * sha3 wc_Sha3 object holding state. 01009 * hash Buffer to hold the hash result. Must be at least 48 bytes. 01010 * returns 0 on success. 01011 */ 01012 WOLFSSL_API int wc_Sha3_384_GetHash(wc_Sha3* sha3, byte* hash) 01013 { 01014 return wc_Sha3GetHash(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE); 01015 } 01016 01017 /* Copy the state of the SHA3-384 operation. 01018 * 01019 * src wc_Sha3 object holding state top copy. 01020 * dst wc_Sha3 object to copy into. 01021 * returns 0 on success. 01022 */ 01023 WOLFSSL_API int wc_Sha3_384_Copy(wc_Sha3* src, wc_Sha3* dst) 01024 { 01025 return wc_Sha3Copy(src, dst); 01026 } 01027 01028 01029 /* Initialize the state for a SHA3-512 hash operation. 01030 * 01031 * sha3 wc_Sha3 object holding state. 01032 * heap Heap reference for dynamic memory allocation. (Used in async ops.) 01033 * devId Device identifier for asynchronous operation. 01034 * returns 0 on success. 01035 */ 01036 WOLFSSL_API int wc_InitSha3_512(wc_Sha3* sha3, void* heap, int devId) 01037 { 01038 return wc_InitSha3(sha3, heap, devId); 01039 } 01040 01041 /* Update the SHA3-512 hash state with message data. 01042 * 01043 * sha3 wc_Sha3 object holding state. 01044 * data Message data to be hashed. 01045 * len Length of the message data. 01046 * returns 0 on success. 01047 */ 01048 WOLFSSL_API int wc_Sha3_512_Update(wc_Sha3* sha3, const byte* data, word32 len) 01049 { 01050 return wc_Sha3Update(sha3, data, len, WC_SHA3_512_COUNT); 01051 } 01052 01053 /* Calculate the SHA3-512 hash based on all the message data seen. 01054 * The state is initialized ready for a new message to hash. 01055 * 01056 * sha3 wc_Sha3 object holding state. 01057 * hash Buffer to hold the hash result. Must be at least 64 bytes. 01058 * returns 0 on success. 01059 */ 01060 WOLFSSL_API int wc_Sha3_512_Final(wc_Sha3* sha3, byte* hash) 01061 { 01062 return wc_Sha3Final(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE); 01063 } 01064 01065 /* Dispose of any dynamically allocated data from the SHA3-512 operation. 01066 * (Required for async ops.) 01067 * 01068 * sha3 wc_Sha3 object holding state. 01069 * returns 0 on success. 01070 */ 01071 WOLFSSL_API void wc_Sha3_512_Free(wc_Sha3* sha3) 01072 { 01073 wc_Sha3Free(sha3); 01074 } 01075 01076 /* Calculate the SHA3-512 hash based on all the message data so far. 01077 * More message data can be added, after this operation, using the current 01078 * state. 01079 * 01080 * sha3 wc_Sha3 object holding state. 01081 * hash Buffer to hold the hash result. Must be at least 64 bytes. 01082 * returns 0 on success. 01083 */ 01084 WOLFSSL_API int wc_Sha3_512_GetHash(wc_Sha3* sha3, byte* hash) 01085 { 01086 return wc_Sha3GetHash(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE); 01087 } 01088 01089 /* Copy the state of the SHA3-512 operation. 01090 * 01091 * src wc_Sha3 object holding state top copy. 01092 * dst wc_Sha3 object to copy into. 01093 * returns 0 on success. 01094 */ 01095 WOLFSSL_API int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst) 01096 { 01097 return wc_Sha3Copy(src, dst); 01098 } 01099 01100 #endif /* WOLFSSL_SHA3 */ 01101
Generated on Tue Jul 12 2022 16:58:07 by
1.7.2