Embedded systems coursework 2.
Fork of Crypto_light by
MD5.cpp@1:14a7cea431aa, 2013-09-09 (annotated)
- 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?
User | Revision | Line number | New 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 | } |