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.
Dependents: HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL
sha256.c
00001 /* sha256.c 00002 * 00003 * Copyright (C) 2006-2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 00023 /* code submitted by raphael.huck@efixo.com */ 00024 00025 #ifdef HAVE_CONFIG_H 00026 #include <config.h> 00027 #endif 00028 00029 #include <cyassl/ctaocrypt/settings.h> 00030 00031 #if !defined(NO_SHA256) 00032 00033 #ifdef CYASSL_PIC32MZ_HASH 00034 #define InitSha256 InitSha256_sw 00035 #define Sha256Update Sha256Update_sw 00036 #define Sha256Final Sha256Final_sw 00037 #endif 00038 00039 #ifdef HAVE_FIPS 00040 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 00041 #define FIPS_NO_WRAPPERS 00042 #endif 00043 00044 #include <cyassl/ctaocrypt/sha256.h> 00045 #include <cyassl/ctaocrypt/logging.h> 00046 #include <cyassl/ctaocrypt/error-crypt.h> 00047 00048 #ifdef NO_INLINE 00049 #include <cyassl/ctaocrypt/misc.h> 00050 #else 00051 #include <ctaocrypt/src/misc.c> 00052 #endif 00053 00054 #ifdef FREESCALE_MMCAU 00055 #include "cau_api.h" 00056 #endif 00057 00058 #ifndef min 00059 00060 static INLINE word32 min(word32 a, word32 b) 00061 { 00062 return a > b ? b : a; 00063 } 00064 00065 #endif /* min */ 00066 00067 00068 int InitSha256(Sha256* sha256) 00069 { 00070 #ifdef FREESCALE_MMCAU 00071 cau_sha256_initialize_output(sha256->digest); 00072 #else 00073 sha256->digest[0] = 0x6A09E667L; 00074 sha256->digest[1] = 0xBB67AE85L; 00075 sha256->digest[2] = 0x3C6EF372L; 00076 sha256->digest[3] = 0xA54FF53AL; 00077 sha256->digest[4] = 0x510E527FL; 00078 sha256->digest[5] = 0x9B05688CL; 00079 sha256->digest[6] = 0x1F83D9ABL; 00080 sha256->digest[7] = 0x5BE0CD19L; 00081 #endif 00082 00083 sha256->buffLen = 0; 00084 sha256->loLen = 0; 00085 sha256->hiLen = 0; 00086 00087 return 0; 00088 } 00089 00090 #ifdef FREESCALE_MMCAU 00091 #define XTRANSFORM(S,B) Transform((S), (B)) 00092 00093 static int Transform(Sha256* sha256, byte* buf) 00094 { 00095 cau_sha256_hash_n(buf, 1, sha256->digest); 00096 00097 return 0; 00098 } 00099 00100 #else 00101 #define XTRANSFORM(S,B) Transform((S)) 00102 00103 static const word32 K[64] = { 00104 0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL, 00105 0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L, 00106 0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L, 00107 0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL, 00108 0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L, 00109 0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L, 00110 0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL, 00111 0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L, 00112 0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L, 00113 0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L, 00114 0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL, 00115 0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L, 00116 0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L 00117 }; 00118 00119 #define Ch(x,y,z) (z ^ (x & (y ^ z))) 00120 #define Maj(x,y,z) (((x | y) & z) | (x & y)) 00121 #define S(x, n) rotrFixed(x, n) 00122 #define R(x, n) (((x)&0xFFFFFFFFU)>>(n)) 00123 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) 00124 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) 00125 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) 00126 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) 00127 00128 #define RND(a,b,c,d,e,f,g,h,i) \ 00129 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ 00130 t1 = Sigma0(a) + Maj(a, b, c); \ 00131 d += t0; \ 00132 h = t0 + t1; 00133 00134 00135 static int Transform(Sha256* sha256) 00136 { 00137 word32 S[8], t0, t1; 00138 int i; 00139 00140 #ifdef CYASSL_SMALL_STACK 00141 word32* W; 00142 00143 W = (word32*) XMALLOC(sizeof(word32) * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00144 if (W == NULL) 00145 return MEMORY_E; 00146 #else 00147 word32 W[64]; 00148 #endif 00149 00150 /* Copy context->state[] to working vars */ 00151 for (i = 0; i < 8; i++) 00152 S[i] = sha256->digest[i]; 00153 00154 for (i = 0; i < 16; i++) 00155 W[i] = sha256->buffer[i]; 00156 00157 for (i = 16; i < 64; i++) 00158 W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16]; 00159 00160 for (i = 0; i < 64; i += 8) { 00161 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); 00162 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); 00163 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); 00164 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); 00165 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); 00166 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); 00167 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); 00168 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); 00169 } 00170 00171 /* Add the working vars back into digest state[] */ 00172 for (i = 0; i < 8; i++) { 00173 sha256->digest[i] += S[i]; 00174 } 00175 00176 #ifdef CYASSL_SMALL_STACK 00177 XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00178 #endif 00179 00180 return 0; 00181 } 00182 00183 #endif /* FREESCALE_MMCAU */ 00184 00185 00186 static INLINE void AddLength(Sha256* sha256, word32 len) 00187 { 00188 word32 tmp = sha256->loLen; 00189 if ( (sha256->loLen += len) < tmp) 00190 sha256->hiLen++; /* carry low to high */ 00191 } 00192 00193 00194 int Sha256Update(Sha256* sha256, const byte* data, word32 len) 00195 { 00196 /* do block size increments */ 00197 byte* local = (byte*)sha256->buffer; 00198 00199 while (len) { 00200 word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen); 00201 XMEMCPY(&local[sha256->buffLen], data, add); 00202 00203 sha256->buffLen += add; 00204 data += add; 00205 len -= add; 00206 00207 if (sha256->buffLen == SHA256_BLOCK_SIZE) { 00208 int ret; 00209 00210 #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) 00211 ByteReverseWords(sha256->buffer, sha256->buffer, 00212 SHA256_BLOCK_SIZE); 00213 #endif 00214 00215 ret = XTRANSFORM(sha256, local); 00216 if (ret != 0) 00217 return ret; 00218 00219 AddLength(sha256, SHA256_BLOCK_SIZE); 00220 sha256->buffLen = 0; 00221 } 00222 } 00223 00224 return 0; 00225 } 00226 00227 00228 int Sha256Final(Sha256* sha256, byte* hash) 00229 { 00230 byte* local = (byte*)sha256->buffer; 00231 int ret; 00232 00233 AddLength(sha256, sha256->buffLen); /* before adding pads */ 00234 00235 local[sha256->buffLen++] = 0x80; /* add 1 */ 00236 00237 /* pad with zeros */ 00238 if (sha256->buffLen > SHA256_PAD_SIZE) { 00239 XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen); 00240 sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen; 00241 00242 #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) 00243 ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE); 00244 #endif 00245 00246 ret = XTRANSFORM(sha256, local); 00247 if (ret != 0) 00248 return ret; 00249 00250 sha256->buffLen = 0; 00251 } 00252 XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen); 00253 00254 /* put lengths in bits */ 00255 sha256->hiLen = (sha256->loLen >> (8*sizeof(sha256->loLen) - 3)) + 00256 (sha256->hiLen << 3); 00257 sha256->loLen = sha256->loLen << 3; 00258 00259 /* store lengths */ 00260 #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) 00261 ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE); 00262 #endif 00263 /* ! length ordering dependent on digest endian type ! */ 00264 XMEMCPY(&local[SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32)); 00265 XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, 00266 sizeof(word32)); 00267 00268 #ifdef FREESCALE_MMCAU 00269 /* Kinetis requires only these bytes reversed */ 00270 ByteReverseWords(&sha256->buffer[SHA256_PAD_SIZE/sizeof(word32)], 00271 &sha256->buffer[SHA256_PAD_SIZE/sizeof(word32)], 00272 2 * sizeof(word32)); 00273 #endif 00274 00275 ret = XTRANSFORM(sha256, local); 00276 if (ret != 0) 00277 return ret; 00278 00279 #ifdef LITTLE_ENDIAN_ORDER 00280 ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE); 00281 #endif 00282 XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE); 00283 00284 return InitSha256(sha256); /* reset state */ 00285 } 00286 00287 00288 int Sha256Hash(const byte* data, word32 len, byte* hash) 00289 { 00290 int ret = 0; 00291 #ifdef CYASSL_SMALL_STACK 00292 Sha256* sha256; 00293 #else 00294 Sha256 sha256[1]; 00295 #endif 00296 00297 #ifdef CYASSL_SMALL_STACK 00298 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00299 if (sha256 == NULL) 00300 return MEMORY_E; 00301 #endif 00302 00303 if ((ret = InitSha256(sha256)) != 0) { 00304 CYASSL_MSG("InitSha256 failed"); 00305 } 00306 else if ((ret = Sha256Update(sha256, data, len)) != 0) { 00307 CYASSL_MSG("Sha256Update failed"); 00308 } 00309 else if ((ret = Sha256Final(sha256, hash)) != 0) { 00310 CYASSL_MSG("Sha256Final failed"); 00311 } 00312 00313 #ifdef CYASSL_SMALL_STACK 00314 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00315 #endif 00316 00317 return ret; 00318 } 00319 00320 00321 #endif /* NO_SHA256 */ 00322
Generated on Wed Jul 13 2022 02:33:57 by
1.7.2