Adjust memory layout for 2.6.22+ kernels with 32KB setup code
[mknbi.git] / md5.c
1 #ifdef  PASSWD
2
3 /*
4  * This is an implementation of the "MD5 Message Digest Algorithm" as
5  * described in
6  *   Bruce Schneier 'Applied Cryptography', pages 436-441, 2nd Edition, 1996,
7  *     John Wiley & Sons, Inc., ISBN 0-471-11709-9.
8  * The MD5 algorithm has been invented by Ron Rivest/"RSA Data Security, Inc.";
9  * Bruce Schneier refers to RFC1321 as the original publication.
10  *
11  * This implementation is copyright 1997 by M. Gutschke.
12  *
13  * This implementation has been optimized for size rather than for speed;
14  * there are a few assumptions that require a little-endian architecture.
15  * The maximum input length is 4GB.
16  */
17
18 #include "stddef.h"
19 #include "string.h"
20 #include "etherboot.h"
21
22 static unsigned long md5_buf[16];
23 static unsigned long ABCD[4]={0x67452301L,0xefcdab89L,0x98badcfeL,0x10325476L};
24 static unsigned long md5_len = 0;
25
26 static unsigned long F(unsigned long X,unsigned long Y,unsigned long Z)
27 { return((X&Y)|((~X)&Z)); }
28
29 static unsigned long G(unsigned long X,unsigned long Y,unsigned long Z)
30 { return((X&Z)|(Y&(~Z))); }
31
32 static unsigned long H(unsigned long X,unsigned long Y,unsigned long Z)
33 { return(X^Y^Z); }
34
35 static unsigned long I(unsigned long X,unsigned long Y,unsigned long Z)
36 { return(Y^(X|(~Z))); }
37
38 static inline unsigned long rotate(unsigned long i,int s)
39 { return((i << s) | (i >> (32-s))); }
40
41 static unsigned long ff(unsigned long (*fnc)(unsigned long,unsigned long,
42                                              unsigned long),
43                         unsigned long a,unsigned long b,unsigned long c,
44                         unsigned long d,unsigned long M,int s,
45                         unsigned long t)
46 { return(b+(rotate((a+fnc(b,c,d)+M+t),s))); }
47
48 static void md5_loop(void)
49 {
50   static unsigned char shifts[4][4] = {
51     {22,17,12,7},{20,14,9,5},{23,16,11,4},{21,15,10,6}};
52   static unsigned char idx[64] = {
53     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
54     1, 6,11, 0, 5,10,15, 4, 9,14, 3, 8,13, 2, 7,12,
55     5, 8,11,14, 1, 4, 7,10,13, 0, 3, 6, 9,12,15, 2,
56     0, 7,14, 5,12, 3,10, 1, 8,15, 6,13, 4,11, 2, 9 };
57   static unsigned long masks[64] = {
58     0xd76aa478L,0xe8c7b756L,0x242070dbL,0xc1bdceeeL,
59     0xf57c0fafL,0x4787c62aL,0xa8304613L,0xfd469501L,
60     0x698098d8L,0x8b44f7afL,0xffff5bb1L,0x895cd7beL,
61     0x6b901122L,0xfd987193L,0xa679438eL,0x49b40821L,
62     0xf61e2562L,0xc040b340L,0x265e5a51L,0xe9b6c7aaL,
63     0xd62f105dL,0x02441453L,0xd8a1e681L,0xe7d3fbc8L,
64     0x21e1cde6L,0xc33707d6L,0xf4d50d87L,0x455a14edL,
65     0xa9e3e905L,0xfcefa3f8L,0x676f02d9L,0x8d2a4c8aL,
66     0xfffa3942L,0x8771f681L,0x6d9d6122L,0xfde5380cL,
67     0xa4beea44L,0x4bdecfa9L,0xf6bb4b60L,0xbebfbc70L,
68     0x289b7ec6L,0xeaa127faL,0xd4ef3085L,0x04881d05L,
69     0xd9d4d039L,0xe6db99e5L,0x1fa27cf8L,0xc4ac5665L,
70     0xf4292244L,0x432aff97L,0xab9423a7L,0xfc93a039L,
71     0x655b59c3L,0x8f0ccc92L,0xffeff47dL,0x85845dd1L,
72     0x6fa87e4fL,0xfe2ce6e0L,0xa3014314L,0x4e0811a1L,
73     0xf7537e82L,0xbd3af235L,0x2ad7d2bbL,0xeb86d391L};
74
75   static unsigned long (*fncs[4])(unsigned long,unsigned long,
76                                   unsigned long) = { F,G,H,I };
77   int i,j,k,l;
78   unsigned long abcd[4];
79
80   memcpy(abcd, ABCD, 16);
81   for (i = j = 0; j < 4; j++)    /* rounds FF..II    */
82     for (k = 0; k < 4; k++)      /* 0..3             */
83       for (l = 4; l--; i++)      /* a,b,c,d..b,c,d,a */
84         abcd[(l+1)&3] = ff(fncs[j],
85                            abcd[(l+1)&3],abcd[(l+2)&3],abcd[(l+3)&3],abcd[l],
86                            md5_buf[idx[i]],shifts[j][l],masks[i]);
87   for (i = 4; i--; )
88     ABCD[i] += abcd[i];
89   return;
90 }
91
92 void md5_put(unsigned int ch)
93 {
94   /* this code assumes a little endian architecture! */
95   ((unsigned char *)md5_buf)[md5_len%64] = ch;
96   if (((++md5_len)%64) == 0)
97     md5_loop();
98   return;
99 }
100
101 void md5_done(unsigned char *buf)
102 {
103   unsigned long len = md5_len;
104   int           i;
105
106   /* this code assumes a little endian architecture! */
107   md5_put(0x80);
108   while ((md5_len%64) != 56)
109     md5_put(0);
110   md5_put(len <<  3); md5_put(len >>  5);
111   md5_put(len >> 13); md5_put(len >> 21);
112   for (i = 4; i--; )
113     md5_put(0);
114   memcpy(buf, ABCD, 16);
115   md5_len = 0;
116   {static unsigned long init[4]={
117     0x67452301L,0xefcdab89L,0x98badcfeL,0x10325476L};
118   memcpy(ABCD, init, 16); }
119   return;
120 }
121
122 #endif