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:
Mon Sep 16 08:35:36 2013 +0000
Revision:
9:e34e076fb223
Child:
10:bc9c23aa3870
implemented MD4

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 9:e34e076fb223 1 #include "MD4.h"
feb11 9:e34e076fb223 2 #include <string.h>
feb11 9:e34e076fb223 3
feb11 9:e34e076fb223 4 static const uint32_t A = 0x67452301;
feb11 9:e34e076fb223 5 static const uint32_t B = 0xefcdab89;
feb11 9:e34e076fb223 6 static const uint32_t C = 0x98badcfe;
feb11 9:e34e076fb223 7 static const uint32_t D = 0x10325476;
feb11 9:e34e076fb223 8
feb11 9:e34e076fb223 9 #define F(X,Y,Z) ((X & Y) | ((~X) & Z))
feb11 9:e34e076fb223 10 #define G(X,Y,Z) ((X & Y) | (X & Z) | (Y & Z))
feb11 9:e34e076fb223 11 #define H(X,Y,Z) (X ^ Y ^ Z)
feb11 9:e34e076fb223 12
feb11 9:e34e076fb223 13
feb11 9:e34e076fb223 14 #define ROTL(W,N) (((W) << N) | ((W) >> (32-N)))
feb11 9:e34e076fb223 15
feb11 9:e34e076fb223 16 #define ROUND1(a,b,c,d,x,s) \
feb11 9:e34e076fb223 17 a = ROTL(a + F(b,c,d) + x,s);
feb11 9:e34e076fb223 18
feb11 9:e34e076fb223 19 #define ROUND2(a,b,c,d,x,s) \
feb11 9:e34e076fb223 20 a = ROTL(a + G(b,c,d) + x + 0x5A827999,s);
feb11 9:e34e076fb223 21
feb11 9:e34e076fb223 22 #define ROUND3(a,b,c,d,x,s) \
feb11 9:e34e076fb223 23 a = ROTL(a + H(b,c,d) + x + 0x6ED9EBA1,s);
feb11 9:e34e076fb223 24
feb11 9:e34e076fb223 25
feb11 9:e34e076fb223 26
feb11 9:e34e076fb223 27 MD4::MD4():
feb11 9:e34e076fb223 28 HashAlgorithm(),
feb11 9:e34e076fb223 29 a(A),
feb11 9:e34e076fb223 30 b(B),
feb11 9:e34e076fb223 31 c(C),
feb11 9:e34e076fb223 32 d(D),
feb11 9:e34e076fb223 33 totalBufferLength(0),
feb11 9:e34e076fb223 34 buffer(),
feb11 9:e34e076fb223 35 bufferLength(0)
feb11 9:e34e076fb223 36 {
feb11 9:e34e076fb223 37 }
feb11 9:e34e076fb223 38
feb11 9:e34e076fb223 39 uint8_t MD4::outputSize() const
feb11 9:e34e076fb223 40 {
feb11 9:e34e076fb223 41 return 16;
feb11 9:e34e076fb223 42 }
feb11 9:e34e076fb223 43
feb11 9:e34e076fb223 44 void MD4::update(uint8_t *data, uint32_t length)
feb11 9:e34e076fb223 45 {
feb11 9:e34e076fb223 46 if(length < 64-bufferLength)
feb11 9:e34e076fb223 47 {
feb11 9:e34e076fb223 48 memcpy(&buffer[bufferLength], data, length);
feb11 9:e34e076fb223 49 bufferLength += length;
feb11 9:e34e076fb223 50 totalBufferLength += length;
feb11 9:e34e076fb223 51 return;
feb11 9:e34e076fb223 52 }
feb11 9:e34e076fb223 53 int offset = 64-bufferLength;
feb11 9:e34e076fb223 54 memcpy(&buffer[bufferLength], data, offset);
feb11 9:e34e076fb223 55 computeRounds(&a, &b, &c, &d, buffer);
feb11 9:e34e076fb223 56 while(length-offset > 64)
feb11 9:e34e076fb223 57 {
feb11 9:e34e076fb223 58 memcpy(buffer, &data[offset], 64);
feb11 9:e34e076fb223 59 computeRounds(&a, &b, &c, &d, buffer);
feb11 9:e34e076fb223 60 offset += 64;
feb11 9:e34e076fb223 61 }
feb11 9:e34e076fb223 62 if(offset > length)
feb11 9:e34e076fb223 63 offset -= 64;
feb11 9:e34e076fb223 64 bufferLength = length - offset;
feb11 9:e34e076fb223 65 memcpy(buffer, &data[offset], bufferLength);
feb11 9:e34e076fb223 66 totalBufferLength += length;
feb11 9:e34e076fb223 67 }
feb11 9:e34e076fb223 68
feb11 9:e34e076fb223 69 void MD4::finalize(uint8_t *hash)
feb11 9:e34e076fb223 70 {
feb11 9:e34e076fb223 71 uint32_t *hash2 = (uint32_t*)hash;
feb11 9:e34e076fb223 72 uint16_t padding;
feb11 9:e34e076fb223 73 if(totalBufferLength % 64 < 56)
feb11 9:e34e076fb223 74 padding = 56 - (totalBufferLength % 64);
feb11 9:e34e076fb223 75 else
feb11 9:e34e076fb223 76 padding = 56 + (64 - (totalBufferLength % 64));
feb11 9:e34e076fb223 77 buffer[bufferLength++] = 0x80;
feb11 9:e34e076fb223 78 padding--;
feb11 9:e34e076fb223 79 if(padding+bufferLength == 56)
feb11 9:e34e076fb223 80 memset(&buffer[bufferLength], 0, padding);
feb11 9:e34e076fb223 81 else
feb11 9:e34e076fb223 82 {
feb11 9:e34e076fb223 83 memset(&buffer[bufferLength], 0, 64-bufferLength);
feb11 9:e34e076fb223 84 computeRounds(&a, &b, &c, &d, buffer);
feb11 9:e34e076fb223 85 memset(buffer, 0, 56);
feb11 9:e34e076fb223 86 }
feb11 9:e34e076fb223 87 uint64_t lengthBit = totalBufferLength << 3;
feb11 9:e34e076fb223 88 uint32_t lengthBitLow = lengthBit;
feb11 9:e34e076fb223 89 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 9:e34e076fb223 90 memcpy(&buffer[56], &lengthBitLow, 4);
feb11 9:e34e076fb223 91 memcpy(&buffer[60], &lengthBitHigh, 4);
feb11 9:e34e076fb223 92 computeRounds(&a, &b, &c, &d, buffer);
feb11 9:e34e076fb223 93
feb11 9:e34e076fb223 94 hash2[0] = a;
feb11 9:e34e076fb223 95 hash2[1] = b;
feb11 9:e34e076fb223 96 hash2[2] = c;
feb11 9:e34e076fb223 97 hash2[3] = d;
feb11 9:e34e076fb223 98 // reset state
feb11 9:e34e076fb223 99 a = A;
feb11 9:e34e076fb223 100 b = B;
feb11 9:e34e076fb223 101 c = C;
feb11 9:e34e076fb223 102 d = D;
feb11 9:e34e076fb223 103 totalBufferLength = 0;
feb11 9:e34e076fb223 104 bufferLength = 0;
feb11 9:e34e076fb223 105 }
feb11 9:e34e076fb223 106
feb11 9:e34e076fb223 107
feb11 9:e34e076fb223 108 void MD4::computeHash(uint8_t *hash, uint8_t *data, uint32_t length)
feb11 9:e34e076fb223 109 {
feb11 9:e34e076fb223 110 uint32_t *hash2 = (uint32_t*)hash;
feb11 9:e34e076fb223 111 uint64_t lengthBit = length << 3;
feb11 9:e34e076fb223 112 uint16_t padding;
feb11 9:e34e076fb223 113 if(length % 64 < 56)
feb11 9:e34e076fb223 114 padding = 56 - (length % 64);
feb11 9:e34e076fb223 115 else
feb11 9:e34e076fb223 116 padding = 56 + (64 - (length % 64));
feb11 9:e34e076fb223 117
feb11 9:e34e076fb223 118 uint32_t a = A, b = B, c = C, d = D;
feb11 9:e34e076fb223 119 while(length >= 64)
feb11 9:e34e076fb223 120 {
feb11 9:e34e076fb223 121 computeRounds(&a, &b, &c, &d, data);
feb11 9:e34e076fb223 122 data += 64;
feb11 9:e34e076fb223 123 length -= 64;
feb11 9:e34e076fb223 124 }
feb11 9:e34e076fb223 125 uint8_t buffer[64];
feb11 9:e34e076fb223 126 memcpy(buffer, data, length);
feb11 9:e34e076fb223 127 buffer[length++] = 0x80;
feb11 9:e34e076fb223 128 padding--;
feb11 9:e34e076fb223 129 if(padding+length == 56)
feb11 9:e34e076fb223 130 memset(&buffer[length], 0, padding);
feb11 9:e34e076fb223 131 else
feb11 9:e34e076fb223 132 {
feb11 9:e34e076fb223 133 memset(&buffer[length], 0, 64-length);
feb11 9:e34e076fb223 134 computeRounds(&a, &b, &c, &d, data);
feb11 9:e34e076fb223 135 memset(buffer, 0, 56);
feb11 9:e34e076fb223 136 }
feb11 9:e34e076fb223 137
feb11 9:e34e076fb223 138 uint32_t lengthBitLow = lengthBit;
feb11 9:e34e076fb223 139 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 9:e34e076fb223 140 memcpy(&buffer[56], &lengthBitLow, 4);
feb11 9:e34e076fb223 141 memcpy(&buffer[60], &lengthBitHigh, 4);
feb11 9:e34e076fb223 142
feb11 9:e34e076fb223 143 computeRounds(&a, &b, &c, &d, buffer);
feb11 9:e34e076fb223 144
feb11 9:e34e076fb223 145 hash2[0] = a;
feb11 9:e34e076fb223 146 hash2[1] = b;
feb11 9:e34e076fb223 147 hash2[2] = c;
feb11 9:e34e076fb223 148 hash2[3] = d;
feb11 9:e34e076fb223 149 }
feb11 9:e34e076fb223 150
feb11 9:e34e076fb223 151 void MD4::computeRounds(uint32_t *a2, uint32_t *b2, uint32_t *c2, uint32_t *d2, uint8_t *buffer)
feb11 9:e34e076fb223 152 {
feb11 9:e34e076fb223 153 uint32_t a = *a2, b = *b2, c = *c2, d = *d2;
feb11 9:e34e076fb223 154 uint32_t tmpA = a, tmpB = b, tmpC = c, tmpD = d;
feb11 9:e34e076fb223 155
feb11 9:e34e076fb223 156 uint32_t *x = (uint32_t*)buffer;
feb11 9:e34e076fb223 157
feb11 9:e34e076fb223 158 // Round 1
feb11 9:e34e076fb223 159 ROUND1(a,b,c,d,x[0],3); ROUND1(d,a,b,c,x[1],7); ROUND1(c,d,a,b,x[2],11); ROUND1(b,c,d,a,x[3],19);
feb11 9:e34e076fb223 160 ROUND1(a,b,c,d,x[4],3); ROUND1(d,a,b,c,x[5],7); ROUND1(c,d,a,b,x[6],11); ROUND1(b,c,d,a,x[7],19);
feb11 9:e34e076fb223 161 ROUND1(a,b,c,d,x[8],3); ROUND1(d,a,b,c,x[9],7); ROUND1(c,d,a,b,x[10],11); ROUND1(b,c,d,a,x[11],19);
feb11 9:e34e076fb223 162 ROUND1(a,b,c,d,x[12],3); ROUND1(d,a,b,c,x[13],7); ROUND1(c,d,a,b,x[14],11); ROUND1(b,c,d,a,x[15],19);
feb11 9:e34e076fb223 163
feb11 9:e34e076fb223 164
feb11 9:e34e076fb223 165 // Round 2
feb11 9:e34e076fb223 166 ROUND2(a,b,c,d,x[0],3); ROUND2(d,a,b,c,x[4],5); ROUND2(c,d,a,b,x[8],9); ROUND2(b,c,d,a,x[12],13);
feb11 9:e34e076fb223 167 ROUND2(a,b,c,d,x[1],3); ROUND2(d,a,b,c,x[5],5); ROUND2(c,d,a,b,x[9],9); ROUND2(b,c,d,a,x[13],13);
feb11 9:e34e076fb223 168 ROUND2(a,b,c,d,x[2],3); ROUND2(d,a,b,c,x[6],5); ROUND2(c,d,a,b,x[10],9); ROUND2(b,c,d,a,x[14],13);
feb11 9:e34e076fb223 169 ROUND2(a,b,c,d,x[3],3); ROUND2(d,a,b,c,x[7],5); ROUND2(c,d,a,b,x[11],9); ROUND2(b,c,d,a,x[15],13);
feb11 9:e34e076fb223 170
feb11 9:e34e076fb223 171
feb11 9:e34e076fb223 172 // Round 3
feb11 9:e34e076fb223 173 ROUND3(a,b,c,d,x[0],3); ROUND3(d,a,b,c,x[8],9); ROUND3(c,d,a,b,x[4],11); ROUND3(b,c,d,a,x[12],15);
feb11 9:e34e076fb223 174 ROUND3(a,b,c,d,x[2],3); ROUND3(d,a,b,c,x[10],9); ROUND3(c,d,a,b,x[6],11); ROUND3(b,c,d,a,x[14],15);
feb11 9:e34e076fb223 175 ROUND3(a,b,c,d,x[1],3); ROUND3(d,a,b,c,x[9],9); ROUND3(c,d,a,b,x[5],11); ROUND3(b,c,d,a,x[13],15);
feb11 9:e34e076fb223 176 ROUND3(a,b,c,d,x[3],3); ROUND3(d,a,b,c,x[11],9); ROUND3(c,d,a,b,x[7],11); ROUND3(b,c,d,a,x[15],15);
feb11 9:e34e076fb223 177
feb11 9:e34e076fb223 178
feb11 9:e34e076fb223 179 *a2 = a + tmpA;
feb11 9:e34e076fb223 180 *b2 = b + tmpB;
feb11 9:e34e076fb223 181 *c2 = c + tmpC;
feb11 9:e34e076fb223 182 *d2 = d + tmpD;
feb11 9:e34e076fb223 183 }