?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. // hashplay framework
  2. // (c) 2019 lvd^mhm
  3.  
  4. /*
  5.     This file is part of hashplay framework.
  6.  
  7.     hashplay framework is free software:
  8.     you can redistribute it and/or modify it under the terms of
  9.     the GNU General Public License as published by
  10.     the Free Software Foundation, either version 3 of the License, or
  11.     (at your option) any later version.
  12.  
  13.     hashplay framework is distributed in the hope that
  14.     it will be useful, but WITHOUT ANY WARRANTY; without even
  15.     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16.     See the GNU General Public License for more details.
  17.  
  18.     You should have received a copy of the GNU General Public License
  19.     along with hashplay framework.
  20.     If not, see <http://www.gnu.org/licenses/>.
  21. */
  22.  
  23. #include <stdint.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <assert.h>
  28.  
  29. #include "hash-common.h"
  30. #include "md5-my.h"
  31.  
  32.  
  33. struct my_md5
  34. {
  35.         uint64_t pos;
  36.  
  37.         uint8_t buf[64];
  38.  
  39.         uint32_t state[4];
  40. };
  41.  
  42.  
  43.  
  44. static const uint32_t a0 = 0x67452301;
  45. static const uint32_t b0 = 0xefcdab89;
  46. static const uint32_t c0 = 0x98badcfe;
  47. static const uint32_t d0 = 0x10325476;
  48.  
  49.  
  50. static inline void md5_compress( const uint32_t * m, uint32_t * state )
  51. {
  52.  
  53. #define F(b,c,d) ( ( (b) & (c) ) | ( (~(b)) & (d) ) )
  54. #define G(b,c,d) ( ( (b) & (d))  | ( (c) & (~(d)) ) )
  55. #define H(b,c,d) ( (b) ^ (c) ^ (d) )
  56. #define I(b,c,d) ( (c) ^ ( (b) | (~(d)) ) )
  57.  
  58. #define ROL(x,n) ( ( (x)<<(n) ) | ( (x)>>(32-(n)) ) )
  59.  
  60. #define ROUND_1(a,b,c,d,msg,add,shift)     \
  61.         do {                               \
  62.                 a += F(b,c,d) + msg + add; \
  63.                 a = ROL(a,shift);          \
  64.                 a += b;                    \
  65.         } while(0)
  66.  
  67. #define ROUND_2(a,b,c,d,msg,add,shift)     \
  68.         do {                               \
  69.                 a += G(b,c,d) + msg + add; \
  70.                 a = ROL(a,shift);          \
  71.                 a += b;                    \
  72.         } while(0)
  73.  
  74. #define ROUND_3(a,b,c,d,msg,add,shift)     \
  75.         do {                               \
  76.                 a += H(b,c,d) + msg + add; \
  77.                 a = ROL(a,shift);          \
  78.                 a += b;                    \
  79.         } while(0)
  80.  
  81. #define ROUND_4(a,b,c,d,msg,add,shift)     \
  82.         do {                               \
  83.                 a += I(b,c,d) + msg + add; \
  84.                 a = ROL(a,shift);          \
  85.                 a += b;                    \
  86.         } while(0)
  87.  
  88.  
  89.  
  90.         uint32_t A = state[0];
  91.         uint32_t B = state[1];
  92.         uint32_t C = state[2];
  93.         uint32_t D = state[3];
  94.  
  95.  
  96.         ROUND_1(A,B,C,D, m[ 0], 0xd76aa478,  7);
  97.         ROUND_1(D,A,B,C, m[ 1], 0xe8c7b756, 12);
  98.         ROUND_1(C,D,A,B, m[ 2], 0x242070db, 17);
  99.         ROUND_1(B,C,D,A, m[ 3], 0xc1bdceee, 22);
  100.         ROUND_1(A,B,C,D, m[ 4], 0xf57c0faf,  7);
  101.         ROUND_1(D,A,B,C, m[ 5], 0x4787c62a, 12);
  102.         ROUND_1(C,D,A,B, m[ 6], 0xa8304613, 17);
  103.         ROUND_1(B,C,D,A, m[ 7], 0xfd469501, 22);
  104.         ROUND_1(A,B,C,D, m[ 8], 0x698098d8,  7);
  105.         ROUND_1(D,A,B,C, m[ 9], 0x8b44f7af, 12);
  106.         ROUND_1(C,D,A,B, m[10], 0xffff5bb1, 17);
  107.         ROUND_1(B,C,D,A, m[11], 0x895cd7be, 22);
  108.         ROUND_1(A,B,C,D, m[12], 0x6b901122,  7);
  109.         ROUND_1(D,A,B,C, m[13], 0xfd987193, 12);
  110.         ROUND_1(C,D,A,B, m[14], 0xa679438e, 17);
  111.         ROUND_1(B,C,D,A, m[15], 0x49b40821, 22);
  112.  
  113.         ROUND_2(A,B,C,D, m[ 1], 0xf61e2562,  5);
  114.         ROUND_2(D,A,B,C, m[ 6], 0xc040b340,  9);
  115.         ROUND_2(C,D,A,B, m[11], 0x265e5a51, 14);
  116.         ROUND_2(B,C,D,A, m[ 0], 0xe9b6c7aa, 20);
  117.         ROUND_2(A,B,C,D, m[ 5], 0xd62f105d,  5);
  118.         ROUND_2(D,A,B,C, m[10], 0x02441453,  9);
  119.         ROUND_2(C,D,A,B, m[15], 0xd8a1e681, 14);
  120.         ROUND_2(B,C,D,A, m[ 4], 0xe7d3fbc8, 20);
  121.         ROUND_2(A,B,C,D, m[ 9], 0x21e1cde6,  5);
  122.         ROUND_2(D,A,B,C, m[14], 0xc33707d6,  9);
  123.         ROUND_2(C,D,A,B, m[ 3], 0xf4d50d87, 14);
  124.         ROUND_2(B,C,D,A, m[ 8], 0x455a14ed, 20);
  125.         ROUND_2(A,B,C,D, m[13], 0xa9e3e905,  5);
  126.         ROUND_2(D,A,B,C, m[ 2], 0xfcefa3f8,  9);
  127.         ROUND_2(C,D,A,B, m[ 7], 0x676f02d9, 14);
  128.         ROUND_2(B,C,D,A, m[12], 0x8d2a4c8a, 20);
  129.  
  130.         ROUND_3(A,B,C,D, m[ 5], 0xfffa3942,  4);
  131.         ROUND_3(D,A,B,C, m[ 8], 0x8771f681, 11);
  132.         ROUND_3(C,D,A,B, m[11], 0x6d9d6122, 16);
  133.         ROUND_3(B,C,D,A, m[14], 0xfde5380c, 23);
  134.         ROUND_3(A,B,C,D, m[ 1], 0xa4beea44,  4);
  135.         ROUND_3(D,A,B,C, m[ 4], 0x4bdecfa9, 11);
  136.         ROUND_3(C,D,A,B, m[ 7], 0xf6bb4b60, 16);
  137.         ROUND_3(B,C,D,A, m[10], 0xbebfbc70, 23);
  138.         ROUND_3(A,B,C,D, m[13], 0x289b7ec6,  4);
  139.         ROUND_3(D,A,B,C, m[ 0], 0xeaa127fa, 11);
  140.         ROUND_3(C,D,A,B, m[ 3], 0xd4ef3085, 16);
  141.         ROUND_3(B,C,D,A, m[ 6], 0x04881d05, 23);
  142.         ROUND_3(A,B,C,D, m[ 9], 0xd9d4d039,  4);
  143.         ROUND_3(D,A,B,C, m[12], 0xe6db99e5, 11);
  144.         ROUND_3(C,D,A,B, m[15], 0x1fa27cf8, 16);
  145.         ROUND_3(B,C,D,A, m[ 2], 0xc4ac5665, 23);
  146.        
  147.         ROUND_4(A,B,C,D, m[ 0], 0xf4292244,  6);
  148.         ROUND_4(D,A,B,C, m[ 7], 0x432aff97, 10);
  149.         ROUND_4(C,D,A,B, m[14], 0xab9423a7, 15);
  150.         ROUND_4(B,C,D,A, m[ 5], 0xfc93a039, 21);
  151.         ROUND_4(A,B,C,D, m[12], 0x655b59c3,  6);
  152.         ROUND_4(D,A,B,C, m[ 3], 0x8f0ccc92, 10);
  153.         ROUND_4(C,D,A,B, m[10], 0xffeff47d, 15);
  154.         ROUND_4(B,C,D,A, m[ 1], 0x85845dd1, 21);
  155.         ROUND_4(A,B,C,D, m[ 8], 0x6fa87e4f,  6);
  156.         ROUND_4(D,A,B,C, m[15], 0xfe2ce6e0, 10);
  157.         ROUND_4(C,D,A,B, m[ 6], 0xa3014314, 15);
  158.         ROUND_4(B,C,D,A, m[13], 0x4e0811a1, 21);
  159.         ROUND_4(A,B,C,D, m[ 4], 0xf7537e82,  6);
  160.         ROUND_4(D,A,B,C, m[11], 0xbd3af235, 10);
  161.         ROUND_4(C,D,A,B, m[ 2], 0x2ad7d2bb, 15);
  162.         ROUND_4(B,C,D,A, m[ 9], 0xeb86d391, 21);
  163.  
  164.         state[0] += A;
  165.         state[1] += B;
  166.         state[2] += C;
  167.         state[3] += D;
  168. }
  169.  
  170. static inline size_t my_min(size_t a, size_t b)
  171. {
  172.         if( a<=b ) return a; else return b;
  173. }
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183. struct hash_iface * make_md5_my(void)
  184. {
  185.         static const char name[]="my MD5";
  186.  
  187.         struct hash_iface * hash = malloc(sizeof(struct hash_iface));
  188.         if( !hash )
  189.         {
  190.                 fprintf(stderr,"%s: %d, %s: can't allocate memory for hash_iface!\n",__FILE__,__LINE__,__func__);
  191.                 exit(1);
  192.         }
  193.  
  194.         hash->hash_specific_data = NULL;
  195.  
  196.         hash->name = name;
  197.  
  198.         hash->hash_init     = &md5_my_hash_init;
  199.         hash->hash_start    = &md5_my_hash_start;
  200.         hash->hash_addbytes = &md5_my_hash_addbytes;
  201.         hash->hash_getsize  = &md5_my_hash_getsize;
  202.         hash->hash_result   = &md5_my_hash_result;
  203.         hash->hash_deinit   = &md5_my_hash_deinit;
  204.  
  205.         return hash;
  206. }
  207.  
  208.  
  209. int    md5_my_hash_init    (struct hash_iface * hash)
  210. {
  211.         struct my_md5 * md5 = (struct my_md5 *)malloc(sizeof(struct my_md5));
  212.        
  213.         if( !md5 )
  214.         {
  215.                 fprintf(stderr,"%s: %d, %s: can't allocate memory for struct my_md5!\n",__FILE__,__LINE__,__func__);
  216.                 exit(1);
  217.         }
  218.  
  219.         hash->hash_specific_data = (void *)md5;
  220.  
  221.         return 1;
  222. }
  223.  
  224. int    md5_my_hash_start   (struct hash_iface * hash)
  225. {
  226.         struct my_md5 * md5 = (struct my_md5 *)hash->hash_specific_data;
  227.        
  228.         if( !md5 )
  229.         {
  230.                 fprintf(stderr,"%s: %d, %s: hash_specific_data was NULL!\n",__FILE__,__LINE__,__func__);
  231.                 exit(1);
  232.         }
  233.  
  234.         md5->pos = 0;
  235.  
  236.         for(int i=0;i<64;i++)
  237.                 md5->buf[i] = 0;
  238.  
  239.         md5->state[0] = a0;
  240.         md5->state[1] = b0;
  241.         md5->state[2] = c0;
  242.         md5->state[3] = d0;
  243.  
  244.         return 1;
  245. }
  246.  
  247. int    md5_my_hash_addbytes(struct hash_iface * hash, const uint8_t * message, size_t size)
  248. {
  249.         struct my_md5 * md5 = (struct my_md5 *)hash->hash_specific_data;
  250.        
  251.         if( !md5 )
  252.         {
  253.                 fprintf(stderr,"%s: %d, %s: hash_specific_data was NULL!\n",__FILE__,__LINE__,__func__);
  254.                 exit(1);
  255.         }
  256.  
  257.         const uint8_t * ptr = message;
  258.         size_t remaining_size = size;
  259.  
  260.  
  261.         while( remaining_size > 0 )
  262.         {
  263.                 // aligned 64-bytes shortcut
  264.                 if( !(md5->pos & 63) && remaining_size >= 64 )
  265.                 {
  266.                         md5_compress( (const uint32_t *)ptr, md5->state );
  267.  
  268.                         md5->pos += 64;
  269.                         ptr += 64;
  270.                         remaining_size -= 64;
  271.  
  272.                         continue;
  273.                 }
  274.  
  275.                 // otherwise fill buffer and perform MD5 update on it
  276.                 size_t size_to_add = my_min( (64-(md5->pos & 63)), remaining_size );
  277.  
  278.                 do
  279.                 {
  280.                         md5->buf[md5->pos & 63] = *ptr;
  281.  
  282.                         ptr++;
  283.                         md5->pos++;
  284.                         remaining_size--;
  285.  
  286.                 } while( (--size_to_add) );
  287.  
  288.                 if( !(md5->pos & 63) )
  289.                         md5_compress( (const uint32_t *)md5->buf, md5->state );
  290.         }
  291.  
  292.         return 1;
  293. }
  294.  
  295. size_t md5_my_hash_getsize (struct hash_iface * hash)
  296. {
  297.         return 16;
  298. }
  299.  
  300. int    md5_my_hash_result  (struct hash_iface * hash, uint8_t * result)
  301. {
  302.         struct my_md5 * md5 = (struct my_md5 *)hash->hash_specific_data;
  303.        
  304.         if( !md5 )
  305.         {
  306.                 fprintf(stderr,"%s: %d, %s: hash_specific_data was NULL!\n",__FILE__,__LINE__,__func__);
  307.                 exit(1);
  308.         }
  309.  
  310.         // make padding
  311.        
  312.         uint64_t bits_hashed = md5->pos * 8;
  313.  
  314.         uint8_t padding[64+8];
  315.  
  316.         for(int i=0;i<64;i++)
  317.                 padding[i]=0;
  318.        
  319.         *(uint64_t *)(&padding[64]) = bits_hashed;
  320.  
  321.  
  322.         int num_pad_bytes = 56 - (md5->pos & 63);
  323.  
  324.         if( num_pad_bytes<=0 ) num_pad_bytes+= 64;
  325.  
  326.         padding[64-num_pad_bytes] = 0x80;
  327.  
  328.         md5_my_hash_addbytes(hash, &padding[64-num_pad_bytes], 8+num_pad_bytes);
  329.  
  330.         assert( !(md5->pos & 63) );
  331.  
  332.  
  333.         memcpy(result,md5->state,16);
  334.  
  335.         return 1;
  336. }
  337.  
  338.  
  339. void   md5_my_hash_deinit  (struct hash_iface * hash)
  340. {
  341.         struct my_md5 * md5 = (struct my_md5 *)hash->hash_specific_data;
  342.        
  343.         if( !md5 )
  344.         {
  345.                 fprintf(stderr,"%s: %d, %s: hash_specific_data was NULL!\n",__FILE__,__LINE__,__func__);
  346.                 exit(1);
  347.         }
  348.  
  349.         free(md5);
  350.        
  351.         hash->hash_specific_data = NULL;
  352. }
  353.  
  354.