root/lib/crypto/md4.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. F
  2. G
  3. H
  4. lshift
  5. mdfour64
  6. copy64
  7. copy4
  8. mdfour

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    a implementation of MD4 designed for use in the SMB authentication protocol
   4    Copyright (C) Andrew Tridgell 1997-1998.
   5    
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10    
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15    
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 #include "includes.h"
  21 #include "../lib/crypto/md4.h"
  22 
  23 /* NOTE: This code makes no attempt to be fast! 
  24 
  25    It assumes that a int is at least 32 bits long
  26 */
  27 
  28 struct mdfour_state {
  29         uint32_t A, B, C, D;
  30 };
  31 
  32 static uint32_t F(uint32_t X, uint32_t Y, uint32_t Z)
     /* [<][>][^][v][top][bottom][index][help] */
  33 {
  34         return (X&Y) | ((~X)&Z);
  35 }
  36 
  37 static uint32_t G(uint32_t X, uint32_t Y, uint32_t Z)
     /* [<][>][^][v][top][bottom][index][help] */
  38 {
  39         return (X&Y) | (X&Z) | (Y&Z); 
  40 }
  41 
  42 static uint32_t H(uint32_t X, uint32_t Y, uint32_t Z)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         return X^Y^Z;
  45 }
  46 
  47 static uint32_t lshift(uint32_t x, int s)
     /* [<][>][^][v][top][bottom][index][help] */
  48 {
  49         x &= 0xFFFFFFFF;
  50         return ((x<<s)&0xFFFFFFFF) | (x>>(32-s));
  51 }
  52 
  53 #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
  54 #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32_t)0x5A827999,s)
  55 #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32_t)0x6ED9EBA1,s)
  56 
  57 /* this applies md4 to 64 byte chunks */
  58 static void mdfour64(struct mdfour_state *s, uint32_t *M)
     /* [<][>][^][v][top][bottom][index][help] */
  59 {
  60         int j;
  61         uint32_t AA, BB, CC, DD;
  62         uint32_t X[16];
  63 
  64         for (j=0;j<16;j++)
  65                 X[j] = M[j];
  66 
  67         AA = s->A; BB = s->B; CC = s->C; DD = s->D;
  68 
  69         ROUND1(s->A,s->B,s->C,s->D,  0,  3);  ROUND1(s->D,s->A,s->B,s->C,  1,  7);  
  70         ROUND1(s->C,s->D,s->A,s->B,  2, 11);  ROUND1(s->B,s->C,s->D,s->A,  3, 19);
  71         ROUND1(s->A,s->B,s->C,s->D,  4,  3);  ROUND1(s->D,s->A,s->B,s->C,  5,  7);  
  72         ROUND1(s->C,s->D,s->A,s->B,  6, 11);  ROUND1(s->B,s->C,s->D,s->A,  7, 19);
  73         ROUND1(s->A,s->B,s->C,s->D,  8,  3);  ROUND1(s->D,s->A,s->B,s->C,  9,  7);  
  74         ROUND1(s->C,s->D,s->A,s->B, 10, 11);  ROUND1(s->B,s->C,s->D,s->A, 11, 19);
  75         ROUND1(s->A,s->B,s->C,s->D, 12,  3);  ROUND1(s->D,s->A,s->B,s->C, 13,  7);  
  76         ROUND1(s->C,s->D,s->A,s->B, 14, 11);  ROUND1(s->B,s->C,s->D,s->A, 15, 19);      
  77 
  78         ROUND2(s->A,s->B,s->C,s->D,  0,  3);  ROUND2(s->D,s->A,s->B,s->C,  4,  5);  
  79         ROUND2(s->C,s->D,s->A,s->B,  8,  9);  ROUND2(s->B,s->C,s->D,s->A, 12, 13);
  80         ROUND2(s->A,s->B,s->C,s->D,  1,  3);  ROUND2(s->D,s->A,s->B,s->C,  5,  5);  
  81         ROUND2(s->C,s->D,s->A,s->B,  9,  9);  ROUND2(s->B,s->C,s->D,s->A, 13, 13);
  82         ROUND2(s->A,s->B,s->C,s->D,  2,  3);  ROUND2(s->D,s->A,s->B,s->C,  6,  5);  
  83         ROUND2(s->C,s->D,s->A,s->B, 10,  9);  ROUND2(s->B,s->C,s->D,s->A, 14, 13);
  84         ROUND2(s->A,s->B,s->C,s->D,  3,  3);  ROUND2(s->D,s->A,s->B,s->C,  7,  5);  
  85         ROUND2(s->C,s->D,s->A,s->B, 11,  9);  ROUND2(s->B,s->C,s->D,s->A, 15, 13);
  86 
  87         ROUND3(s->A,s->B,s->C,s->D,  0,  3);  ROUND3(s->D,s->A,s->B,s->C,  8,  9);  
  88         ROUND3(s->C,s->D,s->A,s->B,  4, 11);  ROUND3(s->B,s->C,s->D,s->A, 12, 15);
  89         ROUND3(s->A,s->B,s->C,s->D,  2,  3);  ROUND3(s->D,s->A,s->B,s->C, 10,  9);  
  90         ROUND3(s->C,s->D,s->A,s->B,  6, 11);  ROUND3(s->B,s->C,s->D,s->A, 14, 15);
  91         ROUND3(s->A,s->B,s->C,s->D,  1,  3);  ROUND3(s->D,s->A,s->B,s->C,  9,  9);  
  92         ROUND3(s->C,s->D,s->A,s->B,  5, 11);  ROUND3(s->B,s->C,s->D,s->A, 13, 15);
  93         ROUND3(s->A,s->B,s->C,s->D,  3,  3);  ROUND3(s->D,s->A,s->B,s->C, 11,  9);  
  94         ROUND3(s->C,s->D,s->A,s->B,  7, 11);  ROUND3(s->B,s->C,s->D,s->A, 15, 15);
  95 
  96         s->A += AA; 
  97         s->B += BB; 
  98         s->C += CC; 
  99         s->D += DD;
 100         
 101         s->A &= 0xFFFFFFFF; 
 102         s->B &= 0xFFFFFFFF;
 103         s->C &= 0xFFFFFFFF; 
 104         s->D &= 0xFFFFFFFF;
 105 
 106         for (j=0;j<16;j++)
 107                 X[j] = 0;
 108 }
 109 
 110 static void copy64(uint32_t *M, const uint8_t *in)
     /* [<][>][^][v][top][bottom][index][help] */
 111 {
 112         int i;
 113 
 114         for (i=0;i<16;i++)
 115                 M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
 116                         (in[i*4+1]<<8) | (in[i*4+0]<<0);
 117 }
 118 
 119 static void copy4(uint8_t *out, uint32_t x)
     /* [<][>][^][v][top][bottom][index][help] */
 120 {
 121         out[0] = x&0xFF;
 122         out[1] = (x>>8)&0xFF;
 123         out[2] = (x>>16)&0xFF;
 124         out[3] = (x>>24)&0xFF;
 125 }
 126 
 127 /**
 128  * produce a md4 message digest from data of length n bytes 
 129  */
 130 _PUBLIC_ void mdfour(uint8_t *out, const uint8_t *in, int n)
     /* [<][>][^][v][top][bottom][index][help] */
 131 {
 132         uint8_t buf[128];
 133         uint32_t M[16];
 134         uint32_t b = n * 8;
 135         int i;
 136         struct mdfour_state state;
 137 
 138         state.A = 0x67452301;
 139         state.B = 0xefcdab89;
 140         state.C = 0x98badcfe;
 141         state.D = 0x10325476;
 142 
 143         while (n > 64) {
 144                 copy64(M, in);
 145                 mdfour64(&state, M);
 146                 in += 64;
 147                 n -= 64;
 148         }
 149 
 150         for (i=0;i<128;i++)
 151                 buf[i] = 0;
 152         memcpy(buf, in, n);
 153         buf[n] = 0x80;
 154         
 155         if (n <= 55) {
 156                 copy4(buf+56, b);
 157                 copy64(M, buf);
 158                 mdfour64(&state, M);
 159         } else {
 160                 copy4(buf+120, b); 
 161                 copy64(M, buf);
 162                 mdfour64(&state, M);
 163                 copy64(M, buf+64);
 164                 mdfour64(&state, M);
 165         }
 166 
 167         for (i=0;i<128;i++)
 168                 buf[i] = 0;
 169         copy64(M, buf);
 170 
 171         copy4(out, state.A);
 172         copy4(out+4, state.B);
 173         copy4(out+8, state.C);
 174         copy4(out+12, state.D);
 175 }
 176 
 177 

/* [<][>][^][v][top][bottom][index][help] */