Fork of François Berder Crypto, fixed AES CBC and small rework

Dependents:   AES_example shaun_larada Smartage

Fork of Crypto by Francois Berder

Committer:
feb11
Date:
Thu Sep 12 10:18:57 2013 +0000
Revision:
4:0da19393bd57
Parent:
3:85c6ee25cf3e
Child:
5:06cd9c8afa0b
improved performance of SHA-2 (32 & 64bits)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 4:0da19393bd57 1 /**
feb11 4:0da19393bd57 2 Implementation of SHA-1 as described here:
feb11 4:0da19393bd57 3 http://tools.ietf.org/html/rfc1319
feb11 4:0da19393bd57 4 */
feb11 4:0da19393bd57 5
feb11 0:7a1237bd2d13 6 #include "SHA1.h"
feb11 0:7a1237bd2d13 7 #include <string.h>
feb11 3:85c6ee25cf3e 8 #include <stdio.h>
feb11 3:85c6ee25cf3e 9 #include <stdlib.h>
feb11 0:7a1237bd2d13 10
feb11 3:85c6ee25cf3e 11 #define F0(B,C,D) ((B & C) | ((~B) & D))
feb11 3:85c6ee25cf3e 12 #define F1(B,C,D) (B ^ C ^ D)
feb11 3:85c6ee25cf3e 13 #define F2(B,C,D) ((B & C) | (B & D) | (C & D))
feb11 3:85c6ee25cf3e 14 #define ROTL(W,N) (((W) << N) | ((W) >> (32-N)))
feb11 3:85c6ee25cf3e 15
feb11 3:85c6ee25cf3e 16 static const uint32_t K0 = 0x5A827999;
feb11 3:85c6ee25cf3e 17 static const uint32_t K1 = 0x6ED9EBA1;
feb11 3:85c6ee25cf3e 18 static const uint32_t K2 = 0x8F1BBCDC;
feb11 3:85c6ee25cf3e 19 static const uint32_t K3 = 0xCA62C1D6;
feb11 0:7a1237bd2d13 20
feb11 0:7a1237bd2d13 21
feb11 0:7a1237bd2d13 22 static const uint32_t H0 = 0x67452301;
feb11 0:7a1237bd2d13 23 static const uint32_t H1 = 0xEFCDAB89;
feb11 0:7a1237bd2d13 24 static const uint32_t H2 = 0x98BADCFE;
feb11 0:7a1237bd2d13 25 static const uint32_t H3 = 0x10325476;
feb11 0:7a1237bd2d13 26 static const uint32_t H4 = 0xC3D2E1F0;
feb11 3:85c6ee25cf3e 27
feb11 3:85c6ee25cf3e 28 static const uint32_t MASK = 0xF;
feb11 3:85c6ee25cf3e 29
feb11 3:85c6ee25cf3e 30 #define W(s) ( w[s] = ROTL(w[((s) + 13) & MASK] ^ w[((s) + 8) & MASK] ^ w[((s) + 2) & MASK] ^ w[s],1))
feb11 0:7a1237bd2d13 31
feb11 3:85c6ee25cf3e 32 #define R0(A,B,C,D,E,T) E += ROTL(A, 5) + F0(B, C, D) + w[T] + K0; \
feb11 3:85c6ee25cf3e 33 B = ROTL(B,30);
feb11 3:85c6ee25cf3e 34 #define R1(A,B,C,D,E,T) E += ROTL(A, 5) + F0(B, C, D) + W(T & MASK) + K0; \
feb11 3:85c6ee25cf3e 35 B = ROTL(B,30);
feb11 3:85c6ee25cf3e 36 #define R2(A,B,C,D,E,T) E += ROTL(A, 5) + F1(B, C, D) + W(T & MASK) + K1; \
feb11 3:85c6ee25cf3e 37 B = ROTL(B,30);
feb11 3:85c6ee25cf3e 38 #define R3(A,B,C,D,E,T) E += ROTL(A, 5) + F2(B, C, D) + W(T & MASK) + K2; \
feb11 3:85c6ee25cf3e 39 B = ROTL(B,30);
feb11 3:85c6ee25cf3e 40 #define R4(A,B,C,D,E,T) E += ROTL(A, 5) + F1(B, C, D) + W(T & MASK) + K3; \
feb11 3:85c6ee25cf3e 41 B = ROTL(B,30);
feb11 0:7a1237bd2d13 42
feb11 3:85c6ee25cf3e 43
feb11 0:7a1237bd2d13 44 SHA1::SHA1():
feb11 0:7a1237bd2d13 45 HashAlgorithm(),
feb11 0:7a1237bd2d13 46 h0(H0),
feb11 0:7a1237bd2d13 47 h1(H1),
feb11 0:7a1237bd2d13 48 h2(H2),
feb11 0:7a1237bd2d13 49 h3(H3),
feb11 0:7a1237bd2d13 50 h4(H4),
feb11 0:7a1237bd2d13 51 totalBufferLength(0),
feb11 0:7a1237bd2d13 52 buffer(),
feb11 0:7a1237bd2d13 53 bufferLength(0)
feb11 0:7a1237bd2d13 54 {
feb11 0:7a1237bd2d13 55 }
feb11 0:7a1237bd2d13 56
feb11 0:7a1237bd2d13 57 uint8_t SHA1::outputSize() const
feb11 0:7a1237bd2d13 58 {
feb11 0:7a1237bd2d13 59 return 20;
feb11 0:7a1237bd2d13 60 }
feb11 0:7a1237bd2d13 61
feb11 0:7a1237bd2d13 62 void SHA1::add(uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 63 {
feb11 0:7a1237bd2d13 64 if(length < 64-bufferLength)
feb11 0:7a1237bd2d13 65 {
feb11 0:7a1237bd2d13 66 memcpy(&buffer[bufferLength], in, length);
feb11 0:7a1237bd2d13 67 bufferLength += length;
feb11 0:7a1237bd2d13 68 totalBufferLength += length;
feb11 0:7a1237bd2d13 69 return;
feb11 0:7a1237bd2d13 70 }
feb11 0:7a1237bd2d13 71 int offset = 64-bufferLength;
feb11 0:7a1237bd2d13 72 memcpy(&buffer[bufferLength], in, offset);
feb11 0:7a1237bd2d13 73 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer);
feb11 0:7a1237bd2d13 74 while(length-offset > 64)
feb11 0:7a1237bd2d13 75 {
feb11 0:7a1237bd2d13 76 memcpy(buffer, &in[offset], 64);
feb11 0:7a1237bd2d13 77 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer);
feb11 0:7a1237bd2d13 78 offset += 64;
feb11 0:7a1237bd2d13 79 }
feb11 0:7a1237bd2d13 80 if(offset > length)
feb11 0:7a1237bd2d13 81 offset -= 64;
feb11 0:7a1237bd2d13 82 bufferLength = length - offset;
feb11 0:7a1237bd2d13 83 memcpy(buffer, &in[offset], bufferLength);
feb11 0:7a1237bd2d13 84 totalBufferLength += length;
feb11 0:7a1237bd2d13 85 }
feb11 0:7a1237bd2d13 86
feb11 0:7a1237bd2d13 87 void SHA1::computeDigest(uint8_t *digest)
feb11 0:7a1237bd2d13 88 {
feb11 3:85c6ee25cf3e 89 uint32_t *digest2 = (uint32_t*)digest;
feb11 0:7a1237bd2d13 90 uint16_t padding;
feb11 0:7a1237bd2d13 91 if(totalBufferLength % 64 < 56)
feb11 0:7a1237bd2d13 92 padding = 56 - (totalBufferLength % 64);
feb11 0:7a1237bd2d13 93 else
feb11 0:7a1237bd2d13 94 padding = 56 + (64 - (totalBufferLength % 64));
feb11 3:85c6ee25cf3e 95
feb11 3:85c6ee25cf3e 96 buffer[bufferLength++] = 0x80;
feb11 3:85c6ee25cf3e 97 padding--;
feb11 3:85c6ee25cf3e 98 if(padding+bufferLength == 56)
feb11 3:85c6ee25cf3e 99 memset(&buffer[bufferLength], 0, padding);
feb11 3:85c6ee25cf3e 100 else
feb11 3:85c6ee25cf3e 101 {
feb11 3:85c6ee25cf3e 102 memset(&buffer[bufferLength], 0, 64-bufferLength);
feb11 3:85c6ee25cf3e 103 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer);
feb11 3:85c6ee25cf3e 104 memset(buffer, 0, 48);
feb11 3:85c6ee25cf3e 105 }
feb11 3:85c6ee25cf3e 106
feb11 3:85c6ee25cf3e 107 uint64_t lengthBit = totalBufferLength << 3;
feb11 0:7a1237bd2d13 108 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 109 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 3:85c6ee25cf3e 110 lengthBitLow = __rev(lengthBitLow);
feb11 3:85c6ee25cf3e 111 lengthBitHigh = __rev(lengthBitHigh);
feb11 3:85c6ee25cf3e 112 memcpy(&buffer[56], &lengthBitHigh, 4);
feb11 3:85c6ee25cf3e 113 memcpy(&buffer[60], &lengthBitLow, 4);
feb11 3:85c6ee25cf3e 114 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer);
feb11 3:85c6ee25cf3e 115
feb11 3:85c6ee25cf3e 116 digest2[0] = __rev(h0);
feb11 3:85c6ee25cf3e 117 digest2[1] = __rev(h1);
feb11 3:85c6ee25cf3e 118 digest2[2] = __rev(h2);
feb11 3:85c6ee25cf3e 119 digest2[3] = __rev(h3);
feb11 3:85c6ee25cf3e 120 digest2[4] = __rev(h4);
feb11 0:7a1237bd2d13 121
feb11 0:7a1237bd2d13 122 // reset state
feb11 0:7a1237bd2d13 123 h0 = H0;
feb11 0:7a1237bd2d13 124 h1 = H1;
feb11 0:7a1237bd2d13 125 h2 = H2;
feb11 0:7a1237bd2d13 126 h3 = H3;
feb11 0:7a1237bd2d13 127 h4 = H4;
feb11 0:7a1237bd2d13 128 totalBufferLength = 0;
feb11 0:7a1237bd2d13 129 bufferLength = 0;
feb11 0:7a1237bd2d13 130 }
feb11 0:7a1237bd2d13 131
feb11 0:7a1237bd2d13 132 void SHA1::computeBlock(uint32_t *h02, uint32_t *h12, uint32_t *h22, uint32_t *h32, uint32_t *h42, uint8_t *buffer)
feb11 0:7a1237bd2d13 133 {
feb11 3:85c6ee25cf3e 134 uint32_t *buffer2 = (uint32_t*)buffer;
feb11 0:7a1237bd2d13 135 uint32_t w[16];
feb11 3:85c6ee25cf3e 136 for(int t = 0; t < 16; ++t)
feb11 3:85c6ee25cf3e 137 w[t] = __rev(buffer2[t]);
feb11 0:7a1237bd2d13 138
feb11 0:7a1237bd2d13 139 uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42;
feb11 3:85c6ee25cf3e 140
feb11 3:85c6ee25cf3e 141 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)
feb11 3:85c6ee25cf3e 142 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)
feb11 3:85c6ee25cf3e 143 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)
feb11 3:85c6ee25cf3e 144 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)
feb11 3:85c6ee25cf3e 145 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)
feb11 3:85c6ee25cf3e 146
feb11 3:85c6ee25cf3e 147
feb11 3:85c6ee25cf3e 148 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)
feb11 3:85c6ee25cf3e 149 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)
feb11 3:85c6ee25cf3e 150 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)
feb11 3:85c6ee25cf3e 151 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)
feb11 3:85c6ee25cf3e 152 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)
feb11 3:85c6ee25cf3e 153
feb11 3:85c6ee25cf3e 154 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)
feb11 3:85c6ee25cf3e 155 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)
feb11 3:85c6ee25cf3e 156 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)
feb11 3:85c6ee25cf3e 157 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)
feb11 3:85c6ee25cf3e 158 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)
feb11 3:85c6ee25cf3e 159
feb11 3:85c6ee25cf3e 160
feb11 3:85c6ee25cf3e 161 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)
feb11 3:85c6ee25cf3e 162 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)
feb11 3:85c6ee25cf3e 163 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)
feb11 3:85c6ee25cf3e 164 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)
feb11 3:85c6ee25cf3e 165 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)
feb11 0:7a1237bd2d13 166
feb11 0:7a1237bd2d13 167 *h02 += a;
feb11 0:7a1237bd2d13 168 *h12 += b;
feb11 0:7a1237bd2d13 169 *h22 += c;
feb11 0:7a1237bd2d13 170 *h32 += d;
feb11 0:7a1237bd2d13 171 *h42 += e;
feb11 0:7a1237bd2d13 172 }
feb11 0:7a1237bd2d13 173
feb11 0:7a1237bd2d13 174
feb11 0:7a1237bd2d13 175
feb11 3:85c6ee25cf3e 176 /* method 1 */
feb11 0:7a1237bd2d13 177 void SHA1::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 178 {
feb11 3:85c6ee25cf3e 179 uint64_t lengthBit = length << 3;
feb11 3:85c6ee25cf3e 180 uint32_t padding;
feb11 0:7a1237bd2d13 181 if(length % 64 < 56)
feb11 0:7a1237bd2d13 182 padding = 56 - (length % 64);
feb11 0:7a1237bd2d13 183 else
feb11 0:7a1237bd2d13 184 padding = 56 + (64 - (length % 64));
feb11 1:14a7cea431aa 185
feb11 1:14a7cea431aa 186 uint32_t h0 = H0, h1 = H1, h2 = H2, h3 = H3, h4 = H4;
feb11 3:85c6ee25cf3e 187 while(length >= 64)
feb11 1:14a7cea431aa 188 {
feb11 3:85c6ee25cf3e 189 computeBlock(&h0,&h1,&h2,&h3,&h4, in);
feb11 3:85c6ee25cf3e 190 length -= 64;
feb11 3:85c6ee25cf3e 191 in += 64;
feb11 3:85c6ee25cf3e 192 }
feb11 3:85c6ee25cf3e 193
feb11 3:85c6ee25cf3e 194 uint8_t buffer[64];
feb11 3:85c6ee25cf3e 195 memcpy(buffer, in, length);
feb11 3:85c6ee25cf3e 196 buffer[length++] = 0x80;
feb11 3:85c6ee25cf3e 197 padding--;
feb11 3:85c6ee25cf3e 198 if(padding+length+8 == 64)
feb11 3:85c6ee25cf3e 199 memset(&buffer[length], 0, padding);
feb11 3:85c6ee25cf3e 200 else
feb11 3:85c6ee25cf3e 201 {
feb11 3:85c6ee25cf3e 202 memset(&buffer[length], 0, 64-length);
feb11 3:85c6ee25cf3e 203 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer);
feb11 3:85c6ee25cf3e 204 memset(buffer, 0, length);
feb11 1:14a7cea431aa 205 }
feb11 1:14a7cea431aa 206
feb11 0:7a1237bd2d13 207 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 208 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 2:473bac39ae7c 209 lengthBitLow = __rev(lengthBitLow);
feb11 2:473bac39ae7c 210 lengthBitHigh = __rev(lengthBitHigh);
feb11 2:473bac39ae7c 211 memcpy(&buffer[60], &lengthBitLow, 4);
feb11 2:473bac39ae7c 212 memcpy(&buffer[56], &lengthBitHigh, 4);
feb11 0:7a1237bd2d13 213
feb11 1:14a7cea431aa 214 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer);
feb11 0:7a1237bd2d13 215
feb11 2:473bac39ae7c 216 h0 = __rev(h0);
feb11 2:473bac39ae7c 217 h1 = __rev(h1);
feb11 2:473bac39ae7c 218 h2 = __rev(h2);
feb11 2:473bac39ae7c 219 h3 = __rev(h3);
feb11 2:473bac39ae7c 220 h4 = __rev(h4);
feb11 2:473bac39ae7c 221
feb11 2:473bac39ae7c 222 memcpy(digest, &h0, 4);
feb11 2:473bac39ae7c 223 memcpy(&digest[4], &h1, 4);
feb11 2:473bac39ae7c 224 memcpy(&digest[8], &h2, 4);
feb11 2:473bac39ae7c 225 memcpy(&digest[12], &h3, 4);
feb11 2:473bac39ae7c 226 memcpy(&digest[16], &h4, 4);
feb11 0:7a1237bd2d13 227 }
feb11 0:7a1237bd2d13 228