Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.

Dependencies:   mbed

Committer:
dflet
Date:
Tue Sep 15 16:45:04 2015 +0000
Revision:
22:f9b5e0b80bf2
Parent:
0:50cedd586816
Removed some debug.

Who changed what in which revision?

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