This library implements some hash and cryptographic algorithms.

Dependents:   ES_CW2_Starter_JIN EMBEDDED_CW2 EMBEDDED_CW2_Final Spinnybois ... more

Fork of Crypto by Francois Berder

Committer:
feb11
Date:
Tue Sep 24 07:19:04 2013 +0000
Revision:
10:bc9c23aa3870
Parent:
7:2dbbdfb08123
Child:
13:ac8e23b98dae
implemented HMAC

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