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:
Sat Sep 07 23:47:28 2013 +0000
Revision:
0:7a1237bd2d13
Child:
1:14a7cea431aa
initial import

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 uint32_t tmpA = a, tmpB = b, tmpC = c, tmpD = d;
feb11 0:7a1237bd2d13 101 computeRounds(&a, &b, &c, &d, buffer);
feb11 0:7a1237bd2d13 102 a += tmpA;
feb11 0:7a1237bd2d13 103 b += tmpB;
feb11 0:7a1237bd2d13 104 c += tmpC;
feb11 0:7a1237bd2d13 105 d += tmpD;
feb11 0:7a1237bd2d13 106 while(length-offset > 64)
feb11 0:7a1237bd2d13 107 {
feb11 0:7a1237bd2d13 108 memcpy(buffer, &in[offset], 64);
feb11 0:7a1237bd2d13 109 tmpA = a;
feb11 0:7a1237bd2d13 110 tmpB = b;
feb11 0:7a1237bd2d13 111 tmpC = c;
feb11 0:7a1237bd2d13 112 tmpD = d;
feb11 0:7a1237bd2d13 113 computeRounds(&a, &b, &c, &d, buffer);
feb11 0:7a1237bd2d13 114 a += tmpA;
feb11 0:7a1237bd2d13 115 b += tmpB;
feb11 0:7a1237bd2d13 116 c += tmpC;
feb11 0:7a1237bd2d13 117 d += tmpD;
feb11 0:7a1237bd2d13 118 offset += 64;
feb11 0:7a1237bd2d13 119 }
feb11 0:7a1237bd2d13 120 if(offset > length)
feb11 0:7a1237bd2d13 121 offset -= 64;
feb11 0:7a1237bd2d13 122 bufferLength = length - offset;
feb11 0:7a1237bd2d13 123 memcpy(buffer, &in[offset], bufferLength);
feb11 0:7a1237bd2d13 124 totalBufferLength += length;
feb11 0:7a1237bd2d13 125 }
feb11 0:7a1237bd2d13 126
feb11 0:7a1237bd2d13 127 void MD5::computeDigest(uint8_t *digest)
feb11 0:7a1237bd2d13 128 {
feb11 0:7a1237bd2d13 129 uint16_t padding;
feb11 0:7a1237bd2d13 130 if(totalBufferLength % 64 < 56)
feb11 0:7a1237bd2d13 131 padding = 56 - (totalBufferLength % 64);
feb11 0:7a1237bd2d13 132 else
feb11 0:7a1237bd2d13 133 padding = 56 + (64 - (totalBufferLength % 64));
feb11 0:7a1237bd2d13 134 uint8_t val = 0x80;
feb11 0:7a1237bd2d13 135 add(&val, 1);
feb11 0:7a1237bd2d13 136 val = 0;
feb11 0:7a1237bd2d13 137 for(int i = 0; i < padding-1; ++i)
feb11 0:7a1237bd2d13 138 add(&val,1);
feb11 0:7a1237bd2d13 139 totalBufferLength -= padding;
feb11 0:7a1237bd2d13 140 uint64_t lengthBit = totalBufferLength * 8;
feb11 0:7a1237bd2d13 141 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 142 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 0:7a1237bd2d13 143 add((uint8_t*)&lengthBitLow,4);
feb11 0:7a1237bd2d13 144 add((uint8_t*)&lengthBitHigh,4);
feb11 0:7a1237bd2d13 145
feb11 0:7a1237bd2d13 146 memcpy(digest, &a, 4);
feb11 0:7a1237bd2d13 147 memcpy(&digest[4], &b, 4);
feb11 0:7a1237bd2d13 148 memcpy(&digest[8], &c, 4);
feb11 0:7a1237bd2d13 149 memcpy(&digest[12], &d, 4);
feb11 0:7a1237bd2d13 150 // reset state
feb11 0:7a1237bd2d13 151 a = A;
feb11 0:7a1237bd2d13 152 b = B;
feb11 0:7a1237bd2d13 153 c = C;
feb11 0:7a1237bd2d13 154 d = D;
feb11 0:7a1237bd2d13 155 totalBufferLength = 0;
feb11 0:7a1237bd2d13 156 bufferLength = 0;
feb11 0:7a1237bd2d13 157 }
feb11 0:7a1237bd2d13 158
feb11 0:7a1237bd2d13 159 void MD5::computeRounds(uint32_t *a2, uint32_t *b2, uint32_t *c2, uint32_t *d2, uint8_t *buffer)
feb11 0:7a1237bd2d13 160 {
feb11 0:7a1237bd2d13 161 uint32_t a = *a2, b = *b2, c = *c2, d = *d2;
feb11 0:7a1237bd2d13 162 uint32_t x[16];
feb11 0:7a1237bd2d13 163 for(int j = 0; j < 16; ++j)
feb11 0:7a1237bd2d13 164 memcpy(&x[j], &buffer[j*4], 4);
feb11 0:7a1237bd2d13 165
feb11 0:7a1237bd2d13 166 // Round 1
feb11 0:7a1237bd2d13 167 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 168 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 169 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 170 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 171
feb11 0:7a1237bd2d13 172 // Round 2
feb11 0:7a1237bd2d13 173 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 174 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 175 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 176 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 177
feb11 0:7a1237bd2d13 178 // Round 3
feb11 0:7a1237bd2d13 179 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 180 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 181 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 182 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 183
feb11 0:7a1237bd2d13 184 // Round 4
feb11 0:7a1237bd2d13 185 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 186 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 187 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 188 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 189
feb11 0:7a1237bd2d13 190 *a2 = a;
feb11 0:7a1237bd2d13 191 *b2 = b;
feb11 0:7a1237bd2d13 192 *c2 = c;
feb11 0:7a1237bd2d13 193 *d2 = d;
feb11 0:7a1237bd2d13 194 }
feb11 0:7a1237bd2d13 195
feb11 0:7a1237bd2d13 196 void MD5::computeDigest(uint8_t *digest, uint8_t *msg, uint32_t length)
feb11 0:7a1237bd2d13 197 {
feb11 0:7a1237bd2d13 198 uint16_t padding;
feb11 0:7a1237bd2d13 199 if(length % 64 < 56)
feb11 0:7a1237bd2d13 200 padding = 56 - (length % 64);
feb11 0:7a1237bd2d13 201 else
feb11 0:7a1237bd2d13 202 padding = 56 + (64 - (length % 64));
feb11 0:7a1237bd2d13 203 uint32_t totalLength = length + padding + 8;
feb11 0:7a1237bd2d13 204 uint8_t *buffer = new uint8_t[totalLength];
feb11 0:7a1237bd2d13 205 memcpy(buffer, msg, length);
feb11 0:7a1237bd2d13 206 buffer[length] = 0x80;
feb11 0:7a1237bd2d13 207 memset(&buffer[length+1], 0, padding-1);
feb11 0:7a1237bd2d13 208 uint64_t lengthBit = length * 8;
feb11 0:7a1237bd2d13 209 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 210 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 0:7a1237bd2d13 211 memcpy(&buffer[length+padding], &lengthBitLow, 4);
feb11 0:7a1237bd2d13 212 memcpy(&buffer[length+padding+4], &lengthBitHigh, 4);
feb11 0:7a1237bd2d13 213
feb11 0:7a1237bd2d13 214 uint32_t a = A, b = B, c = C, d = D;
feb11 0:7a1237bd2d13 215 for(int i = 0; i < totalLength/64; ++i)
feb11 0:7a1237bd2d13 216 {
feb11 0:7a1237bd2d13 217 uint32_t tmpA = a, tmpB = b, tmpC = c, tmpD = d;
feb11 0:7a1237bd2d13 218 computeRounds(&a, &b, &c, &d, &buffer[64*i]);
feb11 0:7a1237bd2d13 219
feb11 0:7a1237bd2d13 220 a += tmpA;
feb11 0:7a1237bd2d13 221 b += tmpB;
feb11 0:7a1237bd2d13 222 c += tmpC;
feb11 0:7a1237bd2d13 223 d += tmpD;
feb11 0:7a1237bd2d13 224 }
feb11 0:7a1237bd2d13 225 delete[] buffer;
feb11 0:7a1237bd2d13 226
feb11 0:7a1237bd2d13 227 memcpy(digest, &a, 4);
feb11 0:7a1237bd2d13 228 memcpy(&digest[4], &b, 4);
feb11 0:7a1237bd2d13 229 memcpy(&digest[8], &c, 4);
feb11 0:7a1237bd2d13 230 memcpy(&digest[12], &d, 4);
feb11 0:7a1237bd2d13 231 }