cya_u
Fork of CyaSSL-forEncrypt by
sha.c@2:d0516dc143b1, 2017-05-10 (annotated)
- Committer:
- vbahl2
- Date:
- Wed May 10 18:20:47 2017 +0000
- Revision:
- 2:d0516dc143b1
- Parent:
- 0:5045d2638c29
updated
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
toddouska | 0:5045d2638c29 | 1 | /* sha.c |
toddouska | 0:5045d2638c29 | 2 | * |
toddouska | 0:5045d2638c29 | 3 | * Copyright (C) 2006-2009 Sawtooth Consulting Ltd. |
toddouska | 0:5045d2638c29 | 4 | * |
toddouska | 0:5045d2638c29 | 5 | * This file is part of CyaSSL. |
toddouska | 0:5045d2638c29 | 6 | * |
toddouska | 0:5045d2638c29 | 7 | * CyaSSL is free software; you can redistribute it and/or modify |
toddouska | 0:5045d2638c29 | 8 | * it under the terms of the GNU General Public License as published by |
toddouska | 0:5045d2638c29 | 9 | * the Free Software Foundation; either version 2 of the License, or |
toddouska | 0:5045d2638c29 | 10 | * (at your option) any later version. |
toddouska | 0:5045d2638c29 | 11 | * |
toddouska | 0:5045d2638c29 | 12 | * CyaSSL is distributed in the hope that it will be useful, |
toddouska | 0:5045d2638c29 | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
toddouska | 0:5045d2638c29 | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
toddouska | 0:5045d2638c29 | 15 | * GNU General Public License for more details. |
toddouska | 0:5045d2638c29 | 16 | * |
toddouska | 0:5045d2638c29 | 17 | * You should have received a copy of the GNU General Public License |
toddouska | 0:5045d2638c29 | 18 | * along with this program; if not, write to the Free Software |
toddouska | 0:5045d2638c29 | 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
toddouska | 0:5045d2638c29 | 20 | */ |
toddouska | 0:5045d2638c29 | 21 | |
toddouska | 0:5045d2638c29 | 22 | |
toddouska | 0:5045d2638c29 | 23 | #include "ctc_sha.h" |
toddouska | 0:5045d2638c29 | 24 | #ifdef NO_INLINE |
toddouska | 0:5045d2638c29 | 25 | #include "misc.h" |
toddouska | 0:5045d2638c29 | 26 | #else |
toddouska | 0:5045d2638c29 | 27 | #include "misc.c" |
toddouska | 0:5045d2638c29 | 28 | #endif |
toddouska | 0:5045d2638c29 | 29 | |
toddouska | 0:5045d2638c29 | 30 | |
toddouska | 0:5045d2638c29 | 31 | #ifndef min |
toddouska | 0:5045d2638c29 | 32 | |
toddouska | 0:5045d2638c29 | 33 | static INLINE word32 min(word32 a, word32 b) |
toddouska | 0:5045d2638c29 | 34 | { |
toddouska | 0:5045d2638c29 | 35 | return a > b ? b : a; |
toddouska | 0:5045d2638c29 | 36 | } |
toddouska | 0:5045d2638c29 | 37 | |
toddouska | 0:5045d2638c29 | 38 | #endif /* min */ |
toddouska | 0:5045d2638c29 | 39 | |
toddouska | 0:5045d2638c29 | 40 | |
toddouska | 0:5045d2638c29 | 41 | void InitSha(Sha* sha) |
toddouska | 0:5045d2638c29 | 42 | { |
toddouska | 0:5045d2638c29 | 43 | sha->digest[0] = 0x67452301L; |
toddouska | 0:5045d2638c29 | 44 | sha->digest[1] = 0xEFCDAB89L; |
toddouska | 0:5045d2638c29 | 45 | sha->digest[2] = 0x98BADCFEL; |
toddouska | 0:5045d2638c29 | 46 | sha->digest[3] = 0x10325476L; |
toddouska | 0:5045d2638c29 | 47 | sha->digest[4] = 0xC3D2E1F0L; |
toddouska | 0:5045d2638c29 | 48 | |
toddouska | 0:5045d2638c29 | 49 | sha->buffLen = 0; |
toddouska | 0:5045d2638c29 | 50 | sha->loLen = 0; |
toddouska | 0:5045d2638c29 | 51 | sha->hiLen = 0; |
toddouska | 0:5045d2638c29 | 52 | } |
toddouska | 0:5045d2638c29 | 53 | |
toddouska | 0:5045d2638c29 | 54 | #define blk0(i) (W[i] = sha->buffer[i]) |
toddouska | 0:5045d2638c29 | 55 | #define blk1(i) (W[i&15] = \ |
toddouska | 0:5045d2638c29 | 56 | rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) |
toddouska | 0:5045d2638c29 | 57 | |
toddouska | 0:5045d2638c29 | 58 | #define f1(x,y,z) (z^(x &(y^z))) |
toddouska | 0:5045d2638c29 | 59 | #define f2(x,y,z) (x^y^z) |
toddouska | 0:5045d2638c29 | 60 | #define f3(x,y,z) ((x&y)|(z&(x|y))) |
toddouska | 0:5045d2638c29 | 61 | #define f4(x,y,z) (x^y^z) |
toddouska | 0:5045d2638c29 | 62 | |
toddouska | 0:5045d2638c29 | 63 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ |
toddouska | 0:5045d2638c29 | 64 | #define R0(v,w,x,y,z,i) z+= f1(w,x,y) + blk0(i) + 0x5A827999+ \ |
toddouska | 0:5045d2638c29 | 65 | rotlFixed(v,5); w = rotlFixed(w,30); |
toddouska | 0:5045d2638c29 | 66 | #define R1(v,w,x,y,z,i) z+= f1(w,x,y) + blk1(i) + 0x5A827999+ \ |
toddouska | 0:5045d2638c29 | 67 | rotlFixed(v,5); w = rotlFixed(w,30); |
toddouska | 0:5045d2638c29 | 68 | #define R2(v,w,x,y,z,i) z+= f2(w,x,y) + blk1(i) + 0x6ED9EBA1+ \ |
toddouska | 0:5045d2638c29 | 69 | rotlFixed(v,5); w = rotlFixed(w,30); |
toddouska | 0:5045d2638c29 | 70 | #define R3(v,w,x,y,z,i) z+= f3(w,x,y) + blk1(i) + 0x8F1BBCDC+ \ |
toddouska | 0:5045d2638c29 | 71 | rotlFixed(v,5); w = rotlFixed(w,30); |
toddouska | 0:5045d2638c29 | 72 | #define R4(v,w,x,y,z,i) z+= f4(w,x,y) + blk1(i) + 0xCA62C1D6+ \ |
toddouska | 0:5045d2638c29 | 73 | rotlFixed(v,5); w = rotlFixed(w,30); |
toddouska | 0:5045d2638c29 | 74 | |
toddouska | 0:5045d2638c29 | 75 | |
toddouska | 0:5045d2638c29 | 76 | static void Transform(Sha* sha) |
toddouska | 0:5045d2638c29 | 77 | { |
toddouska | 0:5045d2638c29 | 78 | word32 W[SHA_BLOCK_SIZE / sizeof(word32)]; |
toddouska | 0:5045d2638c29 | 79 | |
toddouska | 0:5045d2638c29 | 80 | /* Copy context->state[] to working vars */ |
toddouska | 0:5045d2638c29 | 81 | word32 a = sha->digest[0]; |
toddouska | 0:5045d2638c29 | 82 | word32 b = sha->digest[1]; |
toddouska | 0:5045d2638c29 | 83 | word32 c = sha->digest[2]; |
toddouska | 0:5045d2638c29 | 84 | word32 d = sha->digest[3]; |
toddouska | 0:5045d2638c29 | 85 | word32 e = sha->digest[4]; |
toddouska | 0:5045d2638c29 | 86 | |
toddouska | 0:5045d2638c29 | 87 | /* nearly 1 K bigger in code size but 25% faster */ |
toddouska | 0:5045d2638c29 | 88 | /* 4 rounds of 20 operations each. Loop unrolled. */ |
toddouska | 0:5045d2638c29 | 89 | 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); |
toddouska | 0:5045d2638c29 | 90 | 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); |
toddouska | 0:5045d2638c29 | 91 | 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); |
toddouska | 0:5045d2638c29 | 92 | 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); |
toddouska | 0:5045d2638c29 | 93 | |
toddouska | 0:5045d2638c29 | 94 | 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); |
toddouska | 0:5045d2638c29 | 95 | |
toddouska | 0:5045d2638c29 | 96 | 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); |
toddouska | 0:5045d2638c29 | 97 | 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); |
toddouska | 0:5045d2638c29 | 98 | 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); |
toddouska | 0:5045d2638c29 | 99 | 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); |
toddouska | 0:5045d2638c29 | 100 | 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); |
toddouska | 0:5045d2638c29 | 101 | |
toddouska | 0:5045d2638c29 | 102 | 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); |
toddouska | 0:5045d2638c29 | 103 | 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); |
toddouska | 0:5045d2638c29 | 104 | 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); |
toddouska | 0:5045d2638c29 | 105 | 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); |
toddouska | 0:5045d2638c29 | 106 | 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); |
toddouska | 0:5045d2638c29 | 107 | |
toddouska | 0:5045d2638c29 | 108 | 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); |
toddouska | 0:5045d2638c29 | 109 | 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); |
toddouska | 0:5045d2638c29 | 110 | 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); |
toddouska | 0:5045d2638c29 | 111 | 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); |
toddouska | 0:5045d2638c29 | 112 | 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); |
toddouska | 0:5045d2638c29 | 113 | |
toddouska | 0:5045d2638c29 | 114 | /* Add the working vars back into digest state[] */ |
toddouska | 0:5045d2638c29 | 115 | sha->digest[0] += a; |
toddouska | 0:5045d2638c29 | 116 | sha->digest[1] += b; |
toddouska | 0:5045d2638c29 | 117 | sha->digest[2] += c; |
toddouska | 0:5045d2638c29 | 118 | sha->digest[3] += d; |
toddouska | 0:5045d2638c29 | 119 | sha->digest[4] += e; |
toddouska | 0:5045d2638c29 | 120 | } |
toddouska | 0:5045d2638c29 | 121 | |
toddouska | 0:5045d2638c29 | 122 | |
toddouska | 0:5045d2638c29 | 123 | static INLINE void AddLength(Sha* sha, word32 len) |
toddouska | 0:5045d2638c29 | 124 | { |
toddouska | 0:5045d2638c29 | 125 | word32 tmp = sha->loLen; |
toddouska | 0:5045d2638c29 | 126 | if ( (sha->loLen += len) < tmp) |
toddouska | 0:5045d2638c29 | 127 | sha->hiLen++; /* carry low to high */ |
toddouska | 0:5045d2638c29 | 128 | } |
toddouska | 0:5045d2638c29 | 129 | |
toddouska | 0:5045d2638c29 | 130 | |
toddouska | 0:5045d2638c29 | 131 | void ShaUpdate(Sha* sha, const byte* data, word32 len) |
toddouska | 0:5045d2638c29 | 132 | { |
toddouska | 0:5045d2638c29 | 133 | /* do block size increments */ |
toddouska | 0:5045d2638c29 | 134 | byte* local = (byte*)sha->buffer; |
toddouska | 0:5045d2638c29 | 135 | |
toddouska | 0:5045d2638c29 | 136 | while (len) { |
toddouska | 0:5045d2638c29 | 137 | word32 add = min(len, SHA_BLOCK_SIZE - sha->buffLen); |
toddouska | 0:5045d2638c29 | 138 | XMEMCPY(&local[sha->buffLen], data, add); |
toddouska | 0:5045d2638c29 | 139 | |
toddouska | 0:5045d2638c29 | 140 | sha->buffLen += add; |
toddouska | 0:5045d2638c29 | 141 | data += add; |
toddouska | 0:5045d2638c29 | 142 | len -= add; |
toddouska | 0:5045d2638c29 | 143 | |
toddouska | 0:5045d2638c29 | 144 | if (sha->buffLen == SHA_BLOCK_SIZE) { |
toddouska | 0:5045d2638c29 | 145 | #ifdef LITTLE_ENDIAN_ORDER |
toddouska | 0:5045d2638c29 | 146 | ByteReverseBytes(local, local, SHA_BLOCK_SIZE); |
toddouska | 0:5045d2638c29 | 147 | #endif |
toddouska | 0:5045d2638c29 | 148 | Transform(sha); |
toddouska | 0:5045d2638c29 | 149 | AddLength(sha, SHA_BLOCK_SIZE); |
toddouska | 0:5045d2638c29 | 150 | sha->buffLen = 0; |
toddouska | 0:5045d2638c29 | 151 | } |
toddouska | 0:5045d2638c29 | 152 | } |
toddouska | 0:5045d2638c29 | 153 | } |
toddouska | 0:5045d2638c29 | 154 | |
toddouska | 0:5045d2638c29 | 155 | |
toddouska | 0:5045d2638c29 | 156 | void ShaFinal(Sha* sha, byte* hash) |
toddouska | 0:5045d2638c29 | 157 | { |
toddouska | 0:5045d2638c29 | 158 | byte* local = (byte*)sha->buffer; |
toddouska | 0:5045d2638c29 | 159 | |
toddouska | 0:5045d2638c29 | 160 | AddLength(sha, sha->buffLen); /* before adding pads */ |
toddouska | 0:5045d2638c29 | 161 | |
toddouska | 0:5045d2638c29 | 162 | local[sha->buffLen++] = 0x80; /* add 1 */ |
toddouska | 0:5045d2638c29 | 163 | |
toddouska | 0:5045d2638c29 | 164 | /* pad with zeros */ |
toddouska | 0:5045d2638c29 | 165 | if (sha->buffLen > SHA_PAD_SIZE) { |
toddouska | 0:5045d2638c29 | 166 | XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen); |
toddouska | 0:5045d2638c29 | 167 | sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen; |
toddouska | 0:5045d2638c29 | 168 | |
toddouska | 0:5045d2638c29 | 169 | #ifdef LITTLE_ENDIAN_ORDER |
toddouska | 0:5045d2638c29 | 170 | ByteReverseBytes(local, local, SHA_BLOCK_SIZE); |
toddouska | 0:5045d2638c29 | 171 | #endif |
toddouska | 0:5045d2638c29 | 172 | Transform(sha); |
toddouska | 0:5045d2638c29 | 173 | sha->buffLen = 0; |
toddouska | 0:5045d2638c29 | 174 | } |
toddouska | 0:5045d2638c29 | 175 | XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen); |
toddouska | 0:5045d2638c29 | 176 | |
toddouska | 0:5045d2638c29 | 177 | /* put lengths in bits */ |
toddouska | 0:5045d2638c29 | 178 | sha->loLen = sha->loLen << 3; |
toddouska | 0:5045d2638c29 | 179 | sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + |
toddouska | 0:5045d2638c29 | 180 | (sha->hiLen << 3); |
toddouska | 0:5045d2638c29 | 181 | |
toddouska | 0:5045d2638c29 | 182 | /* store lengths */ |
toddouska | 0:5045d2638c29 | 183 | #ifdef LITTLE_ENDIAN_ORDER |
toddouska | 0:5045d2638c29 | 184 | ByteReverseBytes(local, local, SHA_BLOCK_SIZE); |
toddouska | 0:5045d2638c29 | 185 | #endif |
toddouska | 0:5045d2638c29 | 186 | /* ! length ordering dependent on digest endian type ! */ |
toddouska | 0:5045d2638c29 | 187 | XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32)); |
toddouska | 0:5045d2638c29 | 188 | XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32)); |
toddouska | 0:5045d2638c29 | 189 | |
toddouska | 0:5045d2638c29 | 190 | Transform(sha); |
toddouska | 0:5045d2638c29 | 191 | #ifdef LITTLE_ENDIAN_ORDER |
toddouska | 0:5045d2638c29 | 192 | ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE); |
toddouska | 0:5045d2638c29 | 193 | #endif |
toddouska | 0:5045d2638c29 | 194 | XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE); |
toddouska | 0:5045d2638c29 | 195 | |
toddouska | 0:5045d2638c29 | 196 | InitSha(sha); /* reset state */ |
toddouska | 0:5045d2638c29 | 197 | } |
toddouska | 0:5045d2638c29 | 198 |