summaryrefslogtreecommitdiff
path: root/release/src/router/matrixssl/src/crypto/peersec/sha1.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2015-01-03 13:58:15 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2015-01-03 13:58:15 +0100
commit4aca87515a5083ae0e31ce3177189fd43b6d05ac (patch)
tree7b1d9a31393ca090757dc6f0d3859b4fcd93f271 /release/src/router/matrixssl/src/crypto/peersec/sha1.c
parent008d0be72b2f160382c6e880765e96b64a050c65 (diff)
downloadtomato-4aca87515a5083ae0e31ce3177189fd43b6d05ac.tar.gz
tomato-4aca87515a5083ae0e31ce3177189fd43b6d05ac.tar.bz2
patch to Vanilla Tomato 1.28
Diffstat (limited to 'release/src/router/matrixssl/src/crypto/peersec/sha1.c')
-rw-r--r--release/src/router/matrixssl/src/crypto/peersec/sha1.c317
1 files changed, 317 insertions, 0 deletions
diff --git a/release/src/router/matrixssl/src/crypto/peersec/sha1.c b/release/src/router/matrixssl/src/crypto/peersec/sha1.c
new file mode 100644
index 00000000..7a92654f
--- /dev/null
+++ b/release/src/router/matrixssl/src/crypto/peersec/sha1.c
@@ -0,0 +1,317 @@
+/*
+ * sha1.c
+ * Release $Name: MATRIXSSL_1_8_8_OPEN $
+ *
+ * SHA1 hash implementation
+ */
+/*
+ * Copyright (c) PeerSec Networks, 2002-2009. All Rights Reserved.
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from PeerSec Networks
+ * at http://www.peersec.com
+ *
+ * This program is distributed in 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#include "../cryptoLayer.h"
+
+#define F0(x,y,z) (z ^ (x & (y ^ z)))
+#define F1(x,y,z) (x ^ y ^ z)
+#define F2(x,y,z) ((x & y) | (z & (x | y)))
+#define F3(x,y,z) (x ^ y ^ z)
+
+#ifdef CLEAN_STACK
+static void _sha1_compress(hash_state *md)
+#else
+static void sha1_compress(hash_state *md)
+#endif /* CLEAN STACK */
+{
+ unsigned long a,b,c,d,e,W[80],i;
+#ifdef SMALL_CODE
+ ulong32 t;
+#endif
+
+ sslAssert(md != NULL);
+
+/*
+ copy the state into 512-bits into W[0..15]
+ */
+ for (i = 0; i < 16; i++) {
+ LOAD32H(W[i], md->sha1.buf + (4*i));
+ }
+
+/*
+ copy state
+ */
+ a = md->sha1.state[0];
+ b = md->sha1.state[1];
+ c = md->sha1.state[2];
+ d = md->sha1.state[3];
+ e = md->sha1.state[4];
+
+/*
+ expand it
+ */
+ for (i = 16; i < 80; i++) {
+ W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
+ }
+
+/*
+ compress
+ */
+ /* round one */
+ #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
+ #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
+ #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
+ #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
+
+#ifdef SMALL_CODE
+ for (i = 0; i < 20; ) {
+ FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+
+ for (; i < 40; ) {
+ FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+
+ for (; i < 60; ) {
+ FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+
+ for (; i < 80; ) {
+ FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+#else /* SMALL_CODE */
+ for (i = 0; i < 20; ) {
+ FF0(a,b,c,d,e,i++);
+ FF0(e,a,b,c,d,i++);
+ FF0(d,e,a,b,c,i++);
+ FF0(c,d,e,a,b,i++);
+ FF0(b,c,d,e,a,i++);
+ }
+
+ /* round two */
+ for (; i < 40; ) {
+ FF1(a,b,c,d,e,i++);
+ FF1(e,a,b,c,d,i++);
+ FF1(d,e,a,b,c,i++);
+ FF1(c,d,e,a,b,i++);
+ FF1(b,c,d,e,a,i++);
+ }
+
+ /* round three */
+ for (; i < 60; ) {
+ FF2(a,b,c,d,e,i++);
+ FF2(e,a,b,c,d,i++);
+ FF2(d,e,a,b,c,i++);
+ FF2(c,d,e,a,b,i++);
+ FF2(b,c,d,e,a,i++);
+ }
+
+ /* round four */
+ for (; i < 80; ) {
+ FF3(a,b,c,d,e,i++);
+ FF3(e,a,b,c,d,i++);
+ FF3(d,e,a,b,c,i++);
+ FF3(c,d,e,a,b,i++);
+ FF3(b,c,d,e,a,i++);
+ }
+#endif /* SMALL_CODE */
+
+ #undef FF0
+ #undef FF1
+ #undef FF2
+ #undef FF3
+
+/*
+ store
+ */
+ md->sha1.state[0] = md->sha1.state[0] + a;
+ md->sha1.state[1] = md->sha1.state[1] + b;
+ md->sha1.state[2] = md->sha1.state[2] + c;
+ md->sha1.state[3] = md->sha1.state[3] + d;
+ md->sha1.state[4] = md->sha1.state[4] + e;
+}
+
+#ifdef CLEAN_STACK
+static void sha1_compress(hash_state *md)
+{
+ _sha1_compress(md);
+ psBurnStack(sizeof(unsigned long) * 87);
+}
+#endif /* CLEAN_STACK */
+
+void matrixSha1Init(hash_state * md)
+{
+ sslAssert(md != NULL);
+ md->sha1.state[0] = 0x67452301UL;
+ md->sha1.state[1] = 0xefcdab89UL;
+ md->sha1.state[2] = 0x98badcfeUL;
+ md->sha1.state[3] = 0x10325476UL;
+ md->sha1.state[4] = 0xc3d2e1f0UL;
+ md->sha1.curlen = 0;
+#ifdef USE_INT64
+ md->sha1.length = 0;
+#else
+ md->sha1.lengthHi = 0;
+ md->sha1.lengthLo = 0;
+#endif /* USE_INT64 */
+}
+
+void matrixSha1Update(hash_state * md, const unsigned char *buf, unsigned long len)
+{
+ unsigned long n;
+
+ sslAssert(md != NULL);
+ sslAssert(buf != NULL);
+ while (len > 0) {
+ n = MIN(len, (64 - md->sha1.curlen));
+ memcpy(md->sha1.buf + md->sha1.curlen, buf, (size_t)n);
+ md->sha1.curlen += n;
+ buf += n;
+ len -= n;
+
+ /* is 64 bytes full? */
+ if (md->sha1.curlen == 64) {
+ sha1_compress(md);
+#ifdef USE_INT64
+ md->sha1.length += 512;
+#else
+ n = (md->sha1.lengthLo + 512) & 0xFFFFFFFFL;
+ if (n < md->sha1.lengthLo) {
+ md->sha1.lengthHi++;
+ }
+ md->sha1.lengthLo = n;
+#endif /* USE_INT64 */
+ md->sha1.curlen = 0;
+ }
+ }
+}
+
+int32 matrixSha1Final(hash_state * md, unsigned char *hash)
+{
+ int32 i;
+#ifndef USE_INT64
+ unsigned long n;
+#endif
+ sslAssert(md != NULL);
+ if (md->sha1.curlen >= sizeof(md->sha1.buf) || hash == NULL) {
+ return -1;
+ }
+
+/*
+ increase the length of the message
+ */
+#ifdef USE_INT64
+ md->sha1.length += md->sha1.curlen << 3;
+#else
+ n = (md->sha1.lengthLo + (md->sha1.curlen << 3)) & 0xFFFFFFFFL;
+ if (n < md->sha1.lengthLo) {
+ md->sha1.lengthHi++;
+ }
+ md->sha1.lengthHi += (md->sha1.curlen >> 29);
+ md->sha1.lengthLo = n;
+#endif /* USE_INT64 */
+
+/*
+ append the '1' bit
+ */
+ md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
+
+/*
+ if the length is currently above 56 bytes we append zeros then compress.
+ Then we can fall back to padding zeros and length encoding like normal.
+ */
+ if (md->sha1.curlen > 56) {
+ while (md->sha1.curlen < 64) {
+ md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
+ }
+ sha1_compress(md);
+ md->sha1.curlen = 0;
+ }
+
+/*
+ pad upto 56 bytes of zeroes
+ */
+ while (md->sha1.curlen < 56) {
+ md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
+ }
+
+/*
+ store length
+ */
+#ifdef USE_INT64
+ STORE64H(md->sha1.length, md->sha1.buf+56);
+#else
+ STORE32H(md->sha1.lengthHi, md->sha1.buf+56);
+ STORE32H(md->sha1.lengthLo, md->sha1.buf+60);
+#endif /* USE_INT64 */
+ sha1_compress(md);
+
+/*
+ copy output
+ */
+ for (i = 0; i < 5; i++) {
+ STORE32H(md->sha1.state[i], hash+(4*i));
+ }
+#ifdef CLEAN_STACK
+ psZeromem(md, sizeof(hash_state));
+#endif /* CLEAN_STACK */
+ return 20;
+}
+
+#ifdef PEERSEC_TEST
+
+int32 matrixSha1Test()
+{
+ static const struct {
+ char *msg;
+ unsigned char hash[20];
+ } tests[] = {
+ { "abc",
+ { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
+ 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
+ 0x9c, 0xd0, 0xd8, 0x9d }
+ },
+ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
+ 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
+ 0xE5, 0x46, 0x70, 0xF1 }
+ }
+ };
+
+ int32 i;
+ unsigned char tmp[20];
+ hash_state md;
+
+ for (i = 0; i < (int32)(sizeof(tests) / sizeof(tests[0])); i++) {
+ matrixSha1Init(&md);
+ matrixSha1Update(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
+ matrixSha1Final(&md, tmp);
+ if (memcmp(tmp, tests[i].hash, 20) != 0) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ }
+ return CRYPT_OK;
+}
+#endif /* PEERSEC_TEST */
+
+
+/******************************************************************************/
+