OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [sctp/] [sla1.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* SCTP kernel reference Implementation
2
 * Copyright (c) 1999-2000 Cisco, Inc.
3
 * Copyright (c) 1999-2001 Motorola, Inc.
4
 *
5
 * This file is part of the SCTP kernel reference Implementation
6
 *
7
 * (It's really SHA-1 but Hey I was tired when I created this
8
 * file, and on a plane to France :-)
9
 *
10
 * The SCTP reference implementation is free software;
11
 * you can redistribute it and/or modify it under the terms of
12
 * the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2, or (at your option)
14
 * any later version.
15
 *
16
 * The SCTP reference implementation is distributed in the hope that it
17
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
18
 *                 ************************
19
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20
 * See the GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with GNU CC; see the file COPYING.  If not, write to
24
 * the Free Software Foundation, 59 Temple Place - Suite 330,
25
 * Boston, MA 02111-1307, USA.
26
 *
27
 * Please send any bug reports or fixes you make to the
28
 * email address(es):
29
 *    lksctp developers <lksctp-developers@lists.sourceforge.net>
30
 *
31
 * Or submit a bug report through the following website:
32
 *    http://www.sf.net/projects/lksctp
33
 *
34
 * Written or modified by:
35
 *    Randall Stewart <rstewar1@email.mot.com>
36
 *    kmorneau@cisco.com
37
 *    qxie1@email.mot.com
38
 *
39
 * Based on:
40
 *    Randy Stewart, et al. SCTP Reference Implementation which is licenced
41
 *    under the GPL.
42
 *
43
 * Any bugs reported given to us we will try to fix... any fixes shared will
44
 * be incorporated into the next SCTP release.
45
 */
46
 
47
#include <linux/types.h>
48
#include <linux/kernel.h>
49
#include <linux/fcntl.h>
50
#include <asm/string.h>         /* for memcpy */
51
#include <linux/sched.h>        /* dead chicken for in.h */
52
#include <linux/in.h>           /* for htonl and ntohl */
53
 
54
#include <net/sctp/sla1.h>
55
 
56
void SLA1_Init(struct SLA_1_Context *ctx)
57
{
58
        /* Init the SLA-1 context structure.  */
59
        ctx->A = 0;
60
        ctx->B = 0;
61
        ctx->C = 0;
62
        ctx->D = 0;
63
        ctx->E = 0;
64
        ctx->H0 = H0INIT;
65
        ctx->H1 = H1INIT;
66
        ctx->H2 = H2INIT;
67
        ctx->H3 = H3INIT;
68
        ctx->H4 = H4INIT;
69
        ctx->TEMP = 0;
70
        memset(ctx->words, 0, sizeof(ctx->words));
71
        ctx->howManyInBlock = 0;
72
        ctx->runningTotal = 0;
73
}
74
 
75
void SLA1processABlock(struct SLA_1_Context *ctx,unsigned int *block)
76
{
77
        int i;
78
        /* init the W0-W15 to the block of words being
79
         * hashed.
80
         */
81
        /* step a) */
82
 
83
        for (i = 0; i < 16; i++)
84
                ctx->words[i] = ntohl(block[i]);
85
 
86
        /* now init the rest based on the SLA-1 formula, step b) */
87
        for (i = 16; i < 80; i++)
88
                ctx->words[i] =
89
                        CSHIFT(1, ((ctx->words[(i-3)]) ^
90
                                   (ctx->words[(i-8)]) ^
91
                                   (ctx->words[(i-14)]) ^
92
                                   (ctx->words[(i-16)])));
93
 
94
        /* step c) */
95
        ctx->A = ctx->H0;
96
        ctx->B = ctx->H1;
97
        ctx->C = ctx->H2;
98
        ctx->D = ctx->H3;
99
        ctx->E = ctx->H4;
100
 
101
        /* step d) */
102
        for (i = 0; i < 80; i++) {
103
                if (i < 20) {
104
                        ctx->TEMP = ((CSHIFT(5, ctx->A)) +
105
                                     (F1(ctx->B, ctx->C, ctx->D)) +
106
                                     (ctx->E) +
107
                                     ctx->words[i] +
108
                                     K1
109
                                );
110
                } else if (i < 40) {
111
                        ctx->TEMP = ((CSHIFT(5, ctx->A)) +
112
                                     (F2(ctx->B, ctx->C, ctx->D)) +
113
                                     (ctx->E) +
114
                                     (ctx->words[i]) +
115
                                     K2
116
                                );
117
                } else if (i < 60) {
118
                        ctx->TEMP = ((CSHIFT(5, ctx->A)) +
119
                                     (F3(ctx->B, ctx->C, ctx->D)) +
120
                                     (ctx->E) +
121
                                     (ctx->words[i]) +
122
                                     K3
123
                                );
124
                } else {
125
                        ctx->TEMP = ((CSHIFT(5, ctx->A)) +
126
                                     (F4(ctx->B, ctx->C, ctx->D)) +
127
                                     (ctx->E) +
128
                                     (ctx->words[i]) +
129
                                     K4
130
                                );
131
                }
132
                ctx->E = ctx->D;
133
                ctx->D = ctx->C;
134
                ctx->C = CSHIFT(30, ctx->B);
135
                ctx->B = ctx->A;
136
                ctx->A = ctx->TEMP;
137
        }
138
 
139
        /* step e) */
140
        ctx->H0 = (ctx->H0) + (ctx->A);
141
        ctx->H1 = (ctx->H1) + (ctx->B);
142
        ctx->H2 = (ctx->H2) + (ctx->C);
143
        ctx->H3 = (ctx->H3) + (ctx->D);
144
        ctx->H4 = (ctx->H4) + (ctx->E);
145
}
146
 
147
void SLA1_Process(struct SLA_1_Context *ctx, const unsigned char *ptr, int siz)
148
{
149
        int numberLeft, leftToFill;
150
 
151
        numberLeft = siz;
152
        while (numberLeft > 0) {
153
                leftToFill = sizeof(ctx->SLAblock) - ctx->howManyInBlock;
154
                if (leftToFill > numberLeft) {
155
                        /* can only partially fill up this one */
156
                        memcpy(&ctx->SLAblock[ctx->howManyInBlock],
157
                               ptr, numberLeft);
158
                        ctx->howManyInBlock += siz;
159
                        ctx->runningTotal += siz;
160
                        break;
161
                } else {
162
                        /* block is now full, process it */
163
                        memcpy(&ctx->SLAblock[ctx->howManyInBlock],
164
                               ptr, leftToFill);
165
                        SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
166
                        numberLeft -= leftToFill;
167
                        ctx->runningTotal += leftToFill;
168
                        ctx->howManyInBlock = 0;
169
                }
170
        }
171
}
172
 
173
void SLA1_Final(struct SLA_1_Context *ctx, unsigned char *digestBuf)
174
{
175
        /* if any left in block fill with padding
176
         * and process. Then transfer the digest to
177
         * the pointer. At the last block some special
178
         * rules need to apply. We must add a 1 bit
179
         * following the message, then we pad with
180
         * 0's. The total size is encoded as a 64 bit
181
         * number at the end. Now if the last buffer has
182
         * more than 55 octets in it we cannot fit
183
         * the 64 bit number + 10000000 pad on the end
184
         * and must add the 10000000 pad, pad the rest
185
         * of the message with 0's and then create a
186
         * all 0 message with just the 64 bit size
187
         * at the end and run this block through by itself.
188
         * Also the 64 bit int must be in network byte
189
         * order.
190
         */
191
        int i, leftToFill;
192
        unsigned int *ptr;
193
 
194
        if (ctx->howManyInBlock > 55) {
195
                /* special case, we need to process two
196
                 * blocks here. One for the current stuff
197
                 * plus possibly the pad. The other for
198
                 * the size.
199
                 */
200
                leftToFill = sizeof(ctx->SLAblock) - ctx->howManyInBlock;
201
                if (leftToFill == 0) {
202
                        /* Should not really happen but I am paranoid */
203
                        /* Not paranoid enough!  It is possible for leftToFill
204
                         * to become negative!  AAA!!!!  This is another reason
205
                         * to pick MD5 :-)...
206
                         */
207
                        SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
208
                        /* init last block, a bit different then the rest :-) */
209
                        ctx->SLAblock[0] = 0x80;
210
                        for (i = 1; i < sizeof(ctx->SLAblock); i++) {
211
                                ctx->SLAblock[i] = 0x0;
212
                        }
213
                } else if (leftToFill == 1) {
214
                        ctx->SLAblock[ctx->howManyInBlock] = 0x80;
215
                        SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
216
                        /* init last block */
217
                        memset(ctx->SLAblock, 0, sizeof(ctx->SLAblock));
218
                } else {
219
                        ctx->SLAblock[ctx->howManyInBlock] = 0x80;
220
                        for (i = (ctx->howManyInBlock + 1);
221
                             i < sizeof(ctx->SLAblock);
222
                             i++) {
223
                                ctx->SLAblock[i] = 0x0;
224
                        }
225
                        SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
226
                        /* init last block */
227
                        memset(ctx->SLAblock, 0, sizeof(ctx->SLAblock));
228
                }
229
                /* This is in bits so multiply by 8 */
230
                ctx->runningTotal *= 8;
231
                ptr = (unsigned int *) &ctx->SLAblock[60];
232
                *ptr = htonl(ctx->runningTotal);
233
                SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
234
        } else {
235
                /* easy case, we just pad this
236
                 * message to size - end with 0
237
                 * add the magic 0x80 to the next
238
                 * word and then put the network byte
239
                 * order size in the last spot and
240
                 * process the block.
241
                 */
242
                ctx->SLAblock[ctx->howManyInBlock] = 0x80;
243
                for (i = (ctx->howManyInBlock + 1);
244
                     i < sizeof(ctx->SLAblock);
245
                     i++) {
246
                        ctx->SLAblock[i] = 0x0;
247
                }
248
                /* get last int spot */
249
                ctx->runningTotal *= 8;
250
                ptr = (unsigned int *) &ctx->SLAblock[60];
251
                *ptr = htonl(ctx->runningTotal);
252
                SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
253
        }
254
        /* Now at this point all we need do is transfer the
255
         * digest back to the user
256
         */
257
        digestBuf[3] = (ctx->H0 & 0xff);
258
        digestBuf[2] = ((ctx->H0 >> 8) & 0xff);
259
        digestBuf[1] = ((ctx->H0 >> 16) & 0xff);
260
        digestBuf[0] = ((ctx->H0 >> 24) & 0xff);
261
 
262
        digestBuf[7] = (ctx->H1 & 0xff);
263
        digestBuf[6] = ((ctx->H1 >> 8) & 0xff);
264
        digestBuf[5] = ((ctx->H1 >> 16) & 0xff);
265
        digestBuf[4] = ((ctx->H1 >> 24) & 0xff);
266
 
267
        digestBuf[11] = (ctx->H2 & 0xff);
268
        digestBuf[10] = ((ctx->H2 >> 8) & 0xff);
269
        digestBuf[9] = ((ctx->H2 >> 16) & 0xff);
270
        digestBuf[8] = ((ctx->H2 >> 24) & 0xff);
271
 
272
        digestBuf[15] = (ctx->H3 & 0xff);
273
        digestBuf[14] = ((ctx->H3 >> 8) & 0xff);
274
        digestBuf[13] = ((ctx->H3 >> 16) & 0xff);
275
        digestBuf[12] = ((ctx->H3 >> 24) & 0xff);
276
 
277
        digestBuf[19] = (ctx->H4 & 0xff);
278
        digestBuf[18] = ((ctx->H4 >> 8) & 0xff);
279
        digestBuf[17] = ((ctx->H4 >> 16) & 0xff);
280
        digestBuf[16] = ((ctx->H4 >> 24) & 0xff);
281
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.