Example program with HTTPServer and sensor data streaming over TCPSockets, using Donatien Garnier's Net APIs and services code on top of LWIP. Files StreamServer.h and .cpp encapsulate streaming over TCPSockets. Broadcast is done by sendToAll(), and all incoming data is echoed back to the client. Echo code can be replaced with some remote control of the streaming interface. See main() that shows how to periodically send some data to all subscribed clients. To subscribe, a client should open a socket at <mbed_ip> port 123. I used few lines in TCL code to set up a quick sink for the data. HTTP files are served on port 80 concurrently to the streaming.

Dependencies:   mbed

Committer:
iva2k
Date:
Sat Jun 12 06:01:50 2010 +0000
Revision:
0:e614f7875b60

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iva2k 0:e614f7875b60 1 /*
iva2k 0:e614f7875b60 2 * FIPS-180-1 compliant SHA-1 implementation
iva2k 0:e614f7875b60 3 *
iva2k 0:e614f7875b60 4 * Copyright (C) 2006-2010, Paul Bakker <polarssl_maintainer at polarssl.org>
iva2k 0:e614f7875b60 5 * All rights reserved.
iva2k 0:e614f7875b60 6 *
iva2k 0:e614f7875b60 7 * This program is free software; you can redistribute it and/or modify
iva2k 0:e614f7875b60 8 * it under the terms of the GNU General Public License as published by
iva2k 0:e614f7875b60 9 * the Free Software Foundation; either version 2 of the License, or
iva2k 0:e614f7875b60 10 * (at your option) any later version.
iva2k 0:e614f7875b60 11 *
iva2k 0:e614f7875b60 12 * This program is distributed in the hope that it will be useful,
iva2k 0:e614f7875b60 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
iva2k 0:e614f7875b60 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
iva2k 0:e614f7875b60 15 * GNU General Public License for more details.
iva2k 0:e614f7875b60 16 *
iva2k 0:e614f7875b60 17 * You should have received a copy of the GNU General Public License along
iva2k 0:e614f7875b60 18 * with this program; if not, write to the Free Software Foundation, Inc.,
iva2k 0:e614f7875b60 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
iva2k 0:e614f7875b60 20 */
iva2k 0:e614f7875b60 21 /*
iva2k 0:e614f7875b60 22 * The SHA-1 standard was published by NIST in 1993.
iva2k 0:e614f7875b60 23 *
iva2k 0:e614f7875b60 24 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
iva2k 0:e614f7875b60 25 */
iva2k 0:e614f7875b60 26
iva2k 0:e614f7875b60 27 #include "sha1config.h"
iva2k 0:e614f7875b60 28
iva2k 0:e614f7875b60 29 #if defined(POLARSSL_SHA1_C)
iva2k 0:e614f7875b60 30
iva2k 0:e614f7875b60 31 #include "sha1.h"
iva2k 0:e614f7875b60 32
iva2k 0:e614f7875b60 33 #include <string.h>
iva2k 0:e614f7875b60 34 #include <stdio.h>
iva2k 0:e614f7875b60 35
iva2k 0:e614f7875b60 36 /*
iva2k 0:e614f7875b60 37 * 32-bit integer manipulation macros (big endian)
iva2k 0:e614f7875b60 38 */
iva2k 0:e614f7875b60 39 #ifndef GET_ULONG_BE
iva2k 0:e614f7875b60 40 #define GET_ULONG_BE(n,b,i) \
iva2k 0:e614f7875b60 41 { \
iva2k 0:e614f7875b60 42 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
iva2k 0:e614f7875b60 43 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
iva2k 0:e614f7875b60 44 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
iva2k 0:e614f7875b60 45 | ( (unsigned long) (b)[(i) + 3] ); \
iva2k 0:e614f7875b60 46 }
iva2k 0:e614f7875b60 47 #endif
iva2k 0:e614f7875b60 48
iva2k 0:e614f7875b60 49 #ifndef PUT_ULONG_BE
iva2k 0:e614f7875b60 50 #define PUT_ULONG_BE(n,b,i) \
iva2k 0:e614f7875b60 51 { \
iva2k 0:e614f7875b60 52 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
iva2k 0:e614f7875b60 53 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
iva2k 0:e614f7875b60 54 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
iva2k 0:e614f7875b60 55 (b)[(i) + 3] = (unsigned char) ( (n) ); \
iva2k 0:e614f7875b60 56 }
iva2k 0:e614f7875b60 57 #endif
iva2k 0:e614f7875b60 58
iva2k 0:e614f7875b60 59 /*
iva2k 0:e614f7875b60 60 * SHA-1 context setup
iva2k 0:e614f7875b60 61 */
iva2k 0:e614f7875b60 62 void sha1_starts( sha1_context *ctx )
iva2k 0:e614f7875b60 63 {
iva2k 0:e614f7875b60 64 ctx->total[0] = 0;
iva2k 0:e614f7875b60 65 ctx->total[1] = 0;
iva2k 0:e614f7875b60 66
iva2k 0:e614f7875b60 67 ctx->state[0] = 0x67452301;
iva2k 0:e614f7875b60 68 ctx->state[1] = 0xEFCDAB89;
iva2k 0:e614f7875b60 69 ctx->state[2] = 0x98BADCFE;
iva2k 0:e614f7875b60 70 ctx->state[3] = 0x10325476;
iva2k 0:e614f7875b60 71 ctx->state[4] = 0xC3D2E1F0;
iva2k 0:e614f7875b60 72 }
iva2k 0:e614f7875b60 73
iva2k 0:e614f7875b60 74 static void sha1_process( sha1_context *ctx, const unsigned char data[64] )
iva2k 0:e614f7875b60 75 {
iva2k 0:e614f7875b60 76 unsigned long temp, W[16], A, B, C, D, E;
iva2k 0:e614f7875b60 77
iva2k 0:e614f7875b60 78 GET_ULONG_BE( W[ 0], data, 0 );
iva2k 0:e614f7875b60 79 GET_ULONG_BE( W[ 1], data, 4 );
iva2k 0:e614f7875b60 80 GET_ULONG_BE( W[ 2], data, 8 );
iva2k 0:e614f7875b60 81 GET_ULONG_BE( W[ 3], data, 12 );
iva2k 0:e614f7875b60 82 GET_ULONG_BE( W[ 4], data, 16 );
iva2k 0:e614f7875b60 83 GET_ULONG_BE( W[ 5], data, 20 );
iva2k 0:e614f7875b60 84 GET_ULONG_BE( W[ 6], data, 24 );
iva2k 0:e614f7875b60 85 GET_ULONG_BE( W[ 7], data, 28 );
iva2k 0:e614f7875b60 86 GET_ULONG_BE( W[ 8], data, 32 );
iva2k 0:e614f7875b60 87 GET_ULONG_BE( W[ 9], data, 36 );
iva2k 0:e614f7875b60 88 GET_ULONG_BE( W[10], data, 40 );
iva2k 0:e614f7875b60 89 GET_ULONG_BE( W[11], data, 44 );
iva2k 0:e614f7875b60 90 GET_ULONG_BE( W[12], data, 48 );
iva2k 0:e614f7875b60 91 GET_ULONG_BE( W[13], data, 52 );
iva2k 0:e614f7875b60 92 GET_ULONG_BE( W[14], data, 56 );
iva2k 0:e614f7875b60 93 GET_ULONG_BE( W[15], data, 60 );
iva2k 0:e614f7875b60 94
iva2k 0:e614f7875b60 95 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
iva2k 0:e614f7875b60 96
iva2k 0:e614f7875b60 97 #define R(t) \
iva2k 0:e614f7875b60 98 ( \
iva2k 0:e614f7875b60 99 temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
iva2k 0:e614f7875b60 100 W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
iva2k 0:e614f7875b60 101 ( W[t & 0x0F] = S(temp,1) ) \
iva2k 0:e614f7875b60 102 )
iva2k 0:e614f7875b60 103
iva2k 0:e614f7875b60 104 #define P(a,b,c,d,e,x) \
iva2k 0:e614f7875b60 105 { \
iva2k 0:e614f7875b60 106 e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
iva2k 0:e614f7875b60 107 }
iva2k 0:e614f7875b60 108
iva2k 0:e614f7875b60 109 A = ctx->state[0];
iva2k 0:e614f7875b60 110 B = ctx->state[1];
iva2k 0:e614f7875b60 111 C = ctx->state[2];
iva2k 0:e614f7875b60 112 D = ctx->state[3];
iva2k 0:e614f7875b60 113 E = ctx->state[4];
iva2k 0:e614f7875b60 114
iva2k 0:e614f7875b60 115 #define F(x,y,z) (z ^ (x & (y ^ z)))
iva2k 0:e614f7875b60 116 #define K 0x5A827999
iva2k 0:e614f7875b60 117
iva2k 0:e614f7875b60 118 P( A, B, C, D, E, W[0] );
iva2k 0:e614f7875b60 119 P( E, A, B, C, D, W[1] );
iva2k 0:e614f7875b60 120 P( D, E, A, B, C, W[2] );
iva2k 0:e614f7875b60 121 P( C, D, E, A, B, W[3] );
iva2k 0:e614f7875b60 122 P( B, C, D, E, A, W[4] );
iva2k 0:e614f7875b60 123 P( A, B, C, D, E, W[5] );
iva2k 0:e614f7875b60 124 P( E, A, B, C, D, W[6] );
iva2k 0:e614f7875b60 125 P( D, E, A, B, C, W[7] );
iva2k 0:e614f7875b60 126 P( C, D, E, A, B, W[8] );
iva2k 0:e614f7875b60 127 P( B, C, D, E, A, W[9] );
iva2k 0:e614f7875b60 128 P( A, B, C, D, E, W[10] );
iva2k 0:e614f7875b60 129 P( E, A, B, C, D, W[11] );
iva2k 0:e614f7875b60 130 P( D, E, A, B, C, W[12] );
iva2k 0:e614f7875b60 131 P( C, D, E, A, B, W[13] );
iva2k 0:e614f7875b60 132 P( B, C, D, E, A, W[14] );
iva2k 0:e614f7875b60 133 P( A, B, C, D, E, W[15] );
iva2k 0:e614f7875b60 134 P( E, A, B, C, D, R(16) );
iva2k 0:e614f7875b60 135 P( D, E, A, B, C, R(17) );
iva2k 0:e614f7875b60 136 P( C, D, E, A, B, R(18) );
iva2k 0:e614f7875b60 137 P( B, C, D, E, A, R(19) );
iva2k 0:e614f7875b60 138
iva2k 0:e614f7875b60 139 #undef K
iva2k 0:e614f7875b60 140 #undef F
iva2k 0:e614f7875b60 141
iva2k 0:e614f7875b60 142 #define F(x,y,z) (x ^ y ^ z)
iva2k 0:e614f7875b60 143 #define K 0x6ED9EBA1
iva2k 0:e614f7875b60 144
iva2k 0:e614f7875b60 145 P( A, B, C, D, E, R(20) );
iva2k 0:e614f7875b60 146 P( E, A, B, C, D, R(21) );
iva2k 0:e614f7875b60 147 P( D, E, A, B, C, R(22) );
iva2k 0:e614f7875b60 148 P( C, D, E, A, B, R(23) );
iva2k 0:e614f7875b60 149 P( B, C, D, E, A, R(24) );
iva2k 0:e614f7875b60 150 P( A, B, C, D, E, R(25) );
iva2k 0:e614f7875b60 151 P( E, A, B, C, D, R(26) );
iva2k 0:e614f7875b60 152 P( D, E, A, B, C, R(27) );
iva2k 0:e614f7875b60 153 P( C, D, E, A, B, R(28) );
iva2k 0:e614f7875b60 154 P( B, C, D, E, A, R(29) );
iva2k 0:e614f7875b60 155 P( A, B, C, D, E, R(30) );
iva2k 0:e614f7875b60 156 P( E, A, B, C, D, R(31) );
iva2k 0:e614f7875b60 157 P( D, E, A, B, C, R(32) );
iva2k 0:e614f7875b60 158 P( C, D, E, A, B, R(33) );
iva2k 0:e614f7875b60 159 P( B, C, D, E, A, R(34) );
iva2k 0:e614f7875b60 160 P( A, B, C, D, E, R(35) );
iva2k 0:e614f7875b60 161 P( E, A, B, C, D, R(36) );
iva2k 0:e614f7875b60 162 P( D, E, A, B, C, R(37) );
iva2k 0:e614f7875b60 163 P( C, D, E, A, B, R(38) );
iva2k 0:e614f7875b60 164 P( B, C, D, E, A, R(39) );
iva2k 0:e614f7875b60 165
iva2k 0:e614f7875b60 166 #undef K
iva2k 0:e614f7875b60 167 #undef F
iva2k 0:e614f7875b60 168
iva2k 0:e614f7875b60 169 #define F(x,y,z) ((x & y) | (z & (x | y)))
iva2k 0:e614f7875b60 170 #define K 0x8F1BBCDC
iva2k 0:e614f7875b60 171
iva2k 0:e614f7875b60 172 P( A, B, C, D, E, R(40) );
iva2k 0:e614f7875b60 173 P( E, A, B, C, D, R(41) );
iva2k 0:e614f7875b60 174 P( D, E, A, B, C, R(42) );
iva2k 0:e614f7875b60 175 P( C, D, E, A, B, R(43) );
iva2k 0:e614f7875b60 176 P( B, C, D, E, A, R(44) );
iva2k 0:e614f7875b60 177 P( A, B, C, D, E, R(45) );
iva2k 0:e614f7875b60 178 P( E, A, B, C, D, R(46) );
iva2k 0:e614f7875b60 179 P( D, E, A, B, C, R(47) );
iva2k 0:e614f7875b60 180 P( C, D, E, A, B, R(48) );
iva2k 0:e614f7875b60 181 P( B, C, D, E, A, R(49) );
iva2k 0:e614f7875b60 182 P( A, B, C, D, E, R(50) );
iva2k 0:e614f7875b60 183 P( E, A, B, C, D, R(51) );
iva2k 0:e614f7875b60 184 P( D, E, A, B, C, R(52) );
iva2k 0:e614f7875b60 185 P( C, D, E, A, B, R(53) );
iva2k 0:e614f7875b60 186 P( B, C, D, E, A, R(54) );
iva2k 0:e614f7875b60 187 P( A, B, C, D, E, R(55) );
iva2k 0:e614f7875b60 188 P( E, A, B, C, D, R(56) );
iva2k 0:e614f7875b60 189 P( D, E, A, B, C, R(57) );
iva2k 0:e614f7875b60 190 P( C, D, E, A, B, R(58) );
iva2k 0:e614f7875b60 191 P( B, C, D, E, A, R(59) );
iva2k 0:e614f7875b60 192
iva2k 0:e614f7875b60 193 #undef K
iva2k 0:e614f7875b60 194 #undef F
iva2k 0:e614f7875b60 195
iva2k 0:e614f7875b60 196 #define F(x,y,z) (x ^ y ^ z)
iva2k 0:e614f7875b60 197 #define K 0xCA62C1D6
iva2k 0:e614f7875b60 198
iva2k 0:e614f7875b60 199 P( A, B, C, D, E, R(60) );
iva2k 0:e614f7875b60 200 P( E, A, B, C, D, R(61) );
iva2k 0:e614f7875b60 201 P( D, E, A, B, C, R(62) );
iva2k 0:e614f7875b60 202 P( C, D, E, A, B, R(63) );
iva2k 0:e614f7875b60 203 P( B, C, D, E, A, R(64) );
iva2k 0:e614f7875b60 204 P( A, B, C, D, E, R(65) );
iva2k 0:e614f7875b60 205 P( E, A, B, C, D, R(66) );
iva2k 0:e614f7875b60 206 P( D, E, A, B, C, R(67) );
iva2k 0:e614f7875b60 207 P( C, D, E, A, B, R(68) );
iva2k 0:e614f7875b60 208 P( B, C, D, E, A, R(69) );
iva2k 0:e614f7875b60 209 P( A, B, C, D, E, R(70) );
iva2k 0:e614f7875b60 210 P( E, A, B, C, D, R(71) );
iva2k 0:e614f7875b60 211 P( D, E, A, B, C, R(72) );
iva2k 0:e614f7875b60 212 P( C, D, E, A, B, R(73) );
iva2k 0:e614f7875b60 213 P( B, C, D, E, A, R(74) );
iva2k 0:e614f7875b60 214 P( A, B, C, D, E, R(75) );
iva2k 0:e614f7875b60 215 P( E, A, B, C, D, R(76) );
iva2k 0:e614f7875b60 216 P( D, E, A, B, C, R(77) );
iva2k 0:e614f7875b60 217 P( C, D, E, A, B, R(78) );
iva2k 0:e614f7875b60 218 P( B, C, D, E, A, R(79) );
iva2k 0:e614f7875b60 219
iva2k 0:e614f7875b60 220 #undef K
iva2k 0:e614f7875b60 221 #undef F
iva2k 0:e614f7875b60 222
iva2k 0:e614f7875b60 223 ctx->state[0] += A;
iva2k 0:e614f7875b60 224 ctx->state[1] += B;
iva2k 0:e614f7875b60 225 ctx->state[2] += C;
iva2k 0:e614f7875b60 226 ctx->state[3] += D;
iva2k 0:e614f7875b60 227 ctx->state[4] += E;
iva2k 0:e614f7875b60 228 }
iva2k 0:e614f7875b60 229
iva2k 0:e614f7875b60 230 /*
iva2k 0:e614f7875b60 231 * SHA-1 process buffer
iva2k 0:e614f7875b60 232 */
iva2k 0:e614f7875b60 233 void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen )
iva2k 0:e614f7875b60 234 {
iva2k 0:e614f7875b60 235 int fill;
iva2k 0:e614f7875b60 236 unsigned long left;
iva2k 0:e614f7875b60 237
iva2k 0:e614f7875b60 238 if( ilen <= 0 )
iva2k 0:e614f7875b60 239 return;
iva2k 0:e614f7875b60 240
iva2k 0:e614f7875b60 241 left = ctx->total[0] & 0x3F;
iva2k 0:e614f7875b60 242 fill = 64 - left;
iva2k 0:e614f7875b60 243
iva2k 0:e614f7875b60 244 ctx->total[0] += ilen;
iva2k 0:e614f7875b60 245 ctx->total[0] &= 0xFFFFFFFF;
iva2k 0:e614f7875b60 246
iva2k 0:e614f7875b60 247 if( ctx->total[0] < (unsigned long) ilen )
iva2k 0:e614f7875b60 248 ctx->total[1]++;
iva2k 0:e614f7875b60 249
iva2k 0:e614f7875b60 250 if( left && ilen >= fill )
iva2k 0:e614f7875b60 251 {
iva2k 0:e614f7875b60 252 memcpy( (void *) (ctx->buffer + left),
iva2k 0:e614f7875b60 253 (void *) input, fill );
iva2k 0:e614f7875b60 254 sha1_process( ctx, ctx->buffer );
iva2k 0:e614f7875b60 255 input += fill;
iva2k 0:e614f7875b60 256 ilen -= fill;
iva2k 0:e614f7875b60 257 left = 0;
iva2k 0:e614f7875b60 258 }
iva2k 0:e614f7875b60 259
iva2k 0:e614f7875b60 260 while( ilen >= 64 )
iva2k 0:e614f7875b60 261 {
iva2k 0:e614f7875b60 262 sha1_process( ctx, input );
iva2k 0:e614f7875b60 263 input += 64;
iva2k 0:e614f7875b60 264 ilen -= 64;
iva2k 0:e614f7875b60 265 }
iva2k 0:e614f7875b60 266
iva2k 0:e614f7875b60 267 if( ilen > 0 )
iva2k 0:e614f7875b60 268 {
iva2k 0:e614f7875b60 269 memcpy( (void *) (ctx->buffer + left),
iva2k 0:e614f7875b60 270 (void *) input, ilen );
iva2k 0:e614f7875b60 271 }
iva2k 0:e614f7875b60 272 }
iva2k 0:e614f7875b60 273
iva2k 0:e614f7875b60 274 static const unsigned char sha1_padding[64] =
iva2k 0:e614f7875b60 275 {
iva2k 0:e614f7875b60 276 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
iva2k 0:e614f7875b60 277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
iva2k 0:e614f7875b60 278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
iva2k 0:e614f7875b60 279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
iva2k 0:e614f7875b60 280 };
iva2k 0:e614f7875b60 281
iva2k 0:e614f7875b60 282 /*
iva2k 0:e614f7875b60 283 * SHA-1 final digest
iva2k 0:e614f7875b60 284 */
iva2k 0:e614f7875b60 285 void sha1_finish( sha1_context *ctx, unsigned char output[20] )
iva2k 0:e614f7875b60 286 {
iva2k 0:e614f7875b60 287 unsigned long last, padn;
iva2k 0:e614f7875b60 288 unsigned long high, low;
iva2k 0:e614f7875b60 289 unsigned char msglen[8];
iva2k 0:e614f7875b60 290
iva2k 0:e614f7875b60 291 high = ( ctx->total[0] >> 29 )
iva2k 0:e614f7875b60 292 | ( ctx->total[1] << 3 );
iva2k 0:e614f7875b60 293 low = ( ctx->total[0] << 3 );
iva2k 0:e614f7875b60 294
iva2k 0:e614f7875b60 295 PUT_ULONG_BE( high, msglen, 0 );
iva2k 0:e614f7875b60 296 PUT_ULONG_BE( low, msglen, 4 );
iva2k 0:e614f7875b60 297
iva2k 0:e614f7875b60 298 last = ctx->total[0] & 0x3F;
iva2k 0:e614f7875b60 299 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
iva2k 0:e614f7875b60 300
iva2k 0:e614f7875b60 301 sha1_update( ctx, (unsigned char *) sha1_padding, padn );
iva2k 0:e614f7875b60 302 sha1_update( ctx, msglen, 8 );
iva2k 0:e614f7875b60 303
iva2k 0:e614f7875b60 304 PUT_ULONG_BE( ctx->state[0], output, 0 );
iva2k 0:e614f7875b60 305 PUT_ULONG_BE( ctx->state[1], output, 4 );
iva2k 0:e614f7875b60 306 PUT_ULONG_BE( ctx->state[2], output, 8 );
iva2k 0:e614f7875b60 307 PUT_ULONG_BE( ctx->state[3], output, 12 );
iva2k 0:e614f7875b60 308 PUT_ULONG_BE( ctx->state[4], output, 16 );
iva2k 0:e614f7875b60 309 }
iva2k 0:e614f7875b60 310
iva2k 0:e614f7875b60 311 /*
iva2k 0:e614f7875b60 312 * output = SHA-1( input buffer )
iva2k 0:e614f7875b60 313 */
iva2k 0:e614f7875b60 314 void sha1( const unsigned char *input, int ilen, unsigned char output[20] )
iva2k 0:e614f7875b60 315 {
iva2k 0:e614f7875b60 316 sha1_context ctx;
iva2k 0:e614f7875b60 317
iva2k 0:e614f7875b60 318 sha1_starts( &ctx );
iva2k 0:e614f7875b60 319 sha1_update( &ctx, input, ilen );
iva2k 0:e614f7875b60 320 sha1_finish( &ctx, output );
iva2k 0:e614f7875b60 321
iva2k 0:e614f7875b60 322 memset( &ctx, 0, sizeof( sha1_context ) );
iva2k 0:e614f7875b60 323 }
iva2k 0:e614f7875b60 324
iva2k 0:e614f7875b60 325 /*
iva2k 0:e614f7875b60 326 * output = SHA-1( file contents )
iva2k 0:e614f7875b60 327 */
iva2k 0:e614f7875b60 328 #if 0 //No need for that
iva2k 0:e614f7875b60 329 int sha1_file( const char *path, unsigned char output[20] )
iva2k 0:e614f7875b60 330 {
iva2k 0:e614f7875b60 331 FILE *f;
iva2k 0:e614f7875b60 332 size_t n;
iva2k 0:e614f7875b60 333 sha1_context ctx;
iva2k 0:e614f7875b60 334 unsigned char buf[1024];
iva2k 0:e614f7875b60 335
iva2k 0:e614f7875b60 336 if( ( f = fopen( path, "rb" ) ) == NULL )
iva2k 0:e614f7875b60 337 return( 1 );
iva2k 0:e614f7875b60 338
iva2k 0:e614f7875b60 339 sha1_starts( &ctx );
iva2k 0:e614f7875b60 340
iva2k 0:e614f7875b60 341 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
iva2k 0:e614f7875b60 342 sha1_update( &ctx, buf, (int) n );
iva2k 0:e614f7875b60 343
iva2k 0:e614f7875b60 344 sha1_finish( &ctx, output );
iva2k 0:e614f7875b60 345
iva2k 0:e614f7875b60 346 memset( &ctx, 0, sizeof( sha1_context ) );
iva2k 0:e614f7875b60 347
iva2k 0:e614f7875b60 348 if( ferror( f ) != 0 )
iva2k 0:e614f7875b60 349 {
iva2k 0:e614f7875b60 350 fclose( f );
iva2k 0:e614f7875b60 351 return( 2 );
iva2k 0:e614f7875b60 352 }
iva2k 0:e614f7875b60 353
iva2k 0:e614f7875b60 354 fclose( f );
iva2k 0:e614f7875b60 355 return( 0 );
iva2k 0:e614f7875b60 356 }
iva2k 0:e614f7875b60 357 #endif
iva2k 0:e614f7875b60 358
iva2k 0:e614f7875b60 359 /*
iva2k 0:e614f7875b60 360 * SHA-1 HMAC context setup
iva2k 0:e614f7875b60 361 */
iva2k 0:e614f7875b60 362 void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen )
iva2k 0:e614f7875b60 363 {
iva2k 0:e614f7875b60 364 int i;
iva2k 0:e614f7875b60 365 unsigned char sum[20];
iva2k 0:e614f7875b60 366
iva2k 0:e614f7875b60 367 if( keylen > 64 )
iva2k 0:e614f7875b60 368 {
iva2k 0:e614f7875b60 369 sha1( key, keylen, sum );
iva2k 0:e614f7875b60 370 keylen = 20;
iva2k 0:e614f7875b60 371 key = sum;
iva2k 0:e614f7875b60 372 }
iva2k 0:e614f7875b60 373
iva2k 0:e614f7875b60 374 memset( ctx->ipad, 0x36, 64 );
iva2k 0:e614f7875b60 375 memset( ctx->opad, 0x5C, 64 );
iva2k 0:e614f7875b60 376
iva2k 0:e614f7875b60 377 for( i = 0; i < keylen; i++ )
iva2k 0:e614f7875b60 378 {
iva2k 0:e614f7875b60 379 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
iva2k 0:e614f7875b60 380 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
iva2k 0:e614f7875b60 381 }
iva2k 0:e614f7875b60 382
iva2k 0:e614f7875b60 383 sha1_starts( ctx );
iva2k 0:e614f7875b60 384 sha1_update( ctx, ctx->ipad, 64 );
iva2k 0:e614f7875b60 385
iva2k 0:e614f7875b60 386 memset( sum, 0, sizeof( sum ) );
iva2k 0:e614f7875b60 387 }
iva2k 0:e614f7875b60 388
iva2k 0:e614f7875b60 389 /*
iva2k 0:e614f7875b60 390 * SHA-1 HMAC process buffer
iva2k 0:e614f7875b60 391 */
iva2k 0:e614f7875b60 392 void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen )
iva2k 0:e614f7875b60 393 {
iva2k 0:e614f7875b60 394 sha1_update( ctx, input, ilen );
iva2k 0:e614f7875b60 395 }
iva2k 0:e614f7875b60 396
iva2k 0:e614f7875b60 397 /*
iva2k 0:e614f7875b60 398 * SHA-1 HMAC final digest
iva2k 0:e614f7875b60 399 */
iva2k 0:e614f7875b60 400 void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
iva2k 0:e614f7875b60 401 {
iva2k 0:e614f7875b60 402 unsigned char tmpbuf[20];
iva2k 0:e614f7875b60 403
iva2k 0:e614f7875b60 404 sha1_finish( ctx, tmpbuf );
iva2k 0:e614f7875b60 405 sha1_starts( ctx );
iva2k 0:e614f7875b60 406 sha1_update( ctx, ctx->opad, 64 );
iva2k 0:e614f7875b60 407 sha1_update( ctx, tmpbuf, 20 );
iva2k 0:e614f7875b60 408 sha1_finish( ctx, output );
iva2k 0:e614f7875b60 409
iva2k 0:e614f7875b60 410 memset( tmpbuf, 0, sizeof( tmpbuf ) );
iva2k 0:e614f7875b60 411 }
iva2k 0:e614f7875b60 412
iva2k 0:e614f7875b60 413 /*
iva2k 0:e614f7875b60 414 * SHA1 HMAC context reset
iva2k 0:e614f7875b60 415 */
iva2k 0:e614f7875b60 416 void sha1_hmac_reset( sha1_context *ctx )
iva2k 0:e614f7875b60 417 {
iva2k 0:e614f7875b60 418 sha1_starts( ctx );
iva2k 0:e614f7875b60 419 sha1_update( ctx, ctx->ipad, 64 );
iva2k 0:e614f7875b60 420 }
iva2k 0:e614f7875b60 421
iva2k 0:e614f7875b60 422 /*
iva2k 0:e614f7875b60 423 * output = HMAC-SHA-1( hmac key, input buffer )
iva2k 0:e614f7875b60 424 */
iva2k 0:e614f7875b60 425 void sha1_hmac( const unsigned char *key, int keylen,
iva2k 0:e614f7875b60 426 const unsigned char *input, int ilen,
iva2k 0:e614f7875b60 427 unsigned char output[20] )
iva2k 0:e614f7875b60 428 {
iva2k 0:e614f7875b60 429 sha1_context ctx;
iva2k 0:e614f7875b60 430
iva2k 0:e614f7875b60 431 sha1_hmac_starts( &ctx, key, keylen );
iva2k 0:e614f7875b60 432 sha1_hmac_update( &ctx, input, ilen );
iva2k 0:e614f7875b60 433 sha1_hmac_finish( &ctx, output );
iva2k 0:e614f7875b60 434
iva2k 0:e614f7875b60 435 memset( &ctx, 0, sizeof( sha1_context ) );
iva2k 0:e614f7875b60 436 }
iva2k 0:e614f7875b60 437
iva2k 0:e614f7875b60 438 #if defined(POLARSSL_SELF_TEST)
iva2k 0:e614f7875b60 439 /*
iva2k 0:e614f7875b60 440 * FIPS-180-1 test vectors
iva2k 0:e614f7875b60 441 */
iva2k 0:e614f7875b60 442 static unsigned char sha1_test_buf[3][57] =
iva2k 0:e614f7875b60 443 {
iva2k 0:e614f7875b60 444 { "abc" },
iva2k 0:e614f7875b60 445 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
iva2k 0:e614f7875b60 446 { "" }
iva2k 0:e614f7875b60 447 };
iva2k 0:e614f7875b60 448
iva2k 0:e614f7875b60 449 static const int sha1_test_buflen[3] =
iva2k 0:e614f7875b60 450 {
iva2k 0:e614f7875b60 451 3, 56, 1000
iva2k 0:e614f7875b60 452 };
iva2k 0:e614f7875b60 453
iva2k 0:e614f7875b60 454 static const unsigned char sha1_test_sum[3][20] =
iva2k 0:e614f7875b60 455 {
iva2k 0:e614f7875b60 456 { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
iva2k 0:e614f7875b60 457 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
iva2k 0:e614f7875b60 458 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
iva2k 0:e614f7875b60 459 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
iva2k 0:e614f7875b60 460 { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
iva2k 0:e614f7875b60 461 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
iva2k 0:e614f7875b60 462 };
iva2k 0:e614f7875b60 463
iva2k 0:e614f7875b60 464 /*
iva2k 0:e614f7875b60 465 * RFC 2202 test vectors
iva2k 0:e614f7875b60 466 */
iva2k 0:e614f7875b60 467 static unsigned char sha1_hmac_test_key[7][26] =
iva2k 0:e614f7875b60 468 {
iva2k 0:e614f7875b60 469 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
iva2k 0:e614f7875b60 470 "\x0B\x0B\x0B\x0B" },
iva2k 0:e614f7875b60 471 { "Jefe" },
iva2k 0:e614f7875b60 472 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
iva2k 0:e614f7875b60 473 "\xAA\xAA\xAA\xAA" },
iva2k 0:e614f7875b60 474 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
iva2k 0:e614f7875b60 475 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
iva2k 0:e614f7875b60 476 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
iva2k 0:e614f7875b60 477 "\x0C\x0C\x0C\x0C" },
iva2k 0:e614f7875b60 478 { "" }, /* 0xAA 80 times */
iva2k 0:e614f7875b60 479 { "" }
iva2k 0:e614f7875b60 480 };
iva2k 0:e614f7875b60 481
iva2k 0:e614f7875b60 482 static const int sha1_hmac_test_keylen[7] =
iva2k 0:e614f7875b60 483 {
iva2k 0:e614f7875b60 484 20, 4, 20, 25, 20, 80, 80
iva2k 0:e614f7875b60 485 };
iva2k 0:e614f7875b60 486
iva2k 0:e614f7875b60 487 static unsigned char sha1_hmac_test_buf[7][74] =
iva2k 0:e614f7875b60 488 {
iva2k 0:e614f7875b60 489 { "Hi There" },
iva2k 0:e614f7875b60 490 { "what do ya want for nothing?" },
iva2k 0:e614f7875b60 491 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
iva2k 0:e614f7875b60 492 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
iva2k 0:e614f7875b60 493 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
iva2k 0:e614f7875b60 494 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
iva2k 0:e614f7875b60 495 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
iva2k 0:e614f7875b60 496 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
iva2k 0:e614f7875b60 497 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
iva2k 0:e614f7875b60 498 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
iva2k 0:e614f7875b60 499 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
iva2k 0:e614f7875b60 500 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
iva2k 0:e614f7875b60 501 { "Test With Truncation" },
iva2k 0:e614f7875b60 502 { "Test Using Larger Than Block-Size Key - Hash Key First" },
iva2k 0:e614f7875b60 503 { "Test Using Larger Than Block-Size Key and Larger"
iva2k 0:e614f7875b60 504 " Than One Block-Size Data" }
iva2k 0:e614f7875b60 505 };
iva2k 0:e614f7875b60 506
iva2k 0:e614f7875b60 507 static const int sha1_hmac_test_buflen[7] =
iva2k 0:e614f7875b60 508 {
iva2k 0:e614f7875b60 509 8, 28, 50, 50, 20, 54, 73
iva2k 0:e614f7875b60 510 };
iva2k 0:e614f7875b60 511
iva2k 0:e614f7875b60 512 static const unsigned char sha1_hmac_test_sum[7][20] =
iva2k 0:e614f7875b60 513 {
iva2k 0:e614f7875b60 514 { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
iva2k 0:e614f7875b60 515 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
iva2k 0:e614f7875b60 516 { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
iva2k 0:e614f7875b60 517 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
iva2k 0:e614f7875b60 518 { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
iva2k 0:e614f7875b60 519 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
iva2k 0:e614f7875b60 520 { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
iva2k 0:e614f7875b60 521 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
iva2k 0:e614f7875b60 522 { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
iva2k 0:e614f7875b60 523 0x7B, 0xE1 },
iva2k 0:e614f7875b60 524 { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
iva2k 0:e614f7875b60 525 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
iva2k 0:e614f7875b60 526 { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
iva2k 0:e614f7875b60 527 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
iva2k 0:e614f7875b60 528 };
iva2k 0:e614f7875b60 529
iva2k 0:e614f7875b60 530 /*
iva2k 0:e614f7875b60 531 * Checkup routine
iva2k 0:e614f7875b60 532 */
iva2k 0:e614f7875b60 533 int sha1_self_test( int verbose )
iva2k 0:e614f7875b60 534 {
iva2k 0:e614f7875b60 535 int i, j, buflen;
iva2k 0:e614f7875b60 536 unsigned char buf[1024];
iva2k 0:e614f7875b60 537 unsigned char sha1sum[20];
iva2k 0:e614f7875b60 538 sha1_context ctx;
iva2k 0:e614f7875b60 539
iva2k 0:e614f7875b60 540 /*
iva2k 0:e614f7875b60 541 * SHA-1
iva2k 0:e614f7875b60 542 */
iva2k 0:e614f7875b60 543 for( i = 0; i < 3; i++ )
iva2k 0:e614f7875b60 544 {
iva2k 0:e614f7875b60 545 if( verbose != 0 )
iva2k 0:e614f7875b60 546 printf( " SHA-1 test #%d: ", i + 1 );
iva2k 0:e614f7875b60 547
iva2k 0:e614f7875b60 548 sha1_starts( &ctx );
iva2k 0:e614f7875b60 549
iva2k 0:e614f7875b60 550 if( i == 2 )
iva2k 0:e614f7875b60 551 {
iva2k 0:e614f7875b60 552 memset( buf, 'a', buflen = 1000 );
iva2k 0:e614f7875b60 553
iva2k 0:e614f7875b60 554 for( j = 0; j < 1000; j++ )
iva2k 0:e614f7875b60 555 sha1_update( &ctx, buf, buflen );
iva2k 0:e614f7875b60 556 }
iva2k 0:e614f7875b60 557 else
iva2k 0:e614f7875b60 558 sha1_update( &ctx, sha1_test_buf[i],
iva2k 0:e614f7875b60 559 sha1_test_buflen[i] );
iva2k 0:e614f7875b60 560
iva2k 0:e614f7875b60 561 sha1_finish( &ctx, sha1sum );
iva2k 0:e614f7875b60 562
iva2k 0:e614f7875b60 563 if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
iva2k 0:e614f7875b60 564 {
iva2k 0:e614f7875b60 565 if( verbose != 0 )
iva2k 0:e614f7875b60 566 printf( "failed\n" );
iva2k 0:e614f7875b60 567
iva2k 0:e614f7875b60 568 return( 1 );
iva2k 0:e614f7875b60 569 }
iva2k 0:e614f7875b60 570
iva2k 0:e614f7875b60 571 if( verbose != 0 )
iva2k 0:e614f7875b60 572 printf( "passed\n" );
iva2k 0:e614f7875b60 573 }
iva2k 0:e614f7875b60 574
iva2k 0:e614f7875b60 575 if( verbose != 0 )
iva2k 0:e614f7875b60 576 printf( "\n" );
iva2k 0:e614f7875b60 577
iva2k 0:e614f7875b60 578 for( i = 0; i < 7; i++ )
iva2k 0:e614f7875b60 579 {
iva2k 0:e614f7875b60 580 if( verbose != 0 )
iva2k 0:e614f7875b60 581 printf( " HMAC-SHA-1 test #%d: ", i + 1 );
iva2k 0:e614f7875b60 582
iva2k 0:e614f7875b60 583 if( i == 5 || i == 6 )
iva2k 0:e614f7875b60 584 {
iva2k 0:e614f7875b60 585 memset( buf, '\xAA', buflen = 80 );
iva2k 0:e614f7875b60 586 sha1_hmac_starts( &ctx, buf, buflen );
iva2k 0:e614f7875b60 587 }
iva2k 0:e614f7875b60 588 else
iva2k 0:e614f7875b60 589 sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
iva2k 0:e614f7875b60 590 sha1_hmac_test_keylen[i] );
iva2k 0:e614f7875b60 591
iva2k 0:e614f7875b60 592 sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
iva2k 0:e614f7875b60 593 sha1_hmac_test_buflen[i] );
iva2k 0:e614f7875b60 594
iva2k 0:e614f7875b60 595 sha1_hmac_finish( &ctx, sha1sum );
iva2k 0:e614f7875b60 596
iva2k 0:e614f7875b60 597 buflen = ( i == 4 ) ? 12 : 20;
iva2k 0:e614f7875b60 598
iva2k 0:e614f7875b60 599 if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
iva2k 0:e614f7875b60 600 {
iva2k 0:e614f7875b60 601 if( verbose != 0 )
iva2k 0:e614f7875b60 602 printf( "failed\n" );
iva2k 0:e614f7875b60 603
iva2k 0:e614f7875b60 604 return( 1 );
iva2k 0:e614f7875b60 605 }
iva2k 0:e614f7875b60 606
iva2k 0:e614f7875b60 607 if( verbose != 0 )
iva2k 0:e614f7875b60 608 printf( "passed\n" );
iva2k 0:e614f7875b60 609 }
iva2k 0:e614f7875b60 610
iva2k 0:e614f7875b60 611 if( verbose != 0 )
iva2k 0:e614f7875b60 612 printf( "\n" );
iva2k 0:e614f7875b60 613
iva2k 0:e614f7875b60 614 return( 0 );
iva2k 0:e614f7875b60 615 }
iva2k 0:e614f7875b60 616
iva2k 0:e614f7875b60 617 #endif
iva2k 0:e614f7875b60 618
iva2k 0:e614f7875b60 619 #endif