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 15:08:51 2013 +0000
Revision:
5:06cd9c8afa0b
Parent:
4:0da19393bd57
Child:
6:19aa835f2bbb
change API & small improvements in SHA-2

Who changed what in which revision?

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