Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
md4.c
00001 /* md4.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfssl/wolfcrypt/settings.h> 00028 00029 #ifndef NO_MD4 00030 00031 #include <wolfssl/wolfcrypt/md4.h> 00032 #ifdef NO_INLINE 00033 #include <wolfssl/wolfcrypt/misc.h> 00034 #else 00035 #include <wolfcrypt/src/misc.c> 00036 #endif 00037 00038 00039 #ifndef WOLFSSL_HAVE_MIN 00040 #define WOLFSSL_HAVE_MIN 00041 00042 static INLINE word32 min(word32 a, word32 b) 00043 { 00044 return a > b ? b : a; 00045 } 00046 00047 #endif /* WOLFSSL_HAVE_MIN */ 00048 00049 00050 void wc_InitMd4(Md4* md4) 00051 { 00052 md4->digest[0] = 0x67452301L; 00053 md4->digest[1] = 0xefcdab89L; 00054 md4->digest[2] = 0x98badcfeL; 00055 md4->digest[3] = 0x10325476L; 00056 00057 md4->buffLen = 0; 00058 md4->loLen = 0; 00059 md4->hiLen = 0; 00060 } 00061 00062 00063 static void Transform(Md4* md4) 00064 { 00065 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 00066 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 00067 #define H(x, y, z) ((x) ^ (y) ^ (z)) 00068 00069 /* Copy context->state[] to working vars */ 00070 word32 A = md4->digest[0]; 00071 word32 B = md4->digest[1]; 00072 word32 C = md4->digest[2]; 00073 word32 D = md4->digest[3]; 00074 00075 #define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+md4->buffer[k],s); 00076 function(A,B,C,D, 0, 3); 00077 function(D,A,B,C, 1, 7); 00078 function(C,D,A,B, 2,11); 00079 function(B,C,D,A, 3,19); 00080 function(A,B,C,D, 4, 3); 00081 function(D,A,B,C, 5, 7); 00082 function(C,D,A,B, 6,11); 00083 function(B,C,D,A, 7,19); 00084 function(A,B,C,D, 8, 3); 00085 function(D,A,B,C, 9, 7); 00086 function(C,D,A,B,10,11); 00087 function(B,C,D,A,11,19); 00088 function(A,B,C,D,12, 3); 00089 function(D,A,B,C,13, 7); 00090 function(C,D,A,B,14,11); 00091 function(B,C,D,A,15,19); 00092 00093 #undef function 00094 #define function(a,b,c,d,k,s) \ 00095 a=rotlFixed(a+G(b,c,d)+md4->buffer[k]+0x5a827999,s); 00096 00097 function(A,B,C,D, 0, 3); 00098 function(D,A,B,C, 4, 5); 00099 function(C,D,A,B, 8, 9); 00100 function(B,C,D,A,12,13); 00101 function(A,B,C,D, 1, 3); 00102 function(D,A,B,C, 5, 5); 00103 function(C,D,A,B, 9, 9); 00104 function(B,C,D,A,13,13); 00105 function(A,B,C,D, 2, 3); 00106 function(D,A,B,C, 6, 5); 00107 function(C,D,A,B,10, 9); 00108 function(B,C,D,A,14,13); 00109 function(A,B,C,D, 3, 3); 00110 function(D,A,B,C, 7, 5); 00111 function(C,D,A,B,11, 9); 00112 function(B,C,D,A,15,13); 00113 00114 #undef function 00115 #define function(a,b,c,d,k,s) \ 00116 a=rotlFixed(a+H(b,c,d)+md4->buffer[k]+0x6ed9eba1,s); 00117 00118 function(A,B,C,D, 0, 3); 00119 function(D,A,B,C, 8, 9); 00120 function(C,D,A,B, 4,11); 00121 function(B,C,D,A,12,15); 00122 function(A,B,C,D, 2, 3); 00123 function(D,A,B,C,10, 9); 00124 function(C,D,A,B, 6,11); 00125 function(B,C,D,A,14,15); 00126 function(A,B,C,D, 1, 3); 00127 function(D,A,B,C, 9, 9); 00128 function(C,D,A,B, 5,11); 00129 function(B,C,D,A,13,15); 00130 function(A,B,C,D, 3, 3); 00131 function(D,A,B,C,11, 9); 00132 function(C,D,A,B, 7,11); 00133 function(B,C,D,A,15,15); 00134 00135 /* Add the working vars back into digest state[] */ 00136 md4->digest[0] += A; 00137 md4->digest[1] += B; 00138 md4->digest[2] += C; 00139 md4->digest[3] += D; 00140 } 00141 00142 00143 static INLINE void AddLength(Md4* md4, word32 len) 00144 { 00145 word32 tmp = md4->loLen; 00146 if ( (md4->loLen += len) < tmp) 00147 md4->hiLen++; /* carry low to high */ 00148 } 00149 00150 00151 void wc_Md4Update(Md4* md4, const byte* data, word32 len) 00152 { 00153 /* do block size increments */ 00154 byte* local = (byte*)md4->buffer; 00155 00156 while (len) { 00157 word32 add = min(len, MD4_BLOCK_SIZE - md4->buffLen); 00158 XMEMCPY(&local[md4->buffLen], data, add); 00159 00160 md4->buffLen += add; 00161 data += add; 00162 len -= add; 00163 00164 if (md4->buffLen == MD4_BLOCK_SIZE) { 00165 #ifdef BIG_ENDIAN_ORDER 00166 ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE); 00167 #endif 00168 Transform(md4); 00169 AddLength(md4, MD4_BLOCK_SIZE); 00170 md4->buffLen = 0; 00171 } 00172 } 00173 } 00174 00175 00176 void wc_Md4Final(Md4* md4, byte* hash) 00177 { 00178 byte* local = (byte*)md4->buffer; 00179 00180 AddLength(md4, md4->buffLen); /* before adding pads */ 00181 00182 local[md4->buffLen++] = 0x80; /* add 1 */ 00183 00184 /* pad with zeros */ 00185 if (md4->buffLen > MD4_PAD_SIZE) { 00186 XMEMSET(&local[md4->buffLen], 0, MD4_BLOCK_SIZE - md4->buffLen); 00187 md4->buffLen += MD4_BLOCK_SIZE - md4->buffLen; 00188 00189 #ifdef BIG_ENDIAN_ORDER 00190 ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE); 00191 #endif 00192 Transform(md4); 00193 md4->buffLen = 0; 00194 } 00195 XMEMSET(&local[md4->buffLen], 0, MD4_PAD_SIZE - md4->buffLen); 00196 00197 /* put lengths in bits */ 00198 md4->hiLen = (md4->loLen >> (8*sizeof(md4->loLen) - 3)) + 00199 (md4->hiLen << 3); 00200 md4->loLen = md4->loLen << 3; 00201 00202 /* store lengths */ 00203 #ifdef BIG_ENDIAN_ORDER 00204 ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE); 00205 #endif 00206 /* ! length ordering dependent on digest endian type ! */ 00207 XMEMCPY(&local[MD4_PAD_SIZE], &md4->loLen, sizeof(word32)); 00208 XMEMCPY(&local[MD4_PAD_SIZE + sizeof(word32)], &md4->hiLen, sizeof(word32)); 00209 00210 Transform(md4); 00211 #ifdef BIG_ENDIAN_ORDER 00212 ByteReverseWords(md4->digest, md4->digest, MD4_DIGEST_SIZE); 00213 #endif 00214 XMEMCPY(hash, md4->digest, MD4_DIGEST_SIZE); 00215 00216 wc_InitMd4(md4); /* reset state */ 00217 } 00218 00219 00220 #endif /* NO_MD4 */ 00221 00222
Generated on Tue Jul 12 2022 15:55:20 by
1.7.2