diff --git a/crypto/Makefile b/crypto/Makefile index 3ea8bdde0..360843d3c 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -38,11 +38,11 @@ OBJ=\ bigint.o \ crypto_misc.o \ hmac.o \ - md2.o \ md5.o \ rc4.o \ rsa.o \ - sha1.o + sha1.o \ + sha256.o include ../config/makefile.post diff --git a/crypto/crypto.h b/crypto/crypto.h index 128a56bab..df11e923a 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -124,22 +124,21 @@ void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len); void SHA1_Final(uint8_t *digest, SHA1_CTX *); /************************************************************************** - * MD2 declarations + * SHA256 declarations **************************************************************************/ -#define MD2_SIZE 16 +#define SHA256_SIZE 32 typedef struct { - unsigned char cksum[16]; /* checksum of the data block */ - unsigned char state[48]; /* intermediate digest state */ - unsigned char buffer[16]; /* data block being processed */ - int left; /* amount of data in buffer */ -} MD2_CTX; + uint32_t total[2]; + uint32_t state[8]; + uint8_t buffer[64]; +} SHA256_CTX; -EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx); -EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen); -EXP_FUNC void STDCALL MD2_Final(uint8_t *digest, MD2_CTX *ctx); +void SHA256_Init(SHA256_CTX *c); +void SHA256_Update(SHA256_CTX *, const uint8_t *input, int len); +void SHA256_Final(uint8_t digest[32], SHA256_CTX *); /************************************************************************** * MD5 declarations @@ -154,9 +153,9 @@ typedef struct uint8_t buffer[64]; /* input buffer */ } MD5_CTX; -EXP_FUNC void STDCALL MD5_Init(MD5_CTX *); -EXP_FUNC void STDCALL MD5_Update(MD5_CTX *, const uint8_t *msg, int len); -EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *); +void MD5_Init(MD5_CTX *); +void MD5_Update(MD5_CTX *, const uint8_t *msg, int len); +void MD5_Final(uint8_t *digest, MD5_CTX *); /************************************************************************** * HMAC declarations diff --git a/crypto/md2.c b/crypto/md2.c deleted file mode 100644 index dee909a7a..000000000 --- a/crypto/md2.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2007, Cameron Rich - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * RFC 1115/1319 compliant MD2 implementation - * The MD2 algorithm was designed by Ron Rivest in 1989. - * - * http://www.ietf.org/rfc/rfc1115.txt - * http://www.ietf.org/rfc/rfc1319.txt - */ - -#include -#include -#include "os_port.h" -#include "crypto.h" - -/** - * This code is only here to enable the verification of Verisign root - * certificates. So only enable it for verification mode. - */ -#ifdef CONFIG_SSL_CERT_VERIFICATION - -static const uint8_t PI_SUBST[256] = -{ - 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, - 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, - 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, - 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, - 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, - 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, - 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, - 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, - 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, - 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, - 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, - 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, - 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, - 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, - 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, - 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, - 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, - 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, - 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, - 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, - 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, - 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, - 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, - 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, - 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, - 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 -}; - -/* - * MD2 context setup - */ -EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx) -{ - memset(ctx, 0, sizeof *ctx); -} - -static void md2_process(MD2_CTX *ctx) -{ - int i, j; - uint8_t t = 0; - - for (i = 0; i < 16; i++) - { - ctx->state[i + 16] = ctx->buffer[i]; - ctx->state[i + 32] = ctx->buffer[i] ^ ctx->state[i]; - } - - for (i = 0; i < 18; i++) - { - for (j = 0; j < 48; j++) - t = (ctx->state[j] ^= PI_SUBST[t]); - - t = (t + i) & 0xFF; - } - - t = ctx->cksum[15]; - - for (i = 0; i < 16; i++) - t = (ctx->cksum[i] ^= PI_SUBST[ctx->buffer[i] ^ t]); -} - -/* - * MD2 process buffer - */ -EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen) -{ - int fill; - - while (ilen > 0) - { - if (ctx->left + ilen > 16) - fill = 16 - ctx->left; - else - fill = ilen; - - memcpy(ctx->buffer + ctx->left, input, fill); - - ctx->left += fill; - input += fill; - ilen -= fill; - - if (ctx->left == 16) - { - ctx->left = 0; - md2_process(ctx); - } - } -} - -/* - * MD2 final digest - */ -EXP_FUNC void STDCALL MD2_Final(uint8_t *output, MD2_CTX *ctx) -{ - int i; - uint8_t x; - - x = (uint8_t)(16 - ctx->left); - - for (i = ctx->left; i < 16; i++) - ctx->buffer[i] = x; - - md2_process(ctx); - - memcpy(ctx->buffer, ctx->cksum, 16); - md2_process(ctx); - - memcpy(output, ctx->state, 16); -} - -#endif diff --git a/crypto/sha256.c b/crypto/sha256.c new file mode 100644 index 000000000..0c1d04ae4 --- /dev/null +++ b/crypto/sha256.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2014, Cameron Rich + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the axTLS project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright (C) 2001-2003 Christophe Devine + * + * This program is free software; 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 program is distributed in the hope that it will be useful, + * but 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 + */ + +#include +#include "os_port.h" +#include "crypto.h" + +#define GET_UINT32(n,b,i) \ +{ \ + (n) = ((uint32_t) (b)[(i) ] << 24) \ + | ((uint32_t) (b)[(i) + 1] << 16) \ + | ((uint32_t) (b)[(i) + 2] << 8) \ + | ((uint32_t) (b)[(i) + 3] ); \ +} + +#define PUT_UINT32(n,b,i) \ +{ \ + (b)[(i) ] = (uint8_t) ((n) >> 24); \ + (b)[(i) + 1] = (uint8_t) ((n) >> 16); \ + (b)[(i) + 2] = (uint8_t) ((n) >> 8); \ + (b)[(i) + 3] = (uint8_t) ((n) ); \ +} + +static const uint8_t sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/** + * Initialize the SHA256 context + */ +void SHA256_Init(SHA256_CTX *ctx) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; +} + +void SHA256_Process(const uint8_t digest[64], SHA256_CTX *ctx) +{ + uint32_t temp1, temp2, W[64]; + uint32_t A, B, C, D, E, F, G, H; + + GET_UINT32(W[0], digest, 0); + GET_UINT32(W[1], digest, 4); + GET_UINT32(W[2], digest, 8); + GET_UINT32(W[3], digest, 12); + GET_UINT32(W[4], digest, 16); + GET_UINT32(W[5], digest, 20); + GET_UINT32(W[6], digest, 24); + GET_UINT32(W[7], digest, 28); + GET_UINT32(W[8], digest, 32); + GET_UINT32(W[9], digest, 36); + GET_UINT32(W[10], digest, 40); + GET_UINT32(W[11], digest, 44); + GET_UINT32(W[12], digest, 48); + GET_UINT32(W[13], digest, 52); + GET_UINT32(W[14], digest, 56); + GET_UINT32(W[15], digest, 60); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) \ +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + P(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); + P(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); + P(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF); + P(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5); + P(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B); + P(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1); + P(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4); + P(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5); + P(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98); + P(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01); + P(G, H, A, B, C, D, E, F, W[10], 0x243185BE); + P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); + P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); + P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); + P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); + P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); + P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); + P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); + P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); + P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); + P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); + P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); + P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); + P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA); + P(A, B, C, D, E, F, G, H, R(24), 0x983E5152); + P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D); + P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8); + P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); + P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); + P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147); + P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351); + P(B, C, D, E, F, G, H, A, R(31), 0x14292967); + P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85); + P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); + P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); + P(F, G, H, A, B, C, D, E, R(35), 0x53380D13); + P(E, F, G, H, A, B, C, D, R(36), 0x650A7354); + P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); + P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); + P(B, C, D, E, F, G, H, A, R(39), 0x92722C85); + P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); + P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B); + P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); + P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); + P(E, F, G, H, A, B, C, D, R(44), 0xD192E819); + P(D, E, F, G, H, A, B, C, R(45), 0xD6990624); + P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585); + P(B, C, D, E, F, G, H, A, R(47), 0x106AA070); + P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116); + P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08); + P(G, H, A, B, C, D, E, F, R(50), 0x2748774C); + P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); + P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); + P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); + P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); + P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); + P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE); + P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F); + P(G, H, A, B, C, D, E, F, R(58), 0x84C87814); + P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208); + P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); + P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); + P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); + P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +/** + * Accepts an array of octets as the next portion of the message. + */ +void SHA256_Update(SHA256_CTX *ctx, const uint8_t * msg, int len) +{ + uint32_t left = ctx->total[0] & 0x3F; + uint32_t fill = 64 - left; + + ctx->total[0] += len; + ctx->total[0] &= 0xFFFFFFFF; + + if (ctx->total[0] < len) + ctx->total[1]++; + + if (left && len >= fill) + { + memcpy((void *) (ctx->buffer + left), (void *)msg, fill); + SHA256_Process(ctx->buffer, ctx); + len -= fill; + msg += fill; + left = 0; + } + + while (len >= 64) + { + SHA256_Process(msg, ctx); + len -= 64; + msg += 64; + } + + if (len) + { + memcpy((void *) (ctx->buffer + left), (void *) msg, len); + } +} + +/** + * Return the 256-bit message digest into the user's array + */ +void SHA256_Final(uint8_t *digest, SHA256_CTX *ctx) +{ + uint32_t last, padn; + uint32_t high, low; + uint8_t msglen[8]; + + high = (ctx->total[0] >> 29) + | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + PUT_UINT32(high, msglen, 0); + PUT_UINT32(low, msglen, 4); + + last = ctx->total[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + SHA256_Update(ctx, sha256_padding, padn); + SHA256_Update(ctx, msglen, 8); + + PUT_UINT32(ctx->state[0], digest, 0); + PUT_UINT32(ctx->state[1], digest, 4); + PUT_UINT32(ctx->state[2], digest, 8); + PUT_UINT32(ctx->state[3], digest, 12); + PUT_UINT32(ctx->state[4], digest, 16); + PUT_UINT32(ctx->state[5], digest, 20); + PUT_UINT32(ctx->state[6], digest, 24); + PUT_UINT32(ctx->state[7], digest, 28); +} diff --git a/httpd/htpasswd.c b/httpd/htpasswd.c index 7c99abf1e..91feea119 100644 --- a/httpd/htpasswd.c +++ b/httpd/htpasswd.c @@ -121,7 +121,12 @@ int main(int argc, char *argv[]) } RNG_initialize(); - get_random(MD5_SIZE, md5_salt); + if (get_random(MD5_SIZE, md5_salt) < 0) + { + fprintf(stderr, "Can't get random data\n" ); + exit(1); + } + RNG_terminate(); base64_encode(md5_salt, MD5_SIZE, b64_salt, sizeof(b64_salt)); diff --git a/ssl/Makefile b/ssl/Makefile index aafe7bc9b..b8dd55a92 100644 --- a/ssl/Makefile +++ b/ssl/Makefile @@ -69,11 +69,11 @@ CRYPTO_OBJ=\ $(CRYPTO_PATH)bigint.o \ $(CRYPTO_PATH)crypto_misc.o \ $(CRYPTO_PATH)hmac.o \ - $(CRYPTO_PATH)md2.o \ $(CRYPTO_PATH)md5.o \ $(CRYPTO_PATH)rc4.o \ $(CRYPTO_PATH)rsa.o \ - $(CRYPTO_PATH)sha1.o + $(CRYPTO_PATH)sha1.o \ + $(CRYPTO_PATH)sha256.o OBJ=\ asn1.o \ diff --git a/ssl/asn1.c b/ssl/asn1.c index 4e468755d..3d6e23055 100644 --- a/ssl/asn1.c +++ b/ssl/asn1.c @@ -40,22 +40,23 @@ #include "crypto.h" #include "crypto_misc.h" -#define SIG_OID_PREFIX_SIZE 8 -#define SIG_IIS6_OID_SIZE 5 -#define SIG_SUBJECT_ALT_NAME_SIZE 3 - /* Must be an RSA algorithm with either SHA1 or MD5 for verifying to work */ -static const uint8_t sig_oid_prefix[SIG_OID_PREFIX_SIZE] = +static const uint8_t sig_oid_prefix[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01 }; -static const uint8_t sig_sha1WithRSAEncrypt[SIG_IIS6_OID_SIZE] = +static const uint8_t sig_sha1WithRSAEncrypt[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1d }; -static const uint8_t sig_subject_alt_name[SIG_SUBJECT_ALT_NAME_SIZE] = +static const uint8_t sig_sha256WithRSAEncrypt[] = +{ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 +}; + +static const uint8_t sig_subject_alt_name[] = { 0x55, 0x1d, 0x11 }; @@ -553,7 +554,7 @@ int asn1_find_oid(const uint8_t* cert, int* offset, int asn1_find_subjectaltname(const uint8_t* cert, int offset) { if (asn1_find_oid(cert, &offset, sig_subject_alt_name, - SIG_SUBJECT_ALT_NAME_SIZE)) + sizeof(sig_subject_alt_name))) { return offset; } @@ -577,17 +578,24 @@ int asn1_signature_type(const uint8_t *cert, len = get_asn1_length(cert, offset); - if (len == 5 && memcmp(sig_sha1WithRSAEncrypt, &cert[*offset], - SIG_IIS6_OID_SIZE) == 0) + if (len == sizeof(sig_sha1WithRSAEncrypt) && + memcmp(sig_sha1WithRSAEncrypt, &cert[*offset], + sizeof(sig_sha1WithRSAEncrypt)) == 0) { x509_ctx->sig_type = SIG_TYPE_SHA1; } + else if (len == sizeof(sig_sha256WithRSAEncrypt) && + memcmp(sig_sha256WithRSAEncrypt, &cert[*offset], + sizeof(sig_sha256WithRSAEncrypt)) == 0) + { + x509_ctx->sig_type = SIG_TYPE_SHA256; + } else { - if (memcmp(sig_oid_prefix, &cert[*offset], SIG_OID_PREFIX_SIZE)) + if (memcmp(sig_oid_prefix, &cert[*offset], sizeof(sig_oid_prefix))) goto end_check_sig; /* unrecognised cert type */ - x509_ctx->sig_type = cert[*offset + SIG_OID_PREFIX_SIZE]; + x509_ctx->sig_type = cert[*offset + sizeof(sig_oid_prefix)]; } *offset += len; diff --git a/ssl/crypto_misc.h b/ssl/crypto_misc.h index 9bbc8e5ca..bc681117b 100644 --- a/ssl/crypto_misc.h +++ b/ssl/crypto_misc.h @@ -126,6 +126,7 @@ const char * x509_display_error(int error); #define SIG_TYPE_MD2 0x02 #define SIG_TYPE_MD5 0x04 #define SIG_TYPE_SHA1 0x05 +#define SIG_TYPE_SHA256 0x0b int get_asn1_length(const uint8_t *buf, int *offset); int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx); diff --git a/ssl/test/camster_duckdns_org.crt b/ssl/test/camster_duckdns_org.crt new file mode 100644 index 000000000..453bafa37 --- /dev/null +++ b/ssl/test/camster_duckdns_org.crt @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFXTCCBEWgAwIBAgIQRKGXkBbin0Hge3vNu4Z04TANBgkqhkiG9w0BAQsFADCB +kDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNjA0BgNV +BAMTLUNPTU9ETyBSU0EgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBD +QTAeFw0xNDExMTIwMDAwMDBaFw0xNzExMTEyMzU5NTlaMFcxITAfBgNVBAsTGERv +bWFpbiBDb250cm9sIFZhbGlkYXRlZDEUMBIGA1UECxMLUG9zaXRpdmVTU0wxHDAa +BgNVBAMTE2NhbXN0ZXIuZHVja2Rucy5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCvKi9/3GOq1pqgnIQR2hTxr1kv17pUzpQeAVOZVCd/q6KbMrsw +ayPj41hJd+EVtu6DV8Zd/Rxv4P6i2HTRWev9aE2+vFfTmhIZG0HUZqs3Fbq6yONn +ox8d7Dsu/vwIkyaIE9mMAYYr81bX86v8cmvCHatCO/lluwUqjnXUjYpMOpTopHjC +hNzUe63ZtUDVmXfTBHneO5GLZqhQSSX7rd33cJzkojGCoPSFP5TUhN5WGyRi+xa2 +bD+Q5xXlC4f/WVXiZxGiGPrWIpQBO5Y5o33S6Vo2ck9Bvg2g1atsR02m+yARtmH3 ++IDlvg7DeyLL3AXgUwDNHnRb0t9LVDXcYOJnAgMBAAGjggHpMIIB5TAfBgNVHSME +GDAWgBSQr2o6lFoL2JDqElZz30O0Oija5zAdBgNVHQ4EFgQUGNRX8FYKZUYa1F4+ +L7nyHOn3ArcwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYw +FAYIKwYBBQUHAwEGCCsGAQUFBwMCME8GA1UdIARIMEYwOgYLKwYBBAGyMQECAgcw +KzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwCAYG +Z4EMAQIBMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9jcmwuY29tb2RvY2EuY29t +L0NPTU9ET1JTQURvbWFpblZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYUG +CCsGAQUFBwEBBHkwdzBPBggrBgEFBQcwAoZDaHR0cDovL2NydC5jb21vZG9jYS5j +b20vQ09NT0RPUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAk +BggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMDcGA1UdEQQwMC6C +E2NhbXN0ZXIuZHVja2Rucy5vcmeCF3d3dy5jYW1zdGVyLmR1Y2tkbnMub3JnMA0G +CSqGSIb3DQEBCwUAA4IBAQBpfJIXHPyoxbXlS1Jy5V4oDpDR+vKRIXXUPDp6GlmK +6w8W7M536W7JamLrT8wbA04hKgtjQkXD8pXZPFHBNJ92Lza5fKB/KiIlObz386lK +Z9AVc10TwWlkZlFYhYVhQ+kpTtcUUdj5QI2org81s9XQoSViVOM8cxIuYk/er20g +jY3Nvdbjg4dtakH1nsITGMYLN+wJglSAq1QGSQ76fLyYhMfF25nNjPYP96SFf1Dd +XinknP2tED6ukzIgfkimlyn2/XIbnz4Xry8ouq4x/cPd8MOcffWt1QWlGIel5B8i +I1vtVHceHSsHjnnNPSkXIn0/lpc5vzVZ+bw9yLt+Lvc6 +-----END CERTIFICATE----- diff --git a/ssl/test/ssltest.c b/ssl/test/ssltest.c index cd7e4732f..b36f0f996 100644 --- a/ssl/test/ssltest.c +++ b/ssl/test/ssltest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2014, Cameron Rich * * All rights reserved. * @@ -302,6 +302,60 @@ end: return res; } +/************************************************************************** + * SHA256 tests + * + * Run through a couple of the SHA-2 tests to verify that SHA256 is correct. + **************************************************************************/ +static int SHA256_test(BI_CTX *bi_ctx) +{ + SHA256_CTX ctx; + uint8_t ct[SHA256_SIZE]; + uint8_t digest[SHA256_SIZE]; + int res = 1; + + { + const char *in_str = "abc"; + bigint *ct_bi = bi_str_import(bi_ctx, + "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"); + bi_export(bi_ctx, ct_bi, ct, SHA256_SIZE); + + SHA256_Init(&ctx); + SHA256_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA256_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA256 # failed\n"); + goto end; + } + } + + { + const char *in_str = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + bigint *ct_bi = bi_str_import(bi_ctx, + "248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1"); + bi_export(bi_ctx, ct_bi, ct, SHA256_SIZE); + + SHA256_Init(&ctx); + SHA256_Update(&ctx, (const uint8_t *)in_str, strlen(in_str)); + SHA256_Final(digest, &ctx); + + if (memcmp(digest, ct, sizeof(ct))) + { + printf("Error: SHA256 #2 failed\n"); + goto end; + } + } + + res = 0; + printf("All SHA256 tests passed\n"); + +end: + return res; +} + /************************************************************************** * MD5 tests * @@ -521,6 +575,8 @@ static int RSA_test(void) int len; uint8_t *buf; + RNG_initialize(); + /* extract the private key elements */ len = get_file("../ssl/test/axTLS.key_1024", &buf); if (asn1_get_private_key(buf, len, &rsa_ctx) < 0) @@ -547,11 +603,16 @@ static int RSA_test(void) goto end; } - RSA_encrypt(rsa_ctx, (const uint8_t *)"abc", 3, enc_data2, 0); + if (RSA_encrypt(rsa_ctx, (const uint8_t *)"abc", 3, enc_data2, 0) < 0) + { + printf("Error: ENCRYPT #2 failed\n"); + goto end; + } + RSA_decrypt(rsa_ctx, enc_data2, dec_data2, sizeof(dec_data2), 1); if (memcmp("abc", dec_data2, 3)) { - printf("Error: ENCRYPT/DECRYPT #2 failed\n"); + printf("Error: DECRYPT #2 failed\n"); goto end; } @@ -560,6 +621,7 @@ static int RSA_test(void) printf("All RSA tests passed\n"); end: + RNG_terminate(); return res; } @@ -648,8 +710,8 @@ static int cert_tests(void) free(buf); ssl_ctx = ssl_ctx_new(0, 0); - len = get_file("../ssl/test/verisign.x509_ca", &buf); - if ((res = add_cert_auth(ssl_ctx, buf, len)) <0) + if ((res = ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, + "../ssl/test/camster_duckdns_org.crt", NULL)) != SSL_OK) { printf("Cert #7\n"); ssl_display_error(res); @@ -657,23 +719,12 @@ static int cert_tests(void) } ssl_ctx_free(ssl_ctx); - free(buf); - - if (get_file("../ssl/test/verisign.x509_my_cert", &buf) < 0 || - x509_new(buf, &len, &x509_ctx)) - { - printf("Cert #8\n"); - ssl_display_error(res); - goto bad_cert; - } - - x509_free(x509_ctx); - free(buf); ssl_ctx = ssl_ctx_new(0, 0); if ((res = ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, "../ssl/test/ms_iis.cer", NULL)) != SSL_OK) { + printf("Cert #9\n"); ssl_display_error(res); goto bad_cert; } @@ -683,14 +734,14 @@ static int cert_tests(void) if (get_file("../ssl/test/qualityssl.com.der", &buf) < 0 || x509_new(buf, &len, &x509_ctx)) { - printf("Cert #9\n"); + printf("Cert #10\n"); res = -1; goto bad_cert; } if (strcmp(x509_ctx->subject_alt_dnsnames[1], "qualityssl.com")) { - printf("Cert #9 (2)\n"); + printf("Cert #11\n"); res = -1; goto bad_cert; } @@ -701,7 +752,7 @@ static int cert_tests(void) if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, "../ssl/test/ca-bundle.crt", NULL)) { - printf("Cert #10\n"); + printf("Cert #12\n"); goto bad_cert; } @@ -2061,64 +2112,64 @@ error: * Header issue * **************************************************************************/ -static void do_header_issue(void) -{ - char axtls_buf[2048]; -#ifndef WIN32 - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); -#endif - sprintf(axtls_buf, "./axssl s_client -connect localhost:%d", g_port); - SYSTEM(axtls_buf); -} - -static int header_issue(void) -{ - FILE *f = fopen("../ssl/test/header_issue.dat", "r"); - int server_fd = -1, client_fd = -1, ret = 1; - uint8_t buf[2048]; - int size = 0; - struct sockaddr_in client_addr; - socklen_t clnt_len = sizeof(client_addr); -#ifndef WIN32 - pthread_t thread; -#endif - - if (f == NULL || (server_fd = server_socket_init(&g_port)) < 0) - goto error; - -#ifndef WIN32 - pthread_create(&thread, NULL, - (void *(*)(void *))do_header_issue, NULL); - pthread_detach(thread); -#else - CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_header_issue, - NULL, 0, NULL); -#endif - if ((client_fd = accept(server_fd, - (struct sockaddr *) &client_addr, &clnt_len)) < 0) - { - ret = SSL_ERROR_SOCK_SETUP_FAILURE; - goto error; - } - - size = fread(buf, 1, sizeof(buf), f); - if (SOCKET_WRITE(client_fd, buf, size) < 0) - { - ret = SSL_ERROR_SOCK_SETUP_FAILURE; - goto error; - } - - usleep(200000); - - ret = 0; -error: - fclose(f); - SOCKET_CLOSE(client_fd); - SOCKET_CLOSE(server_fd); - TTY_FLUSH(); - SYSTEM("killall axssl"); - return ret; -} +//static void do_header_issue(void) +//{ +// char axtls_buf[2048]; +//#ifndef WIN32 +// pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); +//#endif +// sprintf(axtls_buf, "./axssl s_client -connect localhost:%d", g_port); +// SYSTEM(axtls_buf); +//} +// +//static int header_issue(void) +//{ +// FILE *f = fopen("../ssl/test/header_issue.dat", "r"); +// int server_fd = -1, client_fd = -1, ret = 1; +// uint8_t buf[2048]; +// int size = 0; +// struct sockaddr_in client_addr; +// socklen_t clnt_len = sizeof(client_addr); +//#ifndef WIN32 +// pthread_t thread; +//#endif +// +// if (f == NULL || (server_fd = server_socket_init(&g_port)) < 0) +// goto error; +// +//#ifndef WIN32 +// pthread_create(&thread, NULL, +// (void *(*)(void *))do_header_issue, NULL); +// pthread_detach(thread); +//#else +// CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)do_header_issue, +// NULL, 0, NULL); +//#endif +// if ((client_fd = accept(server_fd, +// (struct sockaddr *) &client_addr, &clnt_len)) < 0) +// { +// ret = SSL_ERROR_SOCK_SETUP_FAILURE; +// goto error; +// } +// +// size = fread(buf, 1, sizeof(buf), f); +// if (SOCKET_WRITE(client_fd, buf, size) < 0) +// { +// ret = SSL_ERROR_SOCK_SETUP_FAILURE; +// goto error; +// } +// +// usleep(200000); +// +// ret = 0; +//error: +// fclose(f); +// SOCKET_CLOSE(client_fd); +// SOCKET_CLOSE(server_fd); +// TTY_FLUSH(); +// SYSTEM("killall axssl"); +// return ret; +//} /************************************************************************** * main() @@ -2178,6 +2229,13 @@ int main(int argc, char *argv[]) } TTY_FLUSH(); + if (SHA256_test(bi_ctx)) + { + printf("SHA256 tests failed\n"); + goto cleanup; + } + TTY_FLUSH(); + if (HMAC_test(bi_ctx)) { printf("HMAC tests failed\n"); @@ -2234,11 +2292,11 @@ int main(int argc, char *argv[]) SYSTEM("sh ../ssl/test/killopenssl.sh"); - if (header_issue()) - { - printf("Header tests failed\n"); TTY_FLUSH(); - goto cleanup; - } +// if (header_issue()) +// { +// printf("Header tests failed\n"); TTY_FLUSH(); +// goto cleanup; +// } ret = 0; /* all ok */ printf("**** ALL TESTS PASSED ****\n"); TTY_FLUSH(); diff --git a/ssl/test/verisign.x509_ca b/ssl/test/verisign.x509_ca deleted file mode 100644 index d2ea1289d..000000000 Binary files a/ssl/test/verisign.x509_ca and /dev/null differ diff --git a/ssl/test/verisign.x509_my_cert b/ssl/test/verisign.x509_my_cert deleted file mode 100644 index 426c9ff7f..000000000 Binary files a/ssl/test/verisign.x509_my_cert and /dev/null differ diff --git a/ssl/tls1.c b/ssl/tls1.c index 800decbaa..f89702fb7 100755 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -1075,7 +1075,9 @@ int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length) uint8_t iv_size = ssl->cipher_info->iv_size; uint8_t *t_buf = alloca(msg_length + iv_size); memcpy(t_buf + iv_size, ssl->bm_data, msg_length); - get_random(iv_size, t_buf); + if (get_random(iv_size, t_buf) < 0) + return SSL_NOT_OK; + msg_length += iv_size; memcpy(ssl->bm_data, t_buf, msg_length); } diff --git a/ssl/tls1_clnt.c b/ssl/tls1_clnt.c index 196b40ed3..b557c3b9f 100644 --- a/ssl/tls1_clnt.c +++ b/ssl/tls1_clnt.c @@ -187,7 +187,9 @@ static int send_client_hello(SSL *ssl) *tm_ptr++ = (uint8_t)(((long)tm & 0x00ff0000) >> 16); *tm_ptr++ = (uint8_t)(((long)tm & 0x0000ff00) >> 8); *tm_ptr++ = (uint8_t)(((long)tm & 0x000000ff)); - get_random(SSL_RANDOM_SIZE-4, &buf[10]); + if (get_random(SSL_RANDOM_SIZE-4, &buf[10]) < 0) + return SSL_NOT_OK; + memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE); offset = 6 + SSL_RANDOM_SIZE; @@ -313,7 +315,9 @@ static int send_client_key_xchg(SSL *ssl) premaster_secret[0] = 0x03; /* encode the version number */ premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */ - get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]); + if (get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]) < 0) + return SSL_NOT_OK; + DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx); /* rsa_ctx->bi_ctx is not thread-safe */ diff --git a/ssl/x509.c b/ssl/x509.c index cb007fbbc..815f83ac0 100644 --- a/ssl/x509.c +++ b/ssl/x509.c @@ -120,7 +120,7 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) bi_ctx = x509_ctx->rsa_ctx->bi_ctx; #ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ - /* use the appropriate signature algorithm (SHA1/MD5/MD2) */ + /* use the appropriate signature algorithm (SHA1/MD5/SHA256) */ if (x509_ctx->sig_type == SIG_TYPE_MD5) { MD5_CTX md5_ctx; @@ -139,14 +139,14 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) SHA1_Final(sha_dgst, &sha_ctx); x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE); } - else if (x509_ctx->sig_type == SIG_TYPE_MD2) + else if (x509_ctx->sig_type == SIG_TYPE_SHA256) { - MD2_CTX md2_ctx; - uint8_t md2_dgst[MD2_SIZE]; - MD2_Init(&md2_ctx); - MD2_Update(&md2_ctx, &cert[begin_tbs], end_tbs-begin_tbs); - MD2_Final(md2_dgst, &md2_ctx); - x509_ctx->digest = bi_import(bi_ctx, md2_dgst, MD2_SIZE); + SHA256_CTX sha256_ctx; + uint8_t sha256_dgst[SHA256_SIZE]; + SHA256_Init(&sha256_ctx); + SHA256_Update(&sha256_ctx, &cert[begin_tbs], end_tbs-begin_tbs); + SHA256_Final(sha256_dgst, &sha256_ctx); + x509_ctx->digest = bi_import(bi_ctx, sha256_dgst, SHA256_SIZE); } if (cert[offset] == ASN1_V3_DATA) @@ -483,14 +483,17 @@ void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx) printf("Sig Type:\t\t\t"); switch (cert->sig_type) { + case SIG_TYPE_MD2: + printf("MD2\n"); + break; case SIG_TYPE_MD5: printf("MD5\n"); break; case SIG_TYPE_SHA1: printf("SHA1\n"); break; - case SIG_TYPE_MD2: - printf("MD2\n"); + case SIG_TYPE_SHA256: + printf("SHA256\n"); break; default: printf("Unrecognized: %d\n", cert->sig_type);