Embedded systems coursework 2.

Fork of Crypto_light by Edward Stott

Committer:
feb11
Date:
Mon Sep 09 12:15:26 2013 +0000
Revision:
1:14a7cea431aa
Parent:
0:7a1237bd2d13
Child:
3:85c6ee25cf3e
remove dynamic memory allocation in MD2, MD5 and SHA-1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 0:7a1237bd2d13 1 #include "MD5.h"
feb11 0:7a1237bd2d13 2 #include <string.h>
feb11 0:7a1237bd2d13 3
feb11 0:7a1237bd2d13 4 static const uint32_t T[] =
feb11 0:7a1237bd2d13 5 {
feb11 0:7a1237bd2d13 6 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
feb11 0:7a1237bd2d13 7 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
feb11 0:7a1237bd2d13 8 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
feb11 0:7a1237bd2d13 9 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
feb11 0:7a1237bd2d13 10 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
feb11 0:7a1237bd2d13 11 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
feb11 0:7a1237bd2d13 12 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
feb11 0:7a1237bd2d13 13 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
feb11 0:7a1237bd2d13 14 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
feb11 0:7a1237bd2d13 15 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
feb11 0:7a1237bd2d13 16 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
feb11 0:7a1237bd2d13 17 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
feb11 0:7a1237bd2d13 18 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
feb11 0:7a1237bd2d13 19 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
feb11 0:7a1237bd2d13 20 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
feb11 0:7a1237bd2d13 21 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
feb11 0:7a1237bd2d13 22 };
feb11 0:7a1237bd2d13 23
feb11 0:7a1237bd2d13 24 static const uint32_t A = 0x67452301;
feb11 0:7a1237bd2d13 25 static const uint32_t B = 0xefcdab89;
feb11 0:7a1237bd2d13 26 static const uint32_t C = 0x98badcfe;
feb11 0:7a1237bd2d13 27 static const uint32_t D = 0x10325476;
feb11 0:7a1237bd2d13 28
feb11 0:7a1237bd2d13 29 static uint32_t F(uint32_t x, uint32_t y, uint32_t z)
feb11 0:7a1237bd2d13 30 {
feb11 0:7a1237bd2d13 31 return (x & y) | ((~x) & z);
feb11 0:7a1237bd2d13 32 }
feb11 0:7a1237bd2d13 33
feb11 0:7a1237bd2d13 34 static uint32_t G(uint32_t x, uint32_t y, uint32_t z)
feb11 0:7a1237bd2d13 35 {
feb11 0:7a1237bd2d13 36 return (x & z) | (y & (~z));
feb11 0:7a1237bd2d13 37 }
feb11 0:7a1237bd2d13 38
feb11 0:7a1237bd2d13 39 static uint32_t H(uint32_t x, uint32_t y, uint32_t z)
feb11 0:7a1237bd2d13 40 {
feb11 0:7a1237bd2d13 41 return x ^ y ^ z;
feb11 0:7a1237bd2d13 42 }
feb11 0:7a1237bd2d13 43
feb11 0:7a1237bd2d13 44 static uint32_t I(uint32_t x, uint32_t y, uint32_t z)
feb11 0:7a1237bd2d13 45 {
feb11 0:7a1237bd2d13 46 return y ^ (x | (~z));
feb11 0:7a1237bd2d13 47 }
feb11 0:7a1237bd2d13 48
feb11 0:7a1237bd2d13 49 static uint32_t rotLeft(uint32_t w, uint8_t s)
feb11 0:7a1237bd2d13 50 {
feb11 0:7a1237bd2d13 51 return (w << s) | (w >> (32-s));
feb11 0:7a1237bd2d13 52 }
feb11 0:7a1237bd2d13 53
feb11 0:7a1237bd2d13 54 #define ROUND1(a,b,c,d,k,s,i) \
feb11 0:7a1237bd2d13 55 a += F(b,c,d) + x[k] + T[i-1]; \
feb11 0:7a1237bd2d13 56 a = rotLeft(a,s);\
feb11 0:7a1237bd2d13 57 a += b;
feb11 0:7a1237bd2d13 58 #define ROUND2(a,b,c,d,k,s,i) \
feb11 0:7a1237bd2d13 59 a += G(b,c,d) + x[k] + T[i-1]; \
feb11 0:7a1237bd2d13 60 a = rotLeft(a,s);\
feb11 0:7a1237bd2d13 61 a += b;
feb11 0:7a1237bd2d13 62 #define ROUND3(a,b,c,d,k,s,i) \
feb11 0:7a1237bd2d13 63 a += H(b,c,d) + x[k] + T[i-1]; \
feb11 0:7a1237bd2d13 64 a = rotLeft(a,s);\
feb11 0:7a1237bd2d13 65 a += b;
feb11 0:7a1237bd2d13 66 #define ROUND4(a,b,c,d,k,s,i) \
feb11 0:7a1237bd2d13 67 a += I(b,c,d) + x[k] + T[i-1]; \
feb11 0:7a1237bd2d13 68 a = rotLeft(a,s);\
feb11 0:7a1237bd2d13 69 a += b;
feb11 0:7a1237bd2d13 70
feb11 0:7a1237bd2d13 71
feb11 0:7a1237bd2d13 72 MD5::MD5():
feb11 0:7a1237bd2d13 73 HashAlgorithm(),
feb11 0:7a1237bd2d13 74 a(A),
feb11 0:7a1237bd2d13 75 b(B),
feb11 0:7a1237bd2d13 76 c(C),
feb11 0:7a1237bd2d13 77 d(D),
feb11 0:7a1237bd2d13 78 totalBufferLength(0),
feb11 0:7a1237bd2d13 79 buffer(),
feb11 0:7a1237bd2d13 80 bufferLength(0)
feb11 0:7a1237bd2d13 81 {
feb11 0:7a1237bd2d13 82 }
feb11 0:7a1237bd2d13 83
feb11 0:7a1237bd2d13 84 uint8_t MD5::outputSize() const
feb11 0:7a1237bd2d13 85 {
feb11 0:7a1237bd2d13 86 return 16;
feb11 0:7a1237bd2d13 87 }
feb11 0:7a1237bd2d13 88
feb11 0:7a1237bd2d13 89 void MD5::add(uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 90 {
feb11 0:7a1237bd2d13 91 if(length < 64-bufferLength)
feb11 0:7a1237bd2d13 92 {
feb11 0:7a1237bd2d13 93 memcpy(&buffer[bufferLength], in, length);
feb11 0:7a1237bd2d13 94 bufferLength += length;
feb11 0:7a1237bd2d13 95 totalBufferLength += length;
feb11 0:7a1237bd2d13 96 return;
feb11 0:7a1237bd2d13 97 }
feb11 0:7a1237bd2d13 98 int offset = 64-bufferLength;
feb11 0:7a1237bd2d13 99 memcpy(&buffer[bufferLength], in, offset);
feb11 0:7a1237bd2d13 100 computeRounds(&a, &b, &c, &d, buffer);
feb11 0:7a1237bd2d13 101 while(length-offset > 64)
feb11 0:7a1237bd2d13 102 {
feb11 0:7a1237bd2d13 103 memcpy(buffer, &in[offset], 64);
feb11 0:7a1237bd2d13 104 computeRounds(&a, &b, &c, &d, buffer);
feb11 0:7a1237bd2d13 105 offset += 64;
feb11 0:7a1237bd2d13 106 }
feb11 0:7a1237bd2d13 107 if(offset > length)
feb11 0:7a1237bd2d13 108 offset -= 64;
feb11 0:7a1237bd2d13 109 bufferLength = length - offset;
feb11 0:7a1237bd2d13 110 memcpy(buffer, &in[offset], bufferLength);
feb11 0:7a1237bd2d13 111 totalBufferLength += length;
feb11 0:7a1237bd2d13 112 }
feb11 0:7a1237bd2d13 113
feb11 0:7a1237bd2d13 114 void MD5::computeDigest(uint8_t *digest)
feb11 0:7a1237bd2d13 115 {
feb11 0:7a1237bd2d13 116 uint16_t padding;
feb11 0:7a1237bd2d13 117 if(totalBufferLength % 64 < 56)
feb11 0:7a1237bd2d13 118 padding = 56 - (totalBufferLength % 64);
feb11 0:7a1237bd2d13 119 else
feb11 0:7a1237bd2d13 120 padding = 56 + (64 - (totalBufferLength % 64));
feb11 0:7a1237bd2d13 121 uint8_t val = 0x80;
feb11 0:7a1237bd2d13 122 add(&val, 1);
feb11 0:7a1237bd2d13 123 val = 0;
feb11 0:7a1237bd2d13 124 for(int i = 0; i < padding-1; ++i)
feb11 0:7a1237bd2d13 125 add(&val,1);
feb11 0:7a1237bd2d13 126 totalBufferLength -= padding;
feb11 0:7a1237bd2d13 127 uint64_t lengthBit = totalBufferLength * 8;
feb11 0:7a1237bd2d13 128 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 129 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 0:7a1237bd2d13 130 add((uint8_t*)&lengthBitLow,4);
feb11 0:7a1237bd2d13 131 add((uint8_t*)&lengthBitHigh,4);
feb11 0:7a1237bd2d13 132
feb11 0:7a1237bd2d13 133 memcpy(digest, &a, 4);
feb11 0:7a1237bd2d13 134 memcpy(&digest[4], &b, 4);
feb11 0:7a1237bd2d13 135 memcpy(&digest[8], &c, 4);
feb11 0:7a1237bd2d13 136 memcpy(&digest[12], &d, 4);
feb11 0:7a1237bd2d13 137 // reset state
feb11 0:7a1237bd2d13 138 a = A;
feb11 0:7a1237bd2d13 139 b = B;
feb11 0:7a1237bd2d13 140 c = C;
feb11 0:7a1237bd2d13 141 d = D;
feb11 0:7a1237bd2d13 142 totalBufferLength = 0;
feb11 0:7a1237bd2d13 143 bufferLength = 0;
feb11 0:7a1237bd2d13 144 }
feb11 0:7a1237bd2d13 145
feb11 0:7a1237bd2d13 146 void MD5::computeRounds(uint32_t *a2, uint32_t *b2, uint32_t *c2, uint32_t *d2, uint8_t *buffer)
feb11 0:7a1237bd2d13 147 {
feb11 1:14a7cea431aa 148
feb11 0:7a1237bd2d13 149 uint32_t a = *a2, b = *b2, c = *c2, d = *d2;
feb11 1:14a7cea431aa 150 uint32_t tmpA = a, tmpB = b, tmpC = c, tmpD = d;
feb11 1:14a7cea431aa 151
feb11 0:7a1237bd2d13 152 uint32_t x[16];
feb11 0:7a1237bd2d13 153 for(int j = 0; j < 16; ++j)
feb11 0:7a1237bd2d13 154 memcpy(&x[j], &buffer[j*4], 4);
feb11 0:7a1237bd2d13 155
feb11 0:7a1237bd2d13 156 // Round 1
feb11 0:7a1237bd2d13 157 ROUND1(a,b,c,d,0,7,1); ROUND1(d,a,b,c,1,12,2); ROUND1(c,d,a,b,2,17,3); ROUND1(b,c,d,a,3,22,4);
feb11 0:7a1237bd2d13 158 ROUND1(a,b,c,d,4,7,5); ROUND1(d,a,b,c,5,12,6); ROUND1(c,d,a,b,6,17,7); ROUND1(b,c,d,a,7,22,8);
feb11 0:7a1237bd2d13 159 ROUND1(a,b,c,d,8,7,9); ROUND1(d,a,b,c,9,12,10); ROUND1(c,d,a,b,10,17,11); ROUND1(b,c,d,a,11,22,12);
feb11 0:7a1237bd2d13 160 ROUND1(a,b,c,d,12,7,13); ROUND1(d,a,b,c,13,12,14); ROUND1(c,d,a,b,14,17,15); ROUND1(b,c,d,a,15,22,16);
feb11 0:7a1237bd2d13 161
feb11 0:7a1237bd2d13 162 // Round 2
feb11 0:7a1237bd2d13 163 ROUND2(a,b,c,d,1,5,17); ROUND2(d,a,b,c,6,9,18); ROUND2(c,d,a,b,11,14,19); ROUND2(b,c,d,a,0,20,20);
feb11 0:7a1237bd2d13 164 ROUND2(a,b,c,d,5,5,21); ROUND2(d,a,b,c,10,9,22); ROUND2(c,d,a,b,15,14,23); ROUND2(b,c,d,a,4,20,24);
feb11 0:7a1237bd2d13 165 ROUND2(a,b,c,d,9,5,25); ROUND2(d,a,b,c,14,9,26); ROUND2(c,d,a,b,3,14,27); ROUND2(b,c,d,a,8,20,28);
feb11 0:7a1237bd2d13 166 ROUND2(a,b,c,d,13,5,29); ROUND2(d,a,b,c,2,9,30); ROUND2(c,d,a,b,7,14,31); ROUND2(b,c,d,a,12,20,32);
feb11 0:7a1237bd2d13 167
feb11 0:7a1237bd2d13 168 // Round 3
feb11 0:7a1237bd2d13 169 ROUND3(a,b,c,d,5,4,33); ROUND3(d,a,b,c,8,11,34); ROUND3(c,d,a,b,11,16,35); ROUND3(b,c,d,a,14,23,36);
feb11 0:7a1237bd2d13 170 ROUND3(a,b,c,d,1,4,37); ROUND3(d,a,b,c,4,11,38); ROUND3(c,d,a,b,7,16,39); ROUND3(b,c,d,a,10,23,40);
feb11 0:7a1237bd2d13 171 ROUND3(a,b,c,d,13,4,41); ROUND3(d,a,b,c,0,11,42); ROUND3(c,d,a,b,3,16,43); ROUND3(b,c,d,a,6,23,44);
feb11 0:7a1237bd2d13 172 ROUND3(a,b,c,d,9,4,45); ROUND3(d,a,b,c,12,11,46); ROUND3(c,d,a,b,15,16,47); ROUND3(b,c,d,a,2,23,48);
feb11 0:7a1237bd2d13 173
feb11 0:7a1237bd2d13 174 // Round 4
feb11 0:7a1237bd2d13 175 ROUND4(a,b,c,d,0,6,49); ROUND4(d,a,b,c,7,10,50); ROUND4(c,d,a,b,14,15,51); ROUND4(b,c,d,a,5,21,52);
feb11 0:7a1237bd2d13 176 ROUND4(a,b,c,d,12,6,53); ROUND4(d,a,b,c,3,10,54); ROUND4(c,d,a,b,10,15,55); ROUND4(b,c,d,a,1,21,56);
feb11 0:7a1237bd2d13 177 ROUND4(a,b,c,d,8,6,57); ROUND4(d,a,b,c,15,10,58); ROUND4(c,d,a,b,6,15,59); ROUND4(b,c,d,a,13,21,60);
feb11 0:7a1237bd2d13 178 ROUND4(a,b,c,d,4,6,61); ROUND4(d,a,b,c,11,10,62); ROUND4(c,d,a,b,2,15,63); ROUND4(b,c,d,a,9,21,64);
feb11 0:7a1237bd2d13 179
feb11 1:14a7cea431aa 180 a += tmpA;
feb11 1:14a7cea431aa 181 b += tmpB;
feb11 1:14a7cea431aa 182 c += tmpC;
feb11 1:14a7cea431aa 183 d += tmpD;
feb11 1:14a7cea431aa 184
feb11 0:7a1237bd2d13 185 *a2 = a;
feb11 0:7a1237bd2d13 186 *b2 = b;
feb11 0:7a1237bd2d13 187 *c2 = c;
feb11 0:7a1237bd2d13 188 *d2 = d;
feb11 0:7a1237bd2d13 189 }
feb11 0:7a1237bd2d13 190
feb11 0:7a1237bd2d13 191 void MD5::computeDigest(uint8_t *digest, uint8_t *msg, uint32_t length)
feb11 0:7a1237bd2d13 192 {
feb11 0:7a1237bd2d13 193 uint16_t padding;
feb11 0:7a1237bd2d13 194 if(length % 64 < 56)
feb11 0:7a1237bd2d13 195 padding = 56 - (length % 64);
feb11 0:7a1237bd2d13 196 else
feb11 0:7a1237bd2d13 197 padding = 56 + (64 - (length % 64));
feb11 1:14a7cea431aa 198
feb11 1:14a7cea431aa 199 uint32_t a = A, b = B, c = C, d = D;
feb11 1:14a7cea431aa 200
feb11 1:14a7cea431aa 201 uint32_t offset = 0;
feb11 1:14a7cea431aa 202 while(length - offset >= 64)
feb11 1:14a7cea431aa 203 {
feb11 1:14a7cea431aa 204 computeRounds(&a, &b, &c, &d, &msg[offset]);
feb11 1:14a7cea431aa 205 offset += 64;
feb11 1:14a7cea431aa 206 }
feb11 1:14a7cea431aa 207 uint8_t buffer[64];
feb11 1:14a7cea431aa 208 memcpy(buffer, &msg[offset], length-offset);
feb11 1:14a7cea431aa 209 uint8_t bufferLength = length - offset;
feb11 1:14a7cea431aa 210 buffer[bufferLength++] = 0x80;
feb11 1:14a7cea431aa 211 padding--;
feb11 1:14a7cea431aa 212 while(padding > 0)
feb11 1:14a7cea431aa 213 {
feb11 1:14a7cea431aa 214 if(bufferLength == 64)
feb11 1:14a7cea431aa 215 {
feb11 1:14a7cea431aa 216 computeRounds(&a, &b, &c, &d, buffer);
feb11 1:14a7cea431aa 217 bufferLength = 0;
feb11 1:14a7cea431aa 218 }
feb11 1:14a7cea431aa 219 buffer[bufferLength++] = 0;
feb11 1:14a7cea431aa 220 padding--;
feb11 1:14a7cea431aa 221 }
feb11 0:7a1237bd2d13 222 uint64_t lengthBit = length * 8;
feb11 0:7a1237bd2d13 223 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 224 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 1:14a7cea431aa 225 memcpy(&buffer[56], &lengthBitLow, 4);
feb11 1:14a7cea431aa 226 memcpy(&buffer[60], &lengthBitHigh, 4);
feb11 0:7a1237bd2d13 227
feb11 1:14a7cea431aa 228 computeRounds(&a, &b, &c, &d, buffer);
feb11 1:14a7cea431aa 229
feb11 0:7a1237bd2d13 230 memcpy(digest, &a, 4);
feb11 0:7a1237bd2d13 231 memcpy(&digest[4], &b, 4);
feb11 0:7a1237bd2d13 232 memcpy(&digest[8], &c, 4);
feb11 0:7a1237bd2d13 233 memcpy(&digest[12], &d, 4);
feb11 0:7a1237bd2d13 234 }