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