Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MiniTLS-HTTPS-Example
crypto/crypto_sha1.c@0:35aa5be3b78d, 2014-06-06 (annotated)
- Committer:
- MiniTLS
- Date:
- Fri Jun 06 10:49:02 2014 +0000
- Revision:
- 0:35aa5be3b78d
Initial commit
Who changed what in which revision?
User | Revision | Line number | New 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 | } |