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.
sha512.c
00001 /* sha512.c 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL 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 * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifdef CYASSL_SHA512 00029 00030 #ifdef HAVE_FIPS 00031 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 00032 #define FIPS_NO_WRAPPERS 00033 #endif 00034 00035 #include <cyassl/ctaocrypt/sha512.h> 00036 #ifdef NO_INLINE 00037 #include <cyassl/ctaocrypt/misc.h> 00038 #else 00039 #include <ctaocrypt/src/misc.c> 00040 #endif 00041 00042 00043 #ifndef min 00044 00045 static INLINE word32 min(word32 a, word32 b) 00046 { 00047 return a > b ? b : a; 00048 } 00049 00050 #endif /* min */ 00051 00052 00053 int InitSha512(Sha512* sha512) 00054 { 00055 sha512->digest[0] = W64LIT(0x6a09e667f3bcc908); 00056 sha512->digest[1] = W64LIT(0xbb67ae8584caa73b); 00057 sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b); 00058 sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1); 00059 sha512->digest[4] = W64LIT(0x510e527fade682d1); 00060 sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f); 00061 sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b); 00062 sha512->digest[7] = W64LIT(0x5be0cd19137e2179); 00063 00064 sha512->buffLen = 0; 00065 sha512->loLen = 0; 00066 sha512->hiLen = 0; 00067 00068 return 0; 00069 } 00070 00071 00072 static const word64 K512[80] = { 00073 W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), 00074 W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), 00075 W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), 00076 W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), 00077 W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), 00078 W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), 00079 W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), 00080 W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), 00081 W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), 00082 W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), 00083 W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), 00084 W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), 00085 W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), 00086 W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), 00087 W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), 00088 W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), 00089 W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), 00090 W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), 00091 W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), 00092 W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), 00093 W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), 00094 W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), 00095 W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), 00096 W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), 00097 W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), 00098 W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), 00099 W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), 00100 W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), 00101 W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), 00102 W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), 00103 W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), 00104 W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), 00105 W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), 00106 W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), 00107 W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), 00108 W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), 00109 W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), 00110 W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), 00111 W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), 00112 W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) 00113 }; 00114 00115 00116 #define blk0(i) (W[i] = sha512->buffer[i]) 00117 #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) 00118 00119 #define Ch(x,y,z) (z^(x&(y^z))) 00120 #define Maj(x,y,z) ((x&y)|(z&(x|y))) 00121 00122 #define a(i) T[(0-i)&7] 00123 #define b(i) T[(1-i)&7] 00124 #define c(i) T[(2-i)&7] 00125 #define d(i) T[(3-i)&7] 00126 #define e(i) T[(4-i)&7] 00127 #define f(i) T[(5-i)&7] 00128 #define g(i) T[(6-i)&7] 00129 #define h(i) T[(7-i)&7] 00130 00131 #define S0(x) (rotrFixed64(x,28)^rotrFixed64(x,34)^rotrFixed64(x,39)) 00132 #define S1(x) (rotrFixed64(x,14)^rotrFixed64(x,18)^rotrFixed64(x,41)) 00133 #define s0(x) (rotrFixed64(x,1)^rotrFixed64(x,8)^(x>>7)) 00134 #define s1(x) (rotrFixed64(x,19)^rotrFixed64(x,61)^(x>>6)) 00135 00136 #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk0(i));\ 00137 d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) 00138 00139 #define blk384(i) (W[i] = sha384->buffer[i]) 00140 00141 #define R2(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk384(i));\ 00142 d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) 00143 00144 00145 static void Transform(Sha512* sha512) 00146 { 00147 const word64* K = K512; 00148 00149 word32 j; 00150 word64 W[16]; 00151 word64 T[8]; 00152 00153 /* Copy digest to working vars */ 00154 XMEMCPY(T, sha512->digest, sizeof(T)); 00155 00156 #ifdef USE_SLOW_SHA2 00157 /* over twice as small, but 50% slower */ 00158 /* 80 operations, not unrolled */ 00159 for (j = 0; j < 80; j += 16) { 00160 int m; 00161 for (m = 0; m < 16; m++) { /* braces needed here for macros {} */ 00162 R(m); 00163 } 00164 } 00165 #else 00166 /* 80 operations, partially loop unrolled */ 00167 for (j = 0; j < 80; j += 16) { 00168 R( 0); R( 1); R( 2); R( 3); 00169 R( 4); R( 5); R( 6); R( 7); 00170 R( 8); R( 9); R(10); R(11); 00171 R(12); R(13); R(14); R(15); 00172 } 00173 #endif /* USE_SLOW_SHA2 */ 00174 00175 /* Add the working vars back into digest */ 00176 00177 sha512->digest[0] += a(0); 00178 sha512->digest[1] += b(0); 00179 sha512->digest[2] += c(0); 00180 sha512->digest[3] += d(0); 00181 sha512->digest[4] += e(0); 00182 sha512->digest[5] += f(0); 00183 sha512->digest[6] += g(0); 00184 sha512->digest[7] += h(0); 00185 00186 /* Wipe variables */ 00187 XMEMSET(W, 0, sizeof(W)); 00188 XMEMSET(T, 0, sizeof(T)); 00189 } 00190 00191 00192 static INLINE void AddLength(Sha512* sha512, word32 len) 00193 { 00194 word32 tmp = sha512->loLen; 00195 if ( (sha512->loLen += len) < tmp) 00196 sha512->hiLen++; /* carry low to high */ 00197 } 00198 00199 00200 int Sha512Update(Sha512* sha512, const byte* data, word32 len) 00201 { 00202 /* do block size increments */ 00203 byte* local = (byte*)sha512->buffer; 00204 00205 while (len) { 00206 word32 add = min(len, SHA512_BLOCK_SIZE - sha512->buffLen); 00207 XMEMCPY(&local[sha512->buffLen], data, add); 00208 00209 sha512->buffLen += add; 00210 data += add; 00211 len -= add; 00212 00213 if (sha512->buffLen == SHA512_BLOCK_SIZE) { 00214 #ifdef LITTLE_ENDIAN_ORDER 00215 ByteReverseWords64(sha512->buffer, sha512->buffer, 00216 SHA512_BLOCK_SIZE); 00217 #endif 00218 Transform(sha512); 00219 AddLength(sha512, SHA512_BLOCK_SIZE); 00220 sha512->buffLen = 0; 00221 } 00222 } 00223 return 0; 00224 } 00225 00226 00227 int Sha512Final(Sha512* sha512, byte* hash) 00228 { 00229 byte* local = (byte*)sha512->buffer; 00230 00231 AddLength(sha512, sha512->buffLen); /* before adding pads */ 00232 00233 local[sha512->buffLen++] = 0x80; /* add 1 */ 00234 00235 /* pad with zeros */ 00236 if (sha512->buffLen > SHA512_PAD_SIZE) { 00237 XMEMSET(&local[sha512->buffLen], 0, SHA512_BLOCK_SIZE -sha512->buffLen); 00238 sha512->buffLen += SHA512_BLOCK_SIZE - sha512->buffLen; 00239 00240 #ifdef LITTLE_ENDIAN_ORDER 00241 ByteReverseWords64(sha512->buffer,sha512->buffer,SHA512_BLOCK_SIZE); 00242 #endif 00243 Transform(sha512); 00244 sha512->buffLen = 0; 00245 } 00246 XMEMSET(&local[sha512->buffLen], 0, SHA512_PAD_SIZE - sha512->buffLen); 00247 00248 /* put lengths in bits */ 00249 sha512->hiLen = (sha512->loLen >> (8*sizeof(sha512->loLen) - 3)) + 00250 (sha512->hiLen << 3); 00251 sha512->loLen = sha512->loLen << 3; 00252 00253 /* store lengths */ 00254 #ifdef LITTLE_ENDIAN_ORDER 00255 ByteReverseWords64(sha512->buffer, sha512->buffer, SHA512_PAD_SIZE); 00256 #endif 00257 /* ! length ordering dependent on digest endian type ! */ 00258 sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen; 00259 sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen; 00260 00261 Transform(sha512); 00262 #ifdef LITTLE_ENDIAN_ORDER 00263 ByteReverseWords64(sha512->digest, sha512->digest, SHA512_DIGEST_SIZE); 00264 #endif 00265 XMEMCPY(hash, sha512->digest, SHA512_DIGEST_SIZE); 00266 00267 return InitSha512(sha512); /* reset state */ 00268 } 00269 00270 00271 00272 #ifdef CYASSL_SHA384 00273 00274 int InitSha384(Sha384* sha384) 00275 { 00276 sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8); 00277 sha384->digest[1] = W64LIT(0x629a292a367cd507); 00278 sha384->digest[2] = W64LIT(0x9159015a3070dd17); 00279 sha384->digest[3] = W64LIT(0x152fecd8f70e5939); 00280 sha384->digest[4] = W64LIT(0x67332667ffc00b31); 00281 sha384->digest[5] = W64LIT(0x8eb44a8768581511); 00282 sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7); 00283 sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4); 00284 00285 sha384->buffLen = 0; 00286 sha384->loLen = 0; 00287 sha384->hiLen = 0; 00288 00289 return 0; 00290 } 00291 00292 00293 static void Transform384(Sha384* sha384) 00294 { 00295 const word64* K = K512; 00296 00297 word32 j; 00298 word64 W[16]; 00299 word64 T[8]; 00300 00301 /* Copy digest to working vars */ 00302 XMEMCPY(T, sha384->digest, sizeof(T)); 00303 00304 #ifdef USE_SLOW_SHA2 00305 /* over twice as small, but 50% slower */ 00306 /* 80 operations, not unrolled */ 00307 for (j = 0; j < 80; j += 16) { 00308 int m; 00309 for (m = 0; m < 16; m++) { /* braces needed for macros {} */ 00310 R2(m); 00311 } 00312 } 00313 #else 00314 /* 80 operations, partially loop unrolled */ 00315 for (j = 0; j < 80; j += 16) { 00316 R2( 0); R2( 1); R2( 2); R2( 3); 00317 R2( 4); R2( 5); R2( 6); R2( 7); 00318 R2( 8); R2( 9); R2(10); R2(11); 00319 R2(12); R2(13); R2(14); R2(15); 00320 } 00321 #endif /* USE_SLOW_SHA2 */ 00322 00323 /* Add the working vars back into digest */ 00324 00325 sha384->digest[0] += a(0); 00326 sha384->digest[1] += b(0); 00327 sha384->digest[2] += c(0); 00328 sha384->digest[3] += d(0); 00329 sha384->digest[4] += e(0); 00330 sha384->digest[5] += f(0); 00331 sha384->digest[6] += g(0); 00332 sha384->digest[7] += h(0); 00333 00334 /* Wipe variables */ 00335 XMEMSET(W, 0, sizeof(W)); 00336 XMEMSET(T, 0, sizeof(T)); 00337 } 00338 00339 00340 static INLINE void AddLength384(Sha384* sha384, word32 len) 00341 { 00342 word32 tmp = sha384->loLen; 00343 if ( (sha384->loLen += len) < tmp) 00344 sha384->hiLen++; /* carry low to high */ 00345 } 00346 00347 00348 int Sha384Update(Sha384* sha384, const byte* data, word32 len) 00349 { 00350 /* do block size increments */ 00351 byte* local = (byte*)sha384->buffer; 00352 00353 while (len) { 00354 word32 add = min(len, SHA384_BLOCK_SIZE - sha384->buffLen); 00355 XMEMCPY(&local[sha384->buffLen], data, add); 00356 00357 sha384->buffLen += add; 00358 data += add; 00359 len -= add; 00360 00361 if (sha384->buffLen == SHA384_BLOCK_SIZE) { 00362 #ifdef LITTLE_ENDIAN_ORDER 00363 ByteReverseWords64(sha384->buffer, sha384->buffer, 00364 SHA384_BLOCK_SIZE); 00365 #endif 00366 Transform384(sha384); 00367 AddLength384(sha384, SHA384_BLOCK_SIZE); 00368 sha384->buffLen = 0; 00369 } 00370 } 00371 return 0; 00372 } 00373 00374 00375 int Sha384Final(Sha384* sha384, byte* hash) 00376 { 00377 byte* local = (byte*)sha384->buffer; 00378 00379 AddLength384(sha384, sha384->buffLen); /* before adding pads */ 00380 00381 local[sha384->buffLen++] = 0x80; /* add 1 */ 00382 00383 /* pad with zeros */ 00384 if (sha384->buffLen > SHA384_PAD_SIZE) { 00385 XMEMSET(&local[sha384->buffLen], 0, SHA384_BLOCK_SIZE -sha384->buffLen); 00386 sha384->buffLen += SHA384_BLOCK_SIZE - sha384->buffLen; 00387 00388 #ifdef LITTLE_ENDIAN_ORDER 00389 ByteReverseWords64(sha384->buffer,sha384->buffer,SHA384_BLOCK_SIZE); 00390 #endif 00391 Transform384(sha384); 00392 sha384->buffLen = 0; 00393 } 00394 XMEMSET(&local[sha384->buffLen], 0, SHA384_PAD_SIZE - sha384->buffLen); 00395 00396 /* put lengths in bits */ 00397 sha384->hiLen = (sha384->loLen >> (8*sizeof(sha384->loLen) - 3)) + 00398 (sha384->hiLen << 3); 00399 sha384->loLen = sha384->loLen << 3; 00400 00401 /* store lengths */ 00402 #ifdef LITTLE_ENDIAN_ORDER 00403 ByteReverseWords64(sha384->buffer, sha384->buffer, SHA384_PAD_SIZE); 00404 #endif 00405 /* ! length ordering dependent on digest endian type ! */ 00406 sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 2] = sha384->hiLen; 00407 sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 1] = sha384->loLen; 00408 00409 Transform384(sha384); 00410 #ifdef LITTLE_ENDIAN_ORDER 00411 ByteReverseWords64(sha384->digest, sha384->digest, SHA384_DIGEST_SIZE); 00412 #endif 00413 XMEMCPY(hash, sha384->digest, SHA384_DIGEST_SIZE); 00414 00415 return InitSha384(sha384); /* reset state */ 00416 } 00417 00418 #endif /* CYASSL_SHA384 */ 00419 00420 #endif /* CYASSL_SHA512 */
Generated on Tue Jul 12 2022 20:12:51 by
