This is a port of cyaSSL 2.7.0.

Dependents:   CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet

Committer:
ashleymills
Date:
Thu Sep 05 15:55:50 2013 +0000
Revision:
1:c0ce1562443a
Parent:
0:714293de3836
Nothing;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:714293de3836 1 /* sha.c
ashleymills 0:714293de3836 2 *
ashleymills 0:714293de3836 3 * Copyright (C) 2006-2013 wolfSSL Inc.
ashleymills 0:714293de3836 4 *
ashleymills 0:714293de3836 5 * This file is part of CyaSSL.
ashleymills 0:714293de3836 6 *
ashleymills 0:714293de3836 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:714293de3836 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:714293de3836 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:714293de3836 10 * (at your option) any later version.
ashleymills 0:714293de3836 11 *
ashleymills 0:714293de3836 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:714293de3836 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:714293de3836 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:714293de3836 15 * GNU General Public License for more details.
ashleymills 0:714293de3836 16 *
ashleymills 0:714293de3836 17 * You should have received a copy of the GNU General Public License
ashleymills 0:714293de3836 18 * along with this program; if not, write to the Free Software
ashleymills 0:714293de3836 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:714293de3836 20 */
ashleymills 0:714293de3836 21
ashleymills 0:714293de3836 22
ashleymills 0:714293de3836 23 #ifdef HAVE_CONFIG_H
ashleymills 0:714293de3836 24 #include <config.h>
ashleymills 0:714293de3836 25 #endif
ashleymills 0:714293de3836 26
ashleymills 0:714293de3836 27 #include <cyassl/ctaocrypt/settings.h>
ashleymills 0:714293de3836 28
ashleymills 0:714293de3836 29 #ifndef NO_SHA
ashleymills 0:714293de3836 30
ashleymills 0:714293de3836 31 #include <cyassl/ctaocrypt/sha.h>
ashleymills 0:714293de3836 32 #ifdef NO_INLINE
ashleymills 0:714293de3836 33 #include <cyassl/ctaocrypt/misc.h>
ashleymills 0:714293de3836 34 #else
ashleymills 0:714293de3836 35 #include <ctaocrypt/src/misc.c>
ashleymills 0:714293de3836 36 #endif
ashleymills 0:714293de3836 37
ashleymills 0:714293de3836 38
ashleymills 0:714293de3836 39 #ifdef STM32F2_HASH
ashleymills 0:714293de3836 40 /*
ashleymills 0:714293de3836 41 * STM32F2 hardware SHA1 support through the STM32F2 standard peripheral
ashleymills 0:714293de3836 42 * library. Documentation located in STM32F2xx Standard Peripheral Library
ashleymills 0:714293de3836 43 * document (See note in README).
ashleymills 0:714293de3836 44 */
ashleymills 0:714293de3836 45 #include "stm32f2xx.h"
ashleymills 0:714293de3836 46 #include "stm32f2xx_hash.h"
ashleymills 0:714293de3836 47
ashleymills 0:714293de3836 48 void InitSha(Sha* sha)
ashleymills 0:714293de3836 49 {
ashleymills 0:714293de3836 50 /* STM32F2 struct notes:
ashleymills 0:714293de3836 51 * sha->buffer = first 4 bytes used to hold partial block if needed
ashleymills 0:714293de3836 52 * sha->buffLen = num bytes currently stored in sha->buffer
ashleymills 0:714293de3836 53 * sha->loLen = num bytes that have been written to STM32 FIFO
ashleymills 0:714293de3836 54 */
ashleymills 0:714293de3836 55 XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
ashleymills 0:714293de3836 56 sha->buffLen = 0;
ashleymills 0:714293de3836 57 sha->loLen = 0;
ashleymills 0:714293de3836 58
ashleymills 0:714293de3836 59 /* initialize HASH peripheral */
ashleymills 0:714293de3836 60 HASH_DeInit();
ashleymills 0:714293de3836 61
ashleymills 0:714293de3836 62 /* configure algo used, algo mode, datatype */
ashleymills 0:714293de3836 63 HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
ashleymills 0:714293de3836 64 HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HASH
ashleymills 0:714293de3836 65 | HASH_DataType_8b);
ashleymills 0:714293de3836 66
ashleymills 0:714293de3836 67 /* reset HASH processor */
ashleymills 0:714293de3836 68 HASH->CR |= HASH_CR_INIT;
ashleymills 0:714293de3836 69 }
ashleymills 0:714293de3836 70
ashleymills 0:714293de3836 71 void ShaUpdate(Sha* sha, const byte* data, word32 len)
ashleymills 0:714293de3836 72 {
ashleymills 0:714293de3836 73 word32 i = 0;
ashleymills 0:714293de3836 74 word32 fill = 0;
ashleymills 0:714293de3836 75 word32 diff = 0;
ashleymills 0:714293de3836 76
ashleymills 0:714293de3836 77 /* if saved partial block is available */
ashleymills 0:714293de3836 78 if (sha->buffLen) {
ashleymills 0:714293de3836 79 fill = 4 - sha->buffLen;
ashleymills 0:714293de3836 80
ashleymills 0:714293de3836 81 /* if enough data to fill, fill and push to FIFO */
ashleymills 0:714293de3836 82 if (fill <= len) {
ashleymills 0:714293de3836 83 XMEMCPY((byte*)sha->buffer + sha->buffLen, data, fill);
ashleymills 0:714293de3836 84 HASH_DataIn(*(uint32_t*)sha->buffer);
ashleymills 0:714293de3836 85
ashleymills 0:714293de3836 86 data += fill;
ashleymills 0:714293de3836 87 len -= fill;
ashleymills 0:714293de3836 88 sha->loLen += 4;
ashleymills 0:714293de3836 89 sha->buffLen = 0;
ashleymills 0:714293de3836 90 } else {
ashleymills 0:714293de3836 91 /* append partial to existing stored block */
ashleymills 0:714293de3836 92 XMEMCPY((byte*)sha->buffer + sha->buffLen, data, len);
ashleymills 0:714293de3836 93 sha->buffLen += len;
ashleymills 0:714293de3836 94 return;
ashleymills 0:714293de3836 95 }
ashleymills 0:714293de3836 96 }
ashleymills 0:714293de3836 97
ashleymills 0:714293de3836 98 /* write input block in the IN FIFO */
ashleymills 0:714293de3836 99 for(i = 0; i < len; i += 4)
ashleymills 0:714293de3836 100 {
ashleymills 0:714293de3836 101 diff = len - i;
ashleymills 0:714293de3836 102 if ( diff < 4) {
ashleymills 0:714293de3836 103 /* store incomplete last block, not yet in FIFO */
ashleymills 0:714293de3836 104 XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
ashleymills 0:714293de3836 105 XMEMCPY((byte*)sha->buffer, data, diff);
ashleymills 0:714293de3836 106 sha->buffLen = diff;
ashleymills 0:714293de3836 107 } else {
ashleymills 0:714293de3836 108 HASH_DataIn(*(uint32_t*)data);
ashleymills 0:714293de3836 109 data+=4;
ashleymills 0:714293de3836 110 }
ashleymills 0:714293de3836 111 }
ashleymills 0:714293de3836 112
ashleymills 0:714293de3836 113 /* keep track of total data length thus far */
ashleymills 0:714293de3836 114 sha->loLen += (len - sha->buffLen);
ashleymills 0:714293de3836 115 }
ashleymills 0:714293de3836 116
ashleymills 0:714293de3836 117 void ShaFinal(Sha* sha, byte* hash)
ashleymills 0:714293de3836 118 {
ashleymills 0:714293de3836 119 __IO uint16_t nbvalidbitsdata = 0;
ashleymills 0:714293de3836 120
ashleymills 0:714293de3836 121 /* finish reading any trailing bytes into FIFO */
ashleymills 0:714293de3836 122 if (sha->buffLen) {
ashleymills 0:714293de3836 123 HASH_DataIn(*(uint32_t*)sha->buffer);
ashleymills 0:714293de3836 124 sha->loLen += sha->buffLen;
ashleymills 0:714293de3836 125 }
ashleymills 0:714293de3836 126
ashleymills 0:714293de3836 127 /* calculate number of valid bits in last word of input data */
ashleymills 0:714293de3836 128 nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE);
ashleymills 0:714293de3836 129
ashleymills 0:714293de3836 130 /* configure number of valid bits in last word of the data */
ashleymills 0:714293de3836 131 HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
ashleymills 0:714293de3836 132
ashleymills 0:714293de3836 133 /* start HASH processor */
ashleymills 0:714293de3836 134 HASH_StartDigest();
ashleymills 0:714293de3836 135
ashleymills 0:714293de3836 136 /* wait until Busy flag == RESET */
ashleymills 0:714293de3836 137 while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
ashleymills 0:714293de3836 138
ashleymills 0:714293de3836 139 /* read message digest */
ashleymills 0:714293de3836 140 sha->digest[0] = HASH->HR[0];
ashleymills 0:714293de3836 141 sha->digest[1] = HASH->HR[1];
ashleymills 0:714293de3836 142 sha->digest[2] = HASH->HR[2];
ashleymills 0:714293de3836 143 sha->digest[3] = HASH->HR[3];
ashleymills 0:714293de3836 144 sha->digest[4] = HASH->HR[4];
ashleymills 0:714293de3836 145
ashleymills 0:714293de3836 146 ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
ashleymills 0:714293de3836 147
ashleymills 0:714293de3836 148 XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
ashleymills 0:714293de3836 149
ashleymills 0:714293de3836 150 InitSha(sha); /* reset state */
ashleymills 0:714293de3836 151 }
ashleymills 0:714293de3836 152
ashleymills 0:714293de3836 153 #else /* CTaoCrypt software implementation */
ashleymills 0:714293de3836 154
ashleymills 0:714293de3836 155 #ifndef min
ashleymills 0:714293de3836 156
ashleymills 0:714293de3836 157 static INLINE word32 min(word32 a, word32 b)
ashleymills 0:714293de3836 158 {
ashleymills 0:714293de3836 159 return a > b ? b : a;
ashleymills 0:714293de3836 160 }
ashleymills 0:714293de3836 161
ashleymills 0:714293de3836 162 #endif /* min */
ashleymills 0:714293de3836 163
ashleymills 0:714293de3836 164
ashleymills 0:714293de3836 165 void InitSha(Sha* sha)
ashleymills 0:714293de3836 166 {
ashleymills 0:714293de3836 167 sha->digest[0] = 0x67452301L;
ashleymills 0:714293de3836 168 sha->digest[1] = 0xEFCDAB89L;
ashleymills 0:714293de3836 169 sha->digest[2] = 0x98BADCFEL;
ashleymills 0:714293de3836 170 sha->digest[3] = 0x10325476L;
ashleymills 0:714293de3836 171 sha->digest[4] = 0xC3D2E1F0L;
ashleymills 0:714293de3836 172
ashleymills 0:714293de3836 173 sha->buffLen = 0;
ashleymills 0:714293de3836 174 sha->loLen = 0;
ashleymills 0:714293de3836 175 sha->hiLen = 0;
ashleymills 0:714293de3836 176 }
ashleymills 0:714293de3836 177
ashleymills 0:714293de3836 178 #define blk0(i) (W[i] = sha->buffer[i])
ashleymills 0:714293de3836 179 #define blk1(i) (W[i&15] = \
ashleymills 0:714293de3836 180 rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
ashleymills 0:714293de3836 181
ashleymills 0:714293de3836 182 #define f1(x,y,z) (z^(x &(y^z)))
ashleymills 0:714293de3836 183 #define f2(x,y,z) (x^y^z)
ashleymills 0:714293de3836 184 #define f3(x,y,z) ((x&y)|(z&(x|y)))
ashleymills 0:714293de3836 185 #define f4(x,y,z) (x^y^z)
ashleymills 0:714293de3836 186
ashleymills 0:714293de3836 187 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
ashleymills 0:714293de3836 188 #define R0(v,w,x,y,z,i) z+= f1(w,x,y) + blk0(i) + 0x5A827999+ \
ashleymills 0:714293de3836 189 rotlFixed(v,5); w = rotlFixed(w,30);
ashleymills 0:714293de3836 190 #define R1(v,w,x,y,z,i) z+= f1(w,x,y) + blk1(i) + 0x5A827999+ \
ashleymills 0:714293de3836 191 rotlFixed(v,5); w = rotlFixed(w,30);
ashleymills 0:714293de3836 192 #define R2(v,w,x,y,z,i) z+= f2(w,x,y) + blk1(i) + 0x6ED9EBA1+ \
ashleymills 0:714293de3836 193 rotlFixed(v,5); w = rotlFixed(w,30);
ashleymills 0:714293de3836 194 #define R3(v,w,x,y,z,i) z+= f3(w,x,y) + blk1(i) + 0x8F1BBCDC+ \
ashleymills 0:714293de3836 195 rotlFixed(v,5); w = rotlFixed(w,30);
ashleymills 0:714293de3836 196 #define R4(v,w,x,y,z,i) z+= f4(w,x,y) + blk1(i) + 0xCA62C1D6+ \
ashleymills 0:714293de3836 197 rotlFixed(v,5); w = rotlFixed(w,30);
ashleymills 0:714293de3836 198
ashleymills 0:714293de3836 199
ashleymills 0:714293de3836 200 static void Transform(Sha* sha)
ashleymills 0:714293de3836 201 {
ashleymills 0:714293de3836 202 word32 W[SHA_BLOCK_SIZE / sizeof(word32)];
ashleymills 0:714293de3836 203
ashleymills 0:714293de3836 204 /* Copy context->state[] to working vars */
ashleymills 0:714293de3836 205 word32 a = sha->digest[0];
ashleymills 0:714293de3836 206 word32 b = sha->digest[1];
ashleymills 0:714293de3836 207 word32 c = sha->digest[2];
ashleymills 0:714293de3836 208 word32 d = sha->digest[3];
ashleymills 0:714293de3836 209 word32 e = sha->digest[4];
ashleymills 0:714293de3836 210
ashleymills 0:714293de3836 211 #ifdef USE_SLOW_SHA
ashleymills 0:714293de3836 212 word32 t, i;
ashleymills 0:714293de3836 213
ashleymills 0:714293de3836 214 for (i = 0; i < 16; i++) {
ashleymills 0:714293de3836 215 R0(a, b, c, d, e, i);
ashleymills 0:714293de3836 216 t = e; e = d; d = c; c = b; b = a; a = t;
ashleymills 0:714293de3836 217 }
ashleymills 0:714293de3836 218
ashleymills 0:714293de3836 219 for (; i < 20; i++) {
ashleymills 0:714293de3836 220 R1(a, b, c, d, e, i);
ashleymills 0:714293de3836 221 t = e; e = d; d = c; c = b; b = a; a = t;
ashleymills 0:714293de3836 222 }
ashleymills 0:714293de3836 223
ashleymills 0:714293de3836 224 for (; i < 40; i++) {
ashleymills 0:714293de3836 225 R2(a, b, c, d, e, i);
ashleymills 0:714293de3836 226 t = e; e = d; d = c; c = b; b = a; a = t;
ashleymills 0:714293de3836 227 }
ashleymills 0:714293de3836 228
ashleymills 0:714293de3836 229 for (; i < 60; i++) {
ashleymills 0:714293de3836 230 R3(a, b, c, d, e, i);
ashleymills 0:714293de3836 231 t = e; e = d; d = c; c = b; b = a; a = t;
ashleymills 0:714293de3836 232 }
ashleymills 0:714293de3836 233
ashleymills 0:714293de3836 234 for (; i < 80; i++) {
ashleymills 0:714293de3836 235 R4(a, b, c, d, e, i);
ashleymills 0:714293de3836 236 t = e; e = d; d = c; c = b; b = a; a = t;
ashleymills 0:714293de3836 237 }
ashleymills 0:714293de3836 238 #else
ashleymills 0:714293de3836 239 /* nearly 1 K bigger in code size but 25% faster */
ashleymills 0:714293de3836 240 /* 4 rounds of 20 operations each. Loop unrolled. */
ashleymills 0:714293de3836 241 R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
ashleymills 0:714293de3836 242 R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
ashleymills 0:714293de3836 243 R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
ashleymills 0:714293de3836 244 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
ashleymills 0:714293de3836 245
ashleymills 0:714293de3836 246 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
ashleymills 0:714293de3836 247
ashleymills 0:714293de3836 248 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
ashleymills 0:714293de3836 249 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
ashleymills 0:714293de3836 250 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
ashleymills 0:714293de3836 251 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
ashleymills 0:714293de3836 252 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
ashleymills 0:714293de3836 253
ashleymills 0:714293de3836 254 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
ashleymills 0:714293de3836 255 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
ashleymills 0:714293de3836 256 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
ashleymills 0:714293de3836 257 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
ashleymills 0:714293de3836 258 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
ashleymills 0:714293de3836 259
ashleymills 0:714293de3836 260 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
ashleymills 0:714293de3836 261 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
ashleymills 0:714293de3836 262 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
ashleymills 0:714293de3836 263 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
ashleymills 0:714293de3836 264 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
ashleymills 0:714293de3836 265 #endif
ashleymills 0:714293de3836 266
ashleymills 0:714293de3836 267 /* Add the working vars back into digest state[] */
ashleymills 0:714293de3836 268 sha->digest[0] += a;
ashleymills 0:714293de3836 269 sha->digest[1] += b;
ashleymills 0:714293de3836 270 sha->digest[2] += c;
ashleymills 0:714293de3836 271 sha->digest[3] += d;
ashleymills 0:714293de3836 272 sha->digest[4] += e;
ashleymills 0:714293de3836 273 }
ashleymills 0:714293de3836 274
ashleymills 0:714293de3836 275
ashleymills 0:714293de3836 276 static INLINE void AddLength(Sha* sha, word32 len)
ashleymills 0:714293de3836 277 {
ashleymills 0:714293de3836 278 word32 tmp = sha->loLen;
ashleymills 0:714293de3836 279 if ( (sha->loLen += len) < tmp)
ashleymills 0:714293de3836 280 sha->hiLen++; /* carry low to high */
ashleymills 0:714293de3836 281 }
ashleymills 0:714293de3836 282
ashleymills 0:714293de3836 283
ashleymills 0:714293de3836 284 void ShaUpdate(Sha* sha, const byte* data, word32 len)
ashleymills 0:714293de3836 285 {
ashleymills 0:714293de3836 286 /* do block size increments */
ashleymills 0:714293de3836 287 byte* local = (byte*)sha->buffer;
ashleymills 0:714293de3836 288
ashleymills 0:714293de3836 289 while (len) {
ashleymills 0:714293de3836 290 word32 add = min(len, SHA_BLOCK_SIZE - sha->buffLen);
ashleymills 0:714293de3836 291 XMEMCPY(&local[sha->buffLen], data, add);
ashleymills 0:714293de3836 292
ashleymills 0:714293de3836 293 sha->buffLen += add;
ashleymills 0:714293de3836 294 data += add;
ashleymills 0:714293de3836 295 len -= add;
ashleymills 0:714293de3836 296
ashleymills 0:714293de3836 297 if (sha->buffLen == SHA_BLOCK_SIZE) {
ashleymills 0:714293de3836 298 #ifdef LITTLE_ENDIAN_ORDER
ashleymills 0:714293de3836 299 ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
ashleymills 0:714293de3836 300 #endif
ashleymills 0:714293de3836 301 Transform(sha);
ashleymills 0:714293de3836 302 AddLength(sha, SHA_BLOCK_SIZE);
ashleymills 0:714293de3836 303 sha->buffLen = 0;
ashleymills 0:714293de3836 304 }
ashleymills 0:714293de3836 305 }
ashleymills 0:714293de3836 306 }
ashleymills 0:714293de3836 307
ashleymills 0:714293de3836 308
ashleymills 0:714293de3836 309 void ShaFinal(Sha* sha, byte* hash)
ashleymills 0:714293de3836 310 {
ashleymills 0:714293de3836 311 byte* local = (byte*)sha->buffer;
ashleymills 0:714293de3836 312
ashleymills 0:714293de3836 313 AddLength(sha, sha->buffLen); /* before adding pads */
ashleymills 0:714293de3836 314
ashleymills 0:714293de3836 315 local[sha->buffLen++] = 0x80; /* add 1 */
ashleymills 0:714293de3836 316
ashleymills 0:714293de3836 317 /* pad with zeros */
ashleymills 0:714293de3836 318 if (sha->buffLen > SHA_PAD_SIZE) {
ashleymills 0:714293de3836 319 XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
ashleymills 0:714293de3836 320 sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;
ashleymills 0:714293de3836 321
ashleymills 0:714293de3836 322 #ifdef LITTLE_ENDIAN_ORDER
ashleymills 0:714293de3836 323 ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
ashleymills 0:714293de3836 324 #endif
ashleymills 0:714293de3836 325 Transform(sha);
ashleymills 0:714293de3836 326 sha->buffLen = 0;
ashleymills 0:714293de3836 327 }
ashleymills 0:714293de3836 328 XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
ashleymills 0:714293de3836 329
ashleymills 0:714293de3836 330 /* put lengths in bits */
ashleymills 0:714293de3836 331 sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) +
ashleymills 0:714293de3836 332 (sha->hiLen << 3);
ashleymills 0:714293de3836 333 sha->loLen = sha->loLen << 3;
ashleymills 0:714293de3836 334
ashleymills 0:714293de3836 335 /* store lengths */
ashleymills 0:714293de3836 336 #ifdef LITTLE_ENDIAN_ORDER
ashleymills 0:714293de3836 337 ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
ashleymills 0:714293de3836 338 #endif
ashleymills 0:714293de3836 339 /* ! length ordering dependent on digest endian type ! */
ashleymills 0:714293de3836 340 XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
ashleymills 0:714293de3836 341 XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));
ashleymills 0:714293de3836 342
ashleymills 0:714293de3836 343 Transform(sha);
ashleymills 0:714293de3836 344 #ifdef LITTLE_ENDIAN_ORDER
ashleymills 0:714293de3836 345 ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
ashleymills 0:714293de3836 346 #endif
ashleymills 0:714293de3836 347 XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
ashleymills 0:714293de3836 348
ashleymills 0:714293de3836 349 InitSha(sha); /* reset state */
ashleymills 0:714293de3836 350 }
ashleymills 0:714293de3836 351
ashleymills 0:714293de3836 352 #endif /* STM32F2_HASH */
ashleymills 0:714293de3836 353
ashleymills 0:714293de3836 354 #endif /* NO_SHA */