Donatien Garnier / MiniTLS-GPL

Dependents:   MiniTLS-HTTPS-Example

Committer:
MiniTLS
Date:
Fri Jun 06 10:49:02 2014 +0000
Revision:
0:35aa5be3b78d
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MiniTLS 0:35aa5be3b78d 1 /*
MiniTLS 0:35aa5be3b78d 2 MuTLS - A super trimmed down TLS/SSL Library for embedded devices
MiniTLS 0:35aa5be3b78d 3 Author: Donatien Garnier
MiniTLS 0:35aa5be3b78d 4 Copyright (C) 2013-2014 AppNearMe Ltd
MiniTLS 0:35aa5be3b78d 5
MiniTLS 0:35aa5be3b78d 6 This program is free software; you can redistribute it and/or
MiniTLS 0:35aa5be3b78d 7 modify it under the terms of the GNU General Public License
MiniTLS 0:35aa5be3b78d 8 as published by the Free Software Foundation; either version 2
MiniTLS 0:35aa5be3b78d 9 of the License, or (at your option) any later version.
MiniTLS 0:35aa5be3b78d 10
MiniTLS 0:35aa5be3b78d 11 This program is distributed in the hope that it will be useful,
MiniTLS 0:35aa5be3b78d 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
MiniTLS 0:35aa5be3b78d 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MiniTLS 0:35aa5be3b78d 14 GNU General Public License for more details.
MiniTLS 0:35aa5be3b78d 15
MiniTLS 0:35aa5be3b78d 16 You should have received a copy of the GNU General Public License
MiniTLS 0:35aa5be3b78d 17 along with this program; if not, write to the Free Software
MiniTLS 0:35aa5be3b78d 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
MiniTLS 0:35aa5be3b78d 19 *//**
MiniTLS 0:35aa5be3b78d 20 * \file crypto_sha1.c
MiniTLS 0:35aa5be3b78d 21 * \copyright Copyright (c) AppNearMe Ltd 2013
MiniTLS 0:35aa5be3b78d 22 * \author Donatien Garnier
MiniTLS 0:35aa5be3b78d 23 */
MiniTLS 0:35aa5be3b78d 24
MiniTLS 0:35aa5be3b78d 25 #define __DEBUG__ 0
MiniTLS 0:35aa5be3b78d 26 #define __MODULE__ "crypto_sha1.c"
MiniTLS 0:35aa5be3b78d 27
MiniTLS 0:35aa5be3b78d 28 //This module has been adapted from libtomcrypt (http://libtom.org/)
MiniTLS 0:35aa5be3b78d 29
MiniTLS 0:35aa5be3b78d 30 #include "core/fwk.h"
MiniTLS 0:35aa5be3b78d 31 #include "crypto_sha1.h"
MiniTLS 0:35aa5be3b78d 32 #include "inc/mutls_errors.h"
MiniTLS 0:35aa5be3b78d 33 #include "crypto_macros.h"
MiniTLS 0:35aa5be3b78d 34
MiniTLS 0:35aa5be3b78d 35 #define fatal(x) do{ ERR("Fatal error %s - %d", #x, x); while(1); }while(0)
MiniTLS 0:35aa5be3b78d 36
MiniTLS 0:35aa5be3b78d 37 static void crypto_sha1_compress(crypto_sha1_t* hash, unsigned char *buf);
MiniTLS 0:35aa5be3b78d 38
MiniTLS 0:35aa5be3b78d 39 void crypto_sha1_init(crypto_sha1_t* hash)
MiniTLS 0:35aa5be3b78d 40 {
MiniTLS 0:35aa5be3b78d 41 hash->state[0] = 0x67452301UL;
MiniTLS 0:35aa5be3b78d 42 hash->state[1] = 0xefcdab89UL;
MiniTLS 0:35aa5be3b78d 43 hash->state[2] = 0x98badcfeUL;
MiniTLS 0:35aa5be3b78d 44 hash->state[3] = 0x10325476UL;
MiniTLS 0:35aa5be3b78d 45 hash->state[4] = 0xc3d2e1f0UL;
MiniTLS 0:35aa5be3b78d 46 hash->curlen = 0;
MiniTLS 0:35aa5be3b78d 47 hash->length = 0;
MiniTLS 0:35aa5be3b78d 48 }
MiniTLS 0:35aa5be3b78d 49
MiniTLS 0:35aa5be3b78d 50 void crypto_sha1_update(crypto_sha1_t* hash, const uint8_t* data, size_t size)
MiniTLS 0:35aa5be3b78d 51 {
MiniTLS 0:35aa5be3b78d 52 unsigned long n;
MiniTLS 0:35aa5be3b78d 53
MiniTLS 0:35aa5be3b78d 54 if ( hash->curlen > sizeof( hash->buf)) {
MiniTLS 0:35aa5be3b78d 55 fatal(CRYPTO_ERR_PARAMETERS);
MiniTLS 0:35aa5be3b78d 56 }
MiniTLS 0:35aa5be3b78d 57 while (size > 0) {
MiniTLS 0:35aa5be3b78d 58 if ( hash->curlen == 0 && size >= 64) {
MiniTLS 0:35aa5be3b78d 59 crypto_sha1_compress(hash, (unsigned char *)data);
MiniTLS 0:35aa5be3b78d 60 hash->length += 64 * 8;
MiniTLS 0:35aa5be3b78d 61 data += 64;
MiniTLS 0:35aa5be3b78d 62 size -= 64;
MiniTLS 0:35aa5be3b78d 63 } else {
MiniTLS 0:35aa5be3b78d 64 n = ( ((size)<((64 - hash->curlen)))?(size):((64 - hash->curlen)) );
MiniTLS 0:35aa5be3b78d 65 memcpy( hash->buf + hash->curlen, data, (size_t)n);
MiniTLS 0:35aa5be3b78d 66 hash->curlen += n;
MiniTLS 0:35aa5be3b78d 67 data += n;
MiniTLS 0:35aa5be3b78d 68 size -= n;
MiniTLS 0:35aa5be3b78d 69 if ( hash->curlen == 64) {
MiniTLS 0:35aa5be3b78d 70 crypto_sha1_compress (hash, hash->buf);
MiniTLS 0:35aa5be3b78d 71 hash->length += 8*64;
MiniTLS 0:35aa5be3b78d 72 hash->curlen = 0;
MiniTLS 0:35aa5be3b78d 73 }
MiniTLS 0:35aa5be3b78d 74 }
MiniTLS 0:35aa5be3b78d 75 }
MiniTLS 0:35aa5be3b78d 76 }
MiniTLS 0:35aa5be3b78d 77
MiniTLS 0:35aa5be3b78d 78 void crypto_sha1_end(crypto_sha1_t* hash, uint8_t* out)
MiniTLS 0:35aa5be3b78d 79 {
MiniTLS 0:35aa5be3b78d 80 int i;
MiniTLS 0:35aa5be3b78d 81
MiniTLS 0:35aa5be3b78d 82 if (hash->curlen >= sizeof(hash->buf)) {
MiniTLS 0:35aa5be3b78d 83 fatal(CRYPTO_ERR_PARAMETERS);
MiniTLS 0:35aa5be3b78d 84 }
MiniTLS 0:35aa5be3b78d 85
MiniTLS 0:35aa5be3b78d 86 /* increase the length of the message */
MiniTLS 0:35aa5be3b78d 87 hash->length += hash->curlen * 8;
MiniTLS 0:35aa5be3b78d 88
MiniTLS 0:35aa5be3b78d 89 /* append the '1' bit */
MiniTLS 0:35aa5be3b78d 90 hash->buf[hash->curlen++] = (unsigned char)0x80;
MiniTLS 0:35aa5be3b78d 91
MiniTLS 0:35aa5be3b78d 92 /* if the length is currently above 56 bytes we append zeros
MiniTLS 0:35aa5be3b78d 93 * then compress. Then we can fall back to padding zeros and length
MiniTLS 0:35aa5be3b78d 94 * encoding like normal.
MiniTLS 0:35aa5be3b78d 95 */
MiniTLS 0:35aa5be3b78d 96 if (hash->curlen > 56) {
MiniTLS 0:35aa5be3b78d 97 while (hash->curlen < 64) {
MiniTLS 0:35aa5be3b78d 98 hash->buf[hash->curlen++] = (unsigned char)0;
MiniTLS 0:35aa5be3b78d 99 }
MiniTLS 0:35aa5be3b78d 100 crypto_sha1_compress(hash, hash->buf);
MiniTLS 0:35aa5be3b78d 101 hash->curlen = 0;
MiniTLS 0:35aa5be3b78d 102 }
MiniTLS 0:35aa5be3b78d 103
MiniTLS 0:35aa5be3b78d 104 /* pad upto 56 bytes of zeroes */
MiniTLS 0:35aa5be3b78d 105 while (hash->curlen < 56) {
MiniTLS 0:35aa5be3b78d 106 hash->buf[hash->curlen++] = (unsigned char)0;
MiniTLS 0:35aa5be3b78d 107 }
MiniTLS 0:35aa5be3b78d 108
MiniTLS 0:35aa5be3b78d 109 /* store length */
MiniTLS 0:35aa5be3b78d 110 STORE64H(hash->length, hash->buf+56);
MiniTLS 0:35aa5be3b78d 111 crypto_sha1_compress(hash, hash->buf);
MiniTLS 0:35aa5be3b78d 112
MiniTLS 0:35aa5be3b78d 113 /* copy output */
MiniTLS 0:35aa5be3b78d 114 for (i = 0; i < 5; i++) {
MiniTLS 0:35aa5be3b78d 115 STORE32H(hash->state[i], out+(4*i));
MiniTLS 0:35aa5be3b78d 116 }
MiniTLS 0:35aa5be3b78d 117 #ifdef CRYPT_CLEAN_STACK
MiniTLS 0:35aa5be3b78d 118 zeromem(hash, sizeof(hash));
MiniTLS 0:35aa5be3b78d 119 #endif
MiniTLS 0:35aa5be3b78d 120 }
MiniTLS 0:35aa5be3b78d 121
MiniTLS 0:35aa5be3b78d 122 void crypto_sha1_copy(crypto_sha1_t* hashTo, crypto_sha1_t* hashFrom)
MiniTLS 0:35aa5be3b78d 123 {
MiniTLS 0:35aa5be3b78d 124 memcpy(hashTo, hashFrom, sizeof(crypto_sha1_t));
MiniTLS 0:35aa5be3b78d 125 }
MiniTLS 0:35aa5be3b78d 126
MiniTLS 0:35aa5be3b78d 127 void crypto_sha1_compress(crypto_sha1_t* hash, unsigned char *buf)
MiniTLS 0:35aa5be3b78d 128 {
MiniTLS 0:35aa5be3b78d 129 ulong32 a,b,c,d,e,W[80],i;
MiniTLS 0:35aa5be3b78d 130
MiniTLS 0:35aa5be3b78d 131
MiniTLS 0:35aa5be3b78d 132 /* copy the state into 512-bits into W[0..15] */
MiniTLS 0:35aa5be3b78d 133 for (i = 0; i < 16; i++) {
MiniTLS 0:35aa5be3b78d 134 LOAD32H(W[i], buf + (4*i));
MiniTLS 0:35aa5be3b78d 135 }
MiniTLS 0:35aa5be3b78d 136
MiniTLS 0:35aa5be3b78d 137 /* copy state */
MiniTLS 0:35aa5be3b78d 138 a = hash->state[0];
MiniTLS 0:35aa5be3b78d 139 b = hash->state[1];
MiniTLS 0:35aa5be3b78d 140 c = hash->state[2];
MiniTLS 0:35aa5be3b78d 141 d = hash->state[3];
MiniTLS 0:35aa5be3b78d 142 e = hash->state[4];
MiniTLS 0:35aa5be3b78d 143
MiniTLS 0:35aa5be3b78d 144 /* expand it */
MiniTLS 0:35aa5be3b78d 145 for (i = 16; i < 80; i++) {
MiniTLS 0:35aa5be3b78d 146 W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
MiniTLS 0:35aa5be3b78d 147 }
MiniTLS 0:35aa5be3b78d 148
MiniTLS 0:35aa5be3b78d 149 /* compress */
MiniTLS 0:35aa5be3b78d 150 /* round one */
MiniTLS 0:35aa5be3b78d 151 #define F0(x,y,z) (z ^ (x & (y ^ z)))
MiniTLS 0:35aa5be3b78d 152 #define F1(x,y,z) (x ^ y ^ z)
MiniTLS 0:35aa5be3b78d 153 #define F2(x,y,z) ((x & y) | (z & (x | y)))
MiniTLS 0:35aa5be3b78d 154 #define F3(x,y,z) (x ^ y ^ z)
MiniTLS 0:35aa5be3b78d 155 #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
MiniTLS 0:35aa5be3b78d 156 #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
MiniTLS 0:35aa5be3b78d 157 #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
MiniTLS 0:35aa5be3b78d 158 #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
MiniTLS 0:35aa5be3b78d 159
MiniTLS 0:35aa5be3b78d 160 #ifdef CRYPT_SMALL_CODE
MiniTLS 0:35aa5be3b78d 161
MiniTLS 0:35aa5be3b78d 162 for (i = 0; i < 20; ) {
MiniTLS 0:35aa5be3b78d 163 FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
MiniTLS 0:35aa5be3b78d 164 }
MiniTLS 0:35aa5be3b78d 165
MiniTLS 0:35aa5be3b78d 166 for (; i < 40; ) {
MiniTLS 0:35aa5be3b78d 167 FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
MiniTLS 0:35aa5be3b78d 168 }
MiniTLS 0:35aa5be3b78d 169
MiniTLS 0:35aa5be3b78d 170 for (; i < 60; ) {
MiniTLS 0:35aa5be3b78d 171 FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
MiniTLS 0:35aa5be3b78d 172 }
MiniTLS 0:35aa5be3b78d 173
MiniTLS 0:35aa5be3b78d 174 for (; i < 80; ) {
MiniTLS 0:35aa5be3b78d 175 FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
MiniTLS 0:35aa5be3b78d 176 }
MiniTLS 0:35aa5be3b78d 177
MiniTLS 0:35aa5be3b78d 178 #else
MiniTLS 0:35aa5be3b78d 179
MiniTLS 0:35aa5be3b78d 180 for (i = 0; i < 20; ) {
MiniTLS 0:35aa5be3b78d 181 FF0(a,b,c,d,e,i++);
MiniTLS 0:35aa5be3b78d 182 FF0(e,a,b,c,d,i++);
MiniTLS 0:35aa5be3b78d 183 FF0(d,e,a,b,c,i++);
MiniTLS 0:35aa5be3b78d 184 FF0(c,d,e,a,b,i++);
MiniTLS 0:35aa5be3b78d 185 FF0(b,c,d,e,a,i++);
MiniTLS 0:35aa5be3b78d 186 }
MiniTLS 0:35aa5be3b78d 187
MiniTLS 0:35aa5be3b78d 188 /* round two */
MiniTLS 0:35aa5be3b78d 189 for (; i < 40; ) {
MiniTLS 0:35aa5be3b78d 190 FF1(a,b,c,d,e,i++);
MiniTLS 0:35aa5be3b78d 191 FF1(e,a,b,c,d,i++);
MiniTLS 0:35aa5be3b78d 192 FF1(d,e,a,b,c,i++);
MiniTLS 0:35aa5be3b78d 193 FF1(c,d,e,a,b,i++);
MiniTLS 0:35aa5be3b78d 194 FF1(b,c,d,e,a,i++);
MiniTLS 0:35aa5be3b78d 195 }
MiniTLS 0:35aa5be3b78d 196
MiniTLS 0:35aa5be3b78d 197 /* round three */
MiniTLS 0:35aa5be3b78d 198 for (; i < 60; ) {
MiniTLS 0:35aa5be3b78d 199 FF2(a,b,c,d,e,i++);
MiniTLS 0:35aa5be3b78d 200 FF2(e,a,b,c,d,i++);
MiniTLS 0:35aa5be3b78d 201 FF2(d,e,a,b,c,i++);
MiniTLS 0:35aa5be3b78d 202 FF2(c,d,e,a,b,i++);
MiniTLS 0:35aa5be3b78d 203 FF2(b,c,d,e,a,i++);
MiniTLS 0:35aa5be3b78d 204 }
MiniTLS 0:35aa5be3b78d 205
MiniTLS 0:35aa5be3b78d 206 /* round four */
MiniTLS 0:35aa5be3b78d 207 for (; i < 80; ) {
MiniTLS 0:35aa5be3b78d 208 FF3(a,b,c,d,e,i++);
MiniTLS 0:35aa5be3b78d 209 FF3(e,a,b,c,d,i++);
MiniTLS 0:35aa5be3b78d 210 FF3(d,e,a,b,c,i++);
MiniTLS 0:35aa5be3b78d 211 FF3(c,d,e,a,b,i++);
MiniTLS 0:35aa5be3b78d 212 FF3(b,c,d,e,a,i++);
MiniTLS 0:35aa5be3b78d 213 }
MiniTLS 0:35aa5be3b78d 214 #endif
MiniTLS 0:35aa5be3b78d 215
MiniTLS 0:35aa5be3b78d 216 #undef FF0
MiniTLS 0:35aa5be3b78d 217 #undef FF1
MiniTLS 0:35aa5be3b78d 218 #undef FF2
MiniTLS 0:35aa5be3b78d 219 #undef FF3
MiniTLS 0:35aa5be3b78d 220
MiniTLS 0:35aa5be3b78d 221 /* store */
MiniTLS 0:35aa5be3b78d 222 hash->state[0] = hash->state[0] + a;
MiniTLS 0:35aa5be3b78d 223 hash->state[1] = hash->state[1] + b;
MiniTLS 0:35aa5be3b78d 224 hash->state[2] = hash->state[2] + c;
MiniTLS 0:35aa5be3b78d 225 hash->state[3] = hash->state[3] + d;
MiniTLS 0:35aa5be3b78d 226 hash->state[4] = hash->state[4] + e;
MiniTLS 0:35aa5be3b78d 227
MiniTLS 0:35aa5be3b78d 228 #if CRYPT_CLEAN_STACK
MiniTLS 0:35aa5be3b78d 229 burn_stack(sizeof(ulong32) * 87);
MiniTLS 0:35aa5be3b78d 230 #endif
MiniTLS 0:35aa5be3b78d 231 }