CyaSSL is an SSL library for devices like mbed.

Dependents:   cyassl-client Sync

Committer:
toddouska
Date:
Sat Feb 05 01:09:17 2011 +0000
Revision:
0:5045d2638c29
Beta Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
toddouska 0:5045d2638c29 1 /* md4.c
toddouska 0:5045d2638c29 2 *
toddouska 0:5045d2638c29 3 * Copyright (C) 2006-2009 Sawtooth Consulting Ltd.
toddouska 0:5045d2638c29 4 *
toddouska 0:5045d2638c29 5 * This file is part of CyaSSL.
toddouska 0:5045d2638c29 6 *
toddouska 0:5045d2638c29 7 * CyaSSL is free software; you can redistribute it and/or modify
toddouska 0:5045d2638c29 8 * it under the terms of the GNU General Public License as published by
toddouska 0:5045d2638c29 9 * the Free Software Foundation; either version 2 of the License, or
toddouska 0:5045d2638c29 10 * (at your option) any later version.
toddouska 0:5045d2638c29 11 *
toddouska 0:5045d2638c29 12 * CyaSSL is distributed in the hope that it will be useful,
toddouska 0:5045d2638c29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
toddouska 0:5045d2638c29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
toddouska 0:5045d2638c29 15 * GNU General Public License for more details.
toddouska 0:5045d2638c29 16 *
toddouska 0:5045d2638c29 17 * You should have received a copy of the GNU General Public License
toddouska 0:5045d2638c29 18 * along with this program; if not, write to the Free Software
toddouska 0:5045d2638c29 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
toddouska 0:5045d2638c29 20 */
toddouska 0:5045d2638c29 21
toddouska 0:5045d2638c29 22
toddouska 0:5045d2638c29 23 #ifndef NO_MD4
toddouska 0:5045d2638c29 24
toddouska 0:5045d2638c29 25 #include "ctc_md4.h"
toddouska 0:5045d2638c29 26 #ifdef NO_INLINE
toddouska 0:5045d2638c29 27 #include "misc.h"
toddouska 0:5045d2638c29 28 #else
toddouska 0:5045d2638c29 29 #include "misc.c"
toddouska 0:5045d2638c29 30 #endif
toddouska 0:5045d2638c29 31
toddouska 0:5045d2638c29 32
toddouska 0:5045d2638c29 33
toddouska 0:5045d2638c29 34 #ifndef min
toddouska 0:5045d2638c29 35
toddouska 0:5045d2638c29 36 static INLINE word32 min(word32 a, word32 b)
toddouska 0:5045d2638c29 37 {
toddouska 0:5045d2638c29 38 return a > b ? b : a;
toddouska 0:5045d2638c29 39 }
toddouska 0:5045d2638c29 40
toddouska 0:5045d2638c29 41 #endif /* min */
toddouska 0:5045d2638c29 42
toddouska 0:5045d2638c29 43
toddouska 0:5045d2638c29 44 void InitMd4(Md4* md4)
toddouska 0:5045d2638c29 45 {
toddouska 0:5045d2638c29 46 md4->digest[0] = 0x67452301L;
toddouska 0:5045d2638c29 47 md4->digest[1] = 0xefcdab89L;
toddouska 0:5045d2638c29 48 md4->digest[2] = 0x98badcfeL;
toddouska 0:5045d2638c29 49 md4->digest[3] = 0x10325476L;
toddouska 0:5045d2638c29 50
toddouska 0:5045d2638c29 51 md4->buffLen = 0;
toddouska 0:5045d2638c29 52 md4->loLen = 0;
toddouska 0:5045d2638c29 53 md4->hiLen = 0;
toddouska 0:5045d2638c29 54 }
toddouska 0:5045d2638c29 55
toddouska 0:5045d2638c29 56
toddouska 0:5045d2638c29 57 static void Transform(Md4* md4)
toddouska 0:5045d2638c29 58 {
toddouska 0:5045d2638c29 59 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
toddouska 0:5045d2638c29 60 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
toddouska 0:5045d2638c29 61 #define H(x, y, z) ((x) ^ (y) ^ (z))
toddouska 0:5045d2638c29 62
toddouska 0:5045d2638c29 63 /* Copy context->state[] to working vars */
toddouska 0:5045d2638c29 64 word32 A = md4->digest[0];
toddouska 0:5045d2638c29 65 word32 B = md4->digest[1];
toddouska 0:5045d2638c29 66 word32 C = md4->digest[2];
toddouska 0:5045d2638c29 67 word32 D = md4->digest[3];
toddouska 0:5045d2638c29 68
toddouska 0:5045d2638c29 69 #define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+md4->buffer[k],s);
toddouska 0:5045d2638c29 70 function(A,B,C,D, 0, 3);
toddouska 0:5045d2638c29 71 function(D,A,B,C, 1, 7);
toddouska 0:5045d2638c29 72 function(C,D,A,B, 2,11);
toddouska 0:5045d2638c29 73 function(B,C,D,A, 3,19);
toddouska 0:5045d2638c29 74 function(A,B,C,D, 4, 3);
toddouska 0:5045d2638c29 75 function(D,A,B,C, 5, 7);
toddouska 0:5045d2638c29 76 function(C,D,A,B, 6,11);
toddouska 0:5045d2638c29 77 function(B,C,D,A, 7,19);
toddouska 0:5045d2638c29 78 function(A,B,C,D, 8, 3);
toddouska 0:5045d2638c29 79 function(D,A,B,C, 9, 7);
toddouska 0:5045d2638c29 80 function(C,D,A,B,10,11);
toddouska 0:5045d2638c29 81 function(B,C,D,A,11,19);
toddouska 0:5045d2638c29 82 function(A,B,C,D,12, 3);
toddouska 0:5045d2638c29 83 function(D,A,B,C,13, 7);
toddouska 0:5045d2638c29 84 function(C,D,A,B,14,11);
toddouska 0:5045d2638c29 85 function(B,C,D,A,15,19);
toddouska 0:5045d2638c29 86
toddouska 0:5045d2638c29 87 #undef function
toddouska 0:5045d2638c29 88 #define function(a,b,c,d,k,s) \
toddouska 0:5045d2638c29 89 a=rotlFixed(a+G(b,c,d)+md4->buffer[k]+0x5a827999,s);
toddouska 0:5045d2638c29 90
toddouska 0:5045d2638c29 91 function(A,B,C,D, 0, 3);
toddouska 0:5045d2638c29 92 function(D,A,B,C, 4, 5);
toddouska 0:5045d2638c29 93 function(C,D,A,B, 8, 9);
toddouska 0:5045d2638c29 94 function(B,C,D,A,12,13);
toddouska 0:5045d2638c29 95 function(A,B,C,D, 1, 3);
toddouska 0:5045d2638c29 96 function(D,A,B,C, 5, 5);
toddouska 0:5045d2638c29 97 function(C,D,A,B, 9, 9);
toddouska 0:5045d2638c29 98 function(B,C,D,A,13,13);
toddouska 0:5045d2638c29 99 function(A,B,C,D, 2, 3);
toddouska 0:5045d2638c29 100 function(D,A,B,C, 6, 5);
toddouska 0:5045d2638c29 101 function(C,D,A,B,10, 9);
toddouska 0:5045d2638c29 102 function(B,C,D,A,14,13);
toddouska 0:5045d2638c29 103 function(A,B,C,D, 3, 3);
toddouska 0:5045d2638c29 104 function(D,A,B,C, 7, 5);
toddouska 0:5045d2638c29 105 function(C,D,A,B,11, 9);
toddouska 0:5045d2638c29 106 function(B,C,D,A,15,13);
toddouska 0:5045d2638c29 107
toddouska 0:5045d2638c29 108 #undef function
toddouska 0:5045d2638c29 109 #define function(a,b,c,d,k,s) \
toddouska 0:5045d2638c29 110 a=rotlFixed(a+H(b,c,d)+md4->buffer[k]+0x6ed9eba1,s);
toddouska 0:5045d2638c29 111
toddouska 0:5045d2638c29 112 function(A,B,C,D, 0, 3);
toddouska 0:5045d2638c29 113 function(D,A,B,C, 8, 9);
toddouska 0:5045d2638c29 114 function(C,D,A,B, 4,11);
toddouska 0:5045d2638c29 115 function(B,C,D,A,12,15);
toddouska 0:5045d2638c29 116 function(A,B,C,D, 2, 3);
toddouska 0:5045d2638c29 117 function(D,A,B,C,10, 9);
toddouska 0:5045d2638c29 118 function(C,D,A,B, 6,11);
toddouska 0:5045d2638c29 119 function(B,C,D,A,14,15);
toddouska 0:5045d2638c29 120 function(A,B,C,D, 1, 3);
toddouska 0:5045d2638c29 121 function(D,A,B,C, 9, 9);
toddouska 0:5045d2638c29 122 function(C,D,A,B, 5,11);
toddouska 0:5045d2638c29 123 function(B,C,D,A,13,15);
toddouska 0:5045d2638c29 124 function(A,B,C,D, 3, 3);
toddouska 0:5045d2638c29 125 function(D,A,B,C,11, 9);
toddouska 0:5045d2638c29 126 function(C,D,A,B, 7,11);
toddouska 0:5045d2638c29 127 function(B,C,D,A,15,15);
toddouska 0:5045d2638c29 128
toddouska 0:5045d2638c29 129 /* Add the working vars back into digest state[] */
toddouska 0:5045d2638c29 130 md4->digest[0] += A;
toddouska 0:5045d2638c29 131 md4->digest[1] += B;
toddouska 0:5045d2638c29 132 md4->digest[2] += C;
toddouska 0:5045d2638c29 133 md4->digest[3] += D;
toddouska 0:5045d2638c29 134 }
toddouska 0:5045d2638c29 135
toddouska 0:5045d2638c29 136
toddouska 0:5045d2638c29 137 static INLINE void AddLength(Md4* md4, word32 len)
toddouska 0:5045d2638c29 138 {
toddouska 0:5045d2638c29 139 word32 tmp = md4->loLen;
toddouska 0:5045d2638c29 140 if ( (md4->loLen += len) < tmp)
toddouska 0:5045d2638c29 141 md4->hiLen++; /* carry low to high */
toddouska 0:5045d2638c29 142 }
toddouska 0:5045d2638c29 143
toddouska 0:5045d2638c29 144
toddouska 0:5045d2638c29 145 void Md4Update(Md4* md4, const byte* data, word32 len)
toddouska 0:5045d2638c29 146 {
toddouska 0:5045d2638c29 147 /* do block size increments */
toddouska 0:5045d2638c29 148 byte* local = (byte*)md4->buffer;
toddouska 0:5045d2638c29 149
toddouska 0:5045d2638c29 150 while (len) {
toddouska 0:5045d2638c29 151 word32 add = min(len, MD4_BLOCK_SIZE - md4->buffLen);
toddouska 0:5045d2638c29 152 XMEMCPY(&local[md4->buffLen], data, add);
toddouska 0:5045d2638c29 153
toddouska 0:5045d2638c29 154 md4->buffLen += add;
toddouska 0:5045d2638c29 155 data += add;
toddouska 0:5045d2638c29 156 len -= add;
toddouska 0:5045d2638c29 157
toddouska 0:5045d2638c29 158 if (md4->buffLen == MD4_BLOCK_SIZE) {
toddouska 0:5045d2638c29 159 #ifdef BIG_ENDIAN_ORDER
toddouska 0:5045d2638c29 160 ByteReverseBytes(local, local, MD4_BLOCK_SIZE);
toddouska 0:5045d2638c29 161 #endif
toddouska 0:5045d2638c29 162 Transform(md4);
toddouska 0:5045d2638c29 163 AddLength(md4, MD4_BLOCK_SIZE);
toddouska 0:5045d2638c29 164 md4->buffLen = 0;
toddouska 0:5045d2638c29 165 }
toddouska 0:5045d2638c29 166 }
toddouska 0:5045d2638c29 167 }
toddouska 0:5045d2638c29 168
toddouska 0:5045d2638c29 169
toddouska 0:5045d2638c29 170 void Md4Final(Md4* md4, byte* hash)
toddouska 0:5045d2638c29 171 {
toddouska 0:5045d2638c29 172 byte* local = (byte*)md4->buffer;
toddouska 0:5045d2638c29 173
toddouska 0:5045d2638c29 174 AddLength(md4, md4->buffLen); /* before adding pads */
toddouska 0:5045d2638c29 175
toddouska 0:5045d2638c29 176 local[md4->buffLen++] = 0x80; /* add 1 */
toddouska 0:5045d2638c29 177
toddouska 0:5045d2638c29 178 /* pad with zeros */
toddouska 0:5045d2638c29 179 if (md4->buffLen > MD4_PAD_SIZE) {
toddouska 0:5045d2638c29 180 XMEMSET(&local[md4->buffLen], 0, MD4_BLOCK_SIZE - md4->buffLen);
toddouska 0:5045d2638c29 181 md4->buffLen += MD4_BLOCK_SIZE - md4->buffLen;
toddouska 0:5045d2638c29 182
toddouska 0:5045d2638c29 183 #ifdef BIG_ENDIAN_ORDER
toddouska 0:5045d2638c29 184 ByteReverseBytes(local, local, MD4_BLOCK_SIZE);
toddouska 0:5045d2638c29 185 #endif
toddouska 0:5045d2638c29 186 Transform(md4);
toddouska 0:5045d2638c29 187 md4->buffLen = 0;
toddouska 0:5045d2638c29 188 }
toddouska 0:5045d2638c29 189 XMEMSET(&local[md4->buffLen], 0, MD4_PAD_SIZE - md4->buffLen);
toddouska 0:5045d2638c29 190
toddouska 0:5045d2638c29 191 /* put lengths in bits */
toddouska 0:5045d2638c29 192 md4->loLen = md4->loLen << 3;
toddouska 0:5045d2638c29 193 md4->hiLen = (md4->loLen >> (8*sizeof(md4->loLen) - 3)) +
toddouska 0:5045d2638c29 194 (md4->hiLen << 3);
toddouska 0:5045d2638c29 195
toddouska 0:5045d2638c29 196 /* store lengths */
toddouska 0:5045d2638c29 197 #ifdef BIG_ENDIAN_ORDER
toddouska 0:5045d2638c29 198 ByteReverseBytes(local, local, MD4_BLOCK_SIZE);
toddouska 0:5045d2638c29 199 #endif
toddouska 0:5045d2638c29 200 /* ! length ordering dependent on digest endian type ! */
toddouska 0:5045d2638c29 201 XMEMCPY(&local[MD4_PAD_SIZE], &md4->loLen, sizeof(word32));
toddouska 0:5045d2638c29 202 XMEMCPY(&local[MD4_PAD_SIZE + sizeof(word32)], &md4->hiLen, sizeof(word32));
toddouska 0:5045d2638c29 203
toddouska 0:5045d2638c29 204 Transform(md4);
toddouska 0:5045d2638c29 205 #ifdef BIG_ENDIAN_ORDER
toddouska 0:5045d2638c29 206 ByteReverseWords(md4->digest, md4->digest, MD4_DIGEST_SIZE);
toddouska 0:5045d2638c29 207 #endif
toddouska 0:5045d2638c29 208 XMEMCPY(hash, md4->digest, MD4_DIGEST_SIZE);
toddouska 0:5045d2638c29 209
toddouska 0:5045d2638c29 210 InitMd4(md4); /* reset state */
toddouska 0:5045d2638c29 211 }
toddouska 0:5045d2638c29 212
toddouska 0:5045d2638c29 213
toddouska 0:5045d2638c29 214 #endif /* NO_MD4 */
toddouska 0:5045d2638c29 215