ARM Shanghai IoT Team (Internal) / newMiniTLS-GPL

Fork of MiniTLS-GPL by Donatien Garnier

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers crypto_md5.c Source File

crypto_md5.c

Go to the documentation of this file.
00001 /*
00002 MiniTLS - A super trimmed down TLS/SSL Library for embedded devices
00003 Author: Donatien Garnier
00004 Copyright (C) 2013-2014 AppNearMe Ltd
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, write to the Free Software
00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019 *//**
00020  * \file crypto_md5.c
00021  * \copyright Copyright (c) AppNearMe Ltd 2014
00022  * \author Donatien Garnier
00023  */
00024 
00025 
00026 #define __DEBUG__ 0
00027 #define __MODULE__ "crypto_md5.c"
00028 
00029 //This module has been adapted from libtomcrypt (http://libtom.org/)
00030 
00031 #include "core/fwk.h"
00032 #include "crypto_md5.h"
00033 #include "inc/minitls_errors.h"
00034 #include "crypto_macros.h"
00035 
00036 #define fatal(x) do{ ERR("Fatal error %s - %d", #x, x); while(1); }while(0)
00037 
00038 static void crypto_md5_compress(crypto_md5_t* hash, unsigned char *buf);
00039 
00040 void crypto_md5_init(crypto_md5_t* hash)
00041 {
00042   hash->state[0] = 0x67452301UL;
00043   hash->state[1] = 0xefcdab89UL;
00044   hash->state[2] = 0x98badcfeUL;
00045   hash->state[3] = 0x10325476UL;
00046   hash->curlen = 0;
00047   hash->length = 0;
00048 }
00049 
00050 void crypto_md5_update(crypto_md5_t* hash, const uint8_t* data, size_t size)
00051 {
00052   unsigned long n;
00053 
00054   if ( hash->curlen > sizeof( hash->buf)) {
00055     fatal(CRYPTO_ERR_PARAMETERS);
00056   }
00057   while (size > 0) {
00058       if ( hash->curlen == 0 && size >= 64) {
00059          crypto_md5_compress(hash, (unsigned char *)data);
00060          hash->length += 64 * 8;
00061          data             += 64;
00062          size          -= 64;
00063       } else {
00064          n = ( ((size)<((64 -  hash->curlen)))?(size):((64 -  hash->curlen)) );
00065          memcpy( hash->buf + hash->curlen, data, (size_t)n);
00066          hash->curlen += n;
00067          data         += n;
00068          size         -= n;
00069          if ( hash->curlen == 64) {
00070              crypto_md5_compress (hash,  hash->buf);
00071              hash->length += 8*64;
00072              hash->curlen = 0;
00073          }
00074      }
00075   }
00076 }
00077 
00078 void crypto_md5_end(crypto_md5_t* hash, uint8_t* out)
00079 {
00080   int i;
00081 
00082   /* increase the length of the message */
00083   hash->length += hash->curlen * 8;
00084 
00085   /* append the '1' bit */
00086   hash->buf[hash->curlen++] = (unsigned char)0x80;
00087 
00088   /* if the length is currently above 56 bytes we append zeros
00089    * then compress.  Then we can fall back to padding zeros and length
00090    * encoding like normal.
00091    */
00092   if (hash->curlen > 56) {
00093       while (hash->curlen < 64) {
00094           hash->buf[hash->curlen++] = (unsigned char)0;
00095       }
00096       crypto_md5_compress(hash, hash->buf);
00097       hash->curlen = 0;
00098   }
00099 
00100   /* pad upto 56 bytes of zeroes */
00101   while (hash->curlen < 56) {
00102       hash->buf[hash->curlen++] = (unsigned char)0;
00103   }
00104 
00105   /* store length */
00106   STORE64L(hash->length, hash->buf+56);
00107   crypto_md5_compress(hash, hash->buf);
00108 
00109   /* copy output */
00110   for (i = 0; i < 4; i++) {
00111       STORE32L(hash->state[i], out+(4*i));
00112   }
00113 #ifdef LTC_CLEAN_STACK
00114   zeromem(md, sizeof(hash_state));
00115 #endif
00116 }
00117 
00118 void crypto_md5_copy(crypto_md5_t* hashTo, crypto_md5_t* hashFrom)
00119 {
00120   memcpy(hashTo, hashFrom, sizeof(crypto_md5_t));
00121 }
00122 
00123 
00124 #define F(x,y,z)  (z ^ (x & (y ^ z)))
00125 #define G(x,y,z)  (y ^ (z & (y ^ x)))
00126 #define H(x,y,z)  (x^y^z)
00127 #define I(x,y,z)  (y^(x|(~z)))
00128 
00129 #ifdef LTC_SMALL_CODE
00130 
00131 #define FF(a,b,c,d,M,s,t) \
00132     a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
00133 
00134 #define GG(a,b,c,d,M,s,t) \
00135     a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
00136 
00137 #define HH(a,b,c,d,M,s,t) \
00138     a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
00139 
00140 #define II(a,b,c,d,M,s,t) \
00141     a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
00142 
00143 static const unsigned char Worder[64] = {
00144    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
00145    1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
00146    5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
00147    0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
00148 };
00149 
00150 static const unsigned char Rorder[64] = {
00151    7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
00152    5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
00153    4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
00154    6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
00155 };
00156 
00157 static const ulong32 Korder[64] = {
00158 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
00159 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
00160 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
00161 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
00162 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
00163 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
00164 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
00165 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
00166 };
00167 
00168 #else
00169 
00170 #define FF(a,b,c,d,M,s,t) \
00171     a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
00172 
00173 #define GG(a,b,c,d,M,s,t) \
00174     a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
00175 
00176 #define HH(a,b,c,d,M,s,t) \
00177     a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
00178 
00179 #define II(a,b,c,d,M,s,t) \
00180     a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
00181 
00182 
00183 #endif
00184 
00185 void crypto_md5_compress(crypto_md5_t* hash, unsigned char *buf)
00186 {
00187   ulong32 i, W[16], a, b, c, d;
00188 #ifdef LTC_SMALL_CODE
00189   ulong32 t;
00190 #endif
00191 
00192   /* copy the state into 512-bits into W[0..15] */
00193   for (i = 0; i < 16; i++) {
00194       LOAD32L(W[i], buf + (4*i));
00195   }
00196 
00197   /* copy state */
00198   a = hash->state[0];
00199   b = hash->state[1];
00200   c = hash->state[2];
00201   d = hash->state[3];
00202 
00203 #ifdef LTC_SMALL_CODE
00204   for (i = 0; i < 16; ++i) {
00205       FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
00206       t = d; d = c; c = b; b = a; a = t;
00207   }
00208 
00209   for (; i < 32; ++i) {
00210       GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
00211       t = d; d = c; c = b; b = a; a = t;
00212   }
00213 
00214   for (; i < 48; ++i) {
00215       HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
00216       t = d; d = c; c = b; b = a; a = t;
00217   }
00218 
00219   for (; i < 64; ++i) {
00220       II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
00221       t = d; d = c; c = b; b = a; a = t;
00222   }
00223 
00224 #else
00225   FF(a,b,c,d,W[0],7,0xd76aa478UL)
00226   FF(d,a,b,c,W[1],12,0xe8c7b756UL)
00227   FF(c,d,a,b,W[2],17,0x242070dbUL)
00228   FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
00229   FF(a,b,c,d,W[4],7,0xf57c0fafUL)
00230   FF(d,a,b,c,W[5],12,0x4787c62aUL)
00231   FF(c,d,a,b,W[6],17,0xa8304613UL)
00232   FF(b,c,d,a,W[7],22,0xfd469501UL)
00233   FF(a,b,c,d,W[8],7,0x698098d8UL)
00234   FF(d,a,b,c,W[9],12,0x8b44f7afUL)
00235   FF(c,d,a,b,W[10],17,0xffff5bb1UL)
00236   FF(b,c,d,a,W[11],22,0x895cd7beUL)
00237   FF(a,b,c,d,W[12],7,0x6b901122UL)
00238   FF(d,a,b,c,W[13],12,0xfd987193UL)
00239   FF(c,d,a,b,W[14],17,0xa679438eUL)
00240   FF(b,c,d,a,W[15],22,0x49b40821UL)
00241   GG(a,b,c,d,W[1],5,0xf61e2562UL)
00242   GG(d,a,b,c,W[6],9,0xc040b340UL)
00243   GG(c,d,a,b,W[11],14,0x265e5a51UL)
00244   GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
00245   GG(a,b,c,d,W[5],5,0xd62f105dUL)
00246   GG(d,a,b,c,W[10],9,0x02441453UL)
00247   GG(c,d,a,b,W[15],14,0xd8a1e681UL)
00248   GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
00249   GG(a,b,c,d,W[9],5,0x21e1cde6UL)
00250   GG(d,a,b,c,W[14],9,0xc33707d6UL)
00251   GG(c,d,a,b,W[3],14,0xf4d50d87UL)
00252   GG(b,c,d,a,W[8],20,0x455a14edUL)
00253   GG(a,b,c,d,W[13],5,0xa9e3e905UL)
00254   GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
00255   GG(c,d,a,b,W[7],14,0x676f02d9UL)
00256   GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
00257   HH(a,b,c,d,W[5],4,0xfffa3942UL)
00258   HH(d,a,b,c,W[8],11,0x8771f681UL)
00259   HH(c,d,a,b,W[11],16,0x6d9d6122UL)
00260   HH(b,c,d,a,W[14],23,0xfde5380cUL)
00261   HH(a,b,c,d,W[1],4,0xa4beea44UL)
00262   HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
00263   HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
00264   HH(b,c,d,a,W[10],23,0xbebfbc70UL)
00265   HH(a,b,c,d,W[13],4,0x289b7ec6UL)
00266   HH(d,a,b,c,W[0],11,0xeaa127faUL)
00267   HH(c,d,a,b,W[3],16,0xd4ef3085UL)
00268   HH(b,c,d,a,W[6],23,0x04881d05UL)
00269   HH(a,b,c,d,W[9],4,0xd9d4d039UL)
00270   HH(d,a,b,c,W[12],11,0xe6db99e5UL)
00271   HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
00272   HH(b,c,d,a,W[2],23,0xc4ac5665UL)
00273   II(a,b,c,d,W[0],6,0xf4292244UL)
00274   II(d,a,b,c,W[7],10,0x432aff97UL)
00275   II(c,d,a,b,W[14],15,0xab9423a7UL)
00276   II(b,c,d,a,W[5],21,0xfc93a039UL)
00277   II(a,b,c,d,W[12],6,0x655b59c3UL)
00278   II(d,a,b,c,W[3],10,0x8f0ccc92UL)
00279   II(c,d,a,b,W[10],15,0xffeff47dUL)
00280   II(b,c,d,a,W[1],21,0x85845dd1UL)
00281   II(a,b,c,d,W[8],6,0x6fa87e4fUL)
00282   II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
00283   II(c,d,a,b,W[6],15,0xa3014314UL)
00284   II(b,c,d,a,W[13],21,0x4e0811a1UL)
00285   II(a,b,c,d,W[4],6,0xf7537e82UL)
00286   II(d,a,b,c,W[11],10,0xbd3af235UL)
00287   II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
00288   II(b,c,d,a,W[9],21,0xeb86d391UL)
00289 #endif
00290 
00291   hash->state[0] = hash->state[0] + a;
00292   hash->state[1] = hash->state[1] + b;
00293   hash->state[2] = hash->state[2] + c;
00294   hash->state[3] = hash->state[3] + d;
00295 }