patch-2.4.23 linux-2.4.23/net/sctp/sla1.c
Next file: linux-2.4.23/net/sctp/sm_make_chunk.c
Previous file: linux-2.4.23/net/sctp/protocol.c
Back to the patch index
Back to the overall index
- Lines: 282
- Date:
2003-11-28 10:26:21.000000000 -0800
- Orig file:
linux-2.4.22/net/sctp/sla1.c
- Orig date:
1969-12-31 16:00:00.000000000 -0800
diff -urN linux-2.4.22/net/sctp/sla1.c linux-2.4.23/net/sctp/sla1.c
@@ -0,0 +1,281 @@
+/* SCTP kernel reference Implementation
+ * Copyright (c) 1999-2000 Cisco, Inc.
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ *
+ * This file is part of the SCTP kernel reference Implementation
+ *
+ * (It's really SHA-1 but Hey I was tired when I created this
+ * file, and on a plane to France :-)
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ * Randall Stewart <rstewar1@email.mot.com>
+ * kmorneau@cisco.com
+ * qxie1@email.mot.com
+ *
+ * Based on:
+ * Randy Stewart, et al. SCTP Reference Implementation which is licenced
+ * under the GPL.
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fcntl.h>
+#include <asm/string.h> /* for memcpy */
+#include <linux/sched.h> /* dead chicken for in.h */
+#include <linux/in.h> /* for htonl and ntohl */
+
+#include <net/sctp/sla1.h>
+
+void SLA1_Init(struct SLA_1_Context *ctx)
+{
+ /* Init the SLA-1 context structure. */
+ ctx->A = 0;
+ ctx->B = 0;
+ ctx->C = 0;
+ ctx->D = 0;
+ ctx->E = 0;
+ ctx->H0 = H0INIT;
+ ctx->H1 = H1INIT;
+ ctx->H2 = H2INIT;
+ ctx->H3 = H3INIT;
+ ctx->H4 = H4INIT;
+ ctx->TEMP = 0;
+ memset(ctx->words, 0, sizeof(ctx->words));
+ ctx->howManyInBlock = 0;
+ ctx->runningTotal = 0;
+}
+
+void SLA1processABlock(struct SLA_1_Context *ctx,unsigned int *block)
+{
+ int i;
+ /* init the W0-W15 to the block of words being
+ * hashed.
+ */
+ /* step a) */
+
+ for (i = 0; i < 16; i++)
+ ctx->words[i] = ntohl(block[i]);
+
+ /* now init the rest based on the SLA-1 formula, step b) */
+ for (i = 16; i < 80; i++)
+ ctx->words[i] =
+ CSHIFT(1, ((ctx->words[(i-3)]) ^
+ (ctx->words[(i-8)]) ^
+ (ctx->words[(i-14)]) ^
+ (ctx->words[(i-16)])));
+
+ /* step c) */
+ ctx->A = ctx->H0;
+ ctx->B = ctx->H1;
+ ctx->C = ctx->H2;
+ ctx->D = ctx->H3;
+ ctx->E = ctx->H4;
+
+ /* step d) */
+ for (i = 0; i < 80; i++) {
+ if (i < 20) {
+ ctx->TEMP = ((CSHIFT(5, ctx->A)) +
+ (F1(ctx->B, ctx->C, ctx->D)) +
+ (ctx->E) +
+ ctx->words[i] +
+ K1
+ );
+ } else if (i < 40) {
+ ctx->TEMP = ((CSHIFT(5, ctx->A)) +
+ (F2(ctx->B, ctx->C, ctx->D)) +
+ (ctx->E) +
+ (ctx->words[i]) +
+ K2
+ );
+ } else if (i < 60) {
+ ctx->TEMP = ((CSHIFT(5, ctx->A)) +
+ (F3(ctx->B, ctx->C, ctx->D)) +
+ (ctx->E) +
+ (ctx->words[i]) +
+ K3
+ );
+ } else {
+ ctx->TEMP = ((CSHIFT(5, ctx->A)) +
+ (F4(ctx->B, ctx->C, ctx->D)) +
+ (ctx->E) +
+ (ctx->words[i]) +
+ K4
+ );
+ }
+ ctx->E = ctx->D;
+ ctx->D = ctx->C;
+ ctx->C = CSHIFT(30, ctx->B);
+ ctx->B = ctx->A;
+ ctx->A = ctx->TEMP;
+ }
+
+ /* step e) */
+ ctx->H0 = (ctx->H0) + (ctx->A);
+ ctx->H1 = (ctx->H1) + (ctx->B);
+ ctx->H2 = (ctx->H2) + (ctx->C);
+ ctx->H3 = (ctx->H3) + (ctx->D);
+ ctx->H4 = (ctx->H4) + (ctx->E);
+}
+
+void SLA1_Process(struct SLA_1_Context *ctx, const unsigned char *ptr, int siz)
+{
+ int numberLeft, leftToFill;
+
+ numberLeft = siz;
+ while (numberLeft > 0) {
+ leftToFill = sizeof(ctx->SLAblock) - ctx->howManyInBlock;
+ if (leftToFill > numberLeft) {
+ /* can only partially fill up this one */
+ memcpy(&ctx->SLAblock[ctx->howManyInBlock],
+ ptr, numberLeft);
+ ctx->howManyInBlock += siz;
+ ctx->runningTotal += siz;
+ break;
+ } else {
+ /* block is now full, process it */
+ memcpy(&ctx->SLAblock[ctx->howManyInBlock],
+ ptr, leftToFill);
+ SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
+ numberLeft -= leftToFill;
+ ctx->runningTotal += leftToFill;
+ ctx->howManyInBlock = 0;
+ }
+ }
+}
+
+void SLA1_Final(struct SLA_1_Context *ctx, unsigned char *digestBuf)
+{
+ /* if any left in block fill with padding
+ * and process. Then transfer the digest to
+ * the pointer. At the last block some special
+ * rules need to apply. We must add a 1 bit
+ * following the message, then we pad with
+ * 0's. The total size is encoded as a 64 bit
+ * number at the end. Now if the last buffer has
+ * more than 55 octets in it we cannot fit
+ * the 64 bit number + 10000000 pad on the end
+ * and must add the 10000000 pad, pad the rest
+ * of the message with 0's and then create a
+ * all 0 message with just the 64 bit size
+ * at the end and run this block through by itself.
+ * Also the 64 bit int must be in network byte
+ * order.
+ */
+ int i, leftToFill;
+ unsigned int *ptr;
+
+ if (ctx->howManyInBlock > 55) {
+ /* special case, we need to process two
+ * blocks here. One for the current stuff
+ * plus possibly the pad. The other for
+ * the size.
+ */
+ leftToFill = sizeof(ctx->SLAblock) - ctx->howManyInBlock;
+ if (leftToFill == 0) {
+ /* Should not really happen but I am paranoid */
+ /* Not paranoid enough! It is possible for leftToFill
+ * to become negative! AAA!!!! This is another reason
+ * to pick MD5 :-)...
+ */
+ SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
+ /* init last block, a bit different then the rest :-) */
+ ctx->SLAblock[0] = 0x80;
+ for (i = 1; i < sizeof(ctx->SLAblock); i++) {
+ ctx->SLAblock[i] = 0x0;
+ }
+ } else if (leftToFill == 1) {
+ ctx->SLAblock[ctx->howManyInBlock] = 0x80;
+ SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
+ /* init last block */
+ memset(ctx->SLAblock, 0, sizeof(ctx->SLAblock));
+ } else {
+ ctx->SLAblock[ctx->howManyInBlock] = 0x80;
+ for (i = (ctx->howManyInBlock + 1);
+ i < sizeof(ctx->SLAblock);
+ i++) {
+ ctx->SLAblock[i] = 0x0;
+ }
+ SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
+ /* init last block */
+ memset(ctx->SLAblock, 0, sizeof(ctx->SLAblock));
+ }
+ /* This is in bits so multiply by 8 */
+ ctx->runningTotal *= 8;
+ ptr = (unsigned int *) &ctx->SLAblock[60];
+ *ptr = htonl(ctx->runningTotal);
+ SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
+ } else {
+ /* easy case, we just pad this
+ * message to size - end with 0
+ * add the magic 0x80 to the next
+ * word and then put the network byte
+ * order size in the last spot and
+ * process the block.
+ */
+ ctx->SLAblock[ctx->howManyInBlock] = 0x80;
+ for (i = (ctx->howManyInBlock + 1);
+ i < sizeof(ctx->SLAblock);
+ i++) {
+ ctx->SLAblock[i] = 0x0;
+ }
+ /* get last int spot */
+ ctx->runningTotal *= 8;
+ ptr = (unsigned int *) &ctx->SLAblock[60];
+ *ptr = htonl(ctx->runningTotal);
+ SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock);
+ }
+ /* Now at this point all we need do is transfer the
+ * digest back to the user
+ */
+ digestBuf[3] = (ctx->H0 & 0xff);
+ digestBuf[2] = ((ctx->H0 >> 8) & 0xff);
+ digestBuf[1] = ((ctx->H0 >> 16) & 0xff);
+ digestBuf[0] = ((ctx->H0 >> 24) & 0xff);
+
+ digestBuf[7] = (ctx->H1 & 0xff);
+ digestBuf[6] = ((ctx->H1 >> 8) & 0xff);
+ digestBuf[5] = ((ctx->H1 >> 16) & 0xff);
+ digestBuf[4] = ((ctx->H1 >> 24) & 0xff);
+
+ digestBuf[11] = (ctx->H2 & 0xff);
+ digestBuf[10] = ((ctx->H2 >> 8) & 0xff);
+ digestBuf[9] = ((ctx->H2 >> 16) & 0xff);
+ digestBuf[8] = ((ctx->H2 >> 24) & 0xff);
+
+ digestBuf[15] = (ctx->H3 & 0xff);
+ digestBuf[14] = ((ctx->H3 >> 8) & 0xff);
+ digestBuf[13] = ((ctx->H3 >> 16) & 0xff);
+ digestBuf[12] = ((ctx->H3 >> 24) & 0xff);
+
+ digestBuf[19] = (ctx->H4 & 0xff);
+ digestBuf[18] = ((ctx->H4 >> 8) & 0xff);
+ digestBuf[17] = ((ctx->H4 >> 16) & 0xff);
+ digestBuf[16] = ((ctx->H4 >> 24) & 0xff);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)