include upstream ip1000a driver version 2.09f
[linux-2.4.git] / net / sctp / hashdriver.c
1 /* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola
2  * 
3  * This file origiantes from Randy Stewart's SCTP reference Implementation.
4  * 
5  * The SCTP reference implementation is free software; 
6  * you can redistribute it and/or modify it under the terms of 
7  * the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  * 
11  * The SCTP reference implementation is distributed in the hope that it 
12  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13  *                 ************************
14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  * See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU CC; see the file COPYING.  If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.  
21  * 
22  * Please send any bug reports or fixes you make to the
23  * email address(es):
24  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
25  * 
26  * Or submit a bug report through the following website:
27  *    http://www.sf.net/projects/lksctp
28  *
29  * Written or modified by: 
30  *    Randy Stewart  rstewar1@email.mot.com
31  *    Ken Morneau    kmorneau@cisco.com
32  *    Qiaobing Xie   qxie1@email.mot.com
33  * 
34  * Any bugs reported given to us we will try to fix... any fixes shared will
35  * be incorperated into the next SCTP release.
36  * 
37  * There are still LOTS of bugs in this code... I always run on the motto
38  * "it is a wonder any code ever works :)"
39  */
40
41 #include <linux/types.h>
42 #include <asm/string.h>
43 #include <net/sctp/sctp.h>
44 #include <net/sctp/sla1.h>
45
46 /* SCTP Main driver.
47  * passing a two pointers and two lengths,
48  * returning a digest pointer filled. The md5 code
49  * was taken directly from the RFC (2104) so to understand it
50  * you may want to go look at the RFC referenced in the
51  * SCTP spec. We did modify this code to either user OUR
52  * implementation of SLA1 or the MD5 that comes from its
53  * RFC. SLA1 may have IPR issues so you need to check in
54  * to this if you wish to use it... Or at least that is
55  * what the FIP-180.1 web page says.
56  */
57
58 void sctp_hash_digest(const char *key, const int in_key_len,
59                       const char *text, const int text_len,
60                       __u8 *digest)
61 {
62         int key_len = in_key_len;
63         struct SLA_1_Context context;
64
65         __u8 k_ipad[65];        /* inner padding -
66                                  * key XORd with ipad
67                                  */
68         __u8 k_opad[65];        /* outer padding -
69                                  * key XORd with opad
70                                  */
71         __u8 tk[20];
72         int i;
73
74         /* if key is longer than 64 bytes reset it to key=MD5(key) */
75         if (key_len > 64) {
76                 struct SLA_1_Context tctx;
77
78                 SLA1_Init(&tctx);
79                 SLA1_Process(&tctx, key, key_len);
80                 SLA1_Final(&tctx,tk);
81                 key = tk;
82                 key_len = 20;
83         }
84
85         /*
86          * the HMAC_MD5 transform looks like:
87          *
88          * MD5(K XOR opad, MD5(K XOR ipad, text))
89          *
90          * where K is an n byte key
91          * ipad is the byte 0x36 repeated 64 times
92          * opad is the byte 0x5c repeated 64 times
93          * and text is the data being protected
94          */
95
96         /* start out by storing key in pads */
97         memset(k_ipad, 0, sizeof k_ipad);
98         memset(k_opad, 0, sizeof k_opad);
99         memcpy(k_ipad, key, key_len);
100         memcpy(k_opad, key, key_len);
101
102         /* XOR key with ipad and opad values */
103         for (i = 0; i < 64; i++) {
104                 k_ipad[i] ^= 0x36;
105                 k_opad[i] ^= 0x5c;
106         }
107
108         /* perform inner hash */
109         SLA1_Init(&context);                     /* init context for 1st
110                                                   * pass
111                                                   */
112         SLA1_Process(&context, k_ipad, 64);      /* start with inner pad */
113         SLA1_Process(&context, text, text_len);  /* then text of datagram */
114         SLA1_Final(&context,digest);             /* finish up 1st pass */
115
116         /*
117          * perform outer hash
118          */
119         SLA1_Init(&context);                   /* init context for 2nd
120                                                 * pass
121                                                 */
122         SLA1_Process(&context, k_opad, 64);     /* start with outer pad */
123         SLA1_Process(&context, digest, 20);     /* then results of 1st
124                                                  * hash
125                                                  */
126         SLA1_Final(&context, digest);          /* finish up 2nd pass */
127 }
128