/* * Send the initial client hello. */ static int ICACHE_FLASH_ATTR send_client_hello(SSL *ssl) { uint8_t *buf = ssl->bm_data; time_t tm = 0; //time(NULL); wujg : pass compile first uint8_t *tm_ptr = &buf[6]; /* time will go here */ int i, offset; buf[0] = HS_CLIENT_HELLO; buf[1] = 0; buf[2] = 0; /* byte 3 is calculated later */ buf[4] = 0x03; buf[5] = ssl->version & 0x0f; /* client random value - spec says that 1st 4 bytes are big endian time */ *tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24); *tm_ptr++ = (uint8_t)(((long)tm & 0x00ff0000) >> 16); *tm_ptr++ = (uint8_t)(((long)tm & 0x0000ff00) >> 8); *tm_ptr++ = (uint8_t)(((long)tm & 0x000000ff)); 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; /* give session resumption a go */ if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) /* set initially by user */ { buf[offset++] = ssl->sess_id_size; memcpy(&buf[offset], ssl->session_id, ssl->sess_id_size); offset += ssl->sess_id_size; CLR_SSL_FLAG(SSL_SESSION_RESUME); /* clear so we can set later */ } else { /* no session id - because no session resumption just yet */ buf[offset++] = 0; } buf[offset++] = 0; /* number of ciphers */ buf[offset++] = NUM_PROTOCOLS*2;/* number of ciphers */ /* put all our supported protocols in our request */ for (i = 0; i < NUM_PROTOCOLS; i++) { buf[offset++] = 0; /* cipher we are using */ buf[offset++] = system_get_data_of_array_8(ssl_prot_prefs, i); } buf[offset++] = 1; /* no compression */ buf[offset++] = 0; buf[3] = offset - 4; /* handshake size */ return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); }
/** * Set up AES with the key/iv and cipher size. */ void ICACHE_FLASH_ATTR AES_set_key(AES_CTX *ctx, const uint8_t *key, const uint8_t *iv, AES_MODE mode) { int i, ii; uint32_t *W, tmp, tmp2; unsigned char *ip; int words; unsigned char *Rcon_ram = (unsigned char *)SSL_MALLOC(32); switch (mode) { case AES_MODE_128: i = 10; words = 4; break; case AES_MODE_256: i = 14; words = 8; break; default: /* fail silently */ return; } ctx->rounds = i; ctx->key_size = words; W = ctx->ks; for (i = 0; i < words; i+=2) { W[i+0]= ((uint32_t)key[ 0]<<24)| ((uint32_t)key[ 1]<<16)| ((uint32_t)key[ 2]<< 8)| ((uint32_t)key[ 3] ); W[i+1]= ((uint32_t)key[ 4]<<24)| ((uint32_t)key[ 5]<<16)| ((uint32_t)key[ 6]<< 8)| ((uint32_t)key[ 7] ); key += 8; } // ip = Rcon; ip = Rcon_ram; memcpy(ip, Rcon, 32); // align, copy two byte more ii = 4 * (ctx->rounds+1); for (i = words; i<ii; i++) { tmp = W[i-1]; if ((i % words) == 0) { tmp2 =(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp )&0xff)<< 8; tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>> 8)&0xff)<<16; tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>>16)&0xff)<<24; tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>>24) ); tmp=tmp2^(((unsigned int)*ip)<<24); ip++; } if ((words == 8) && ((i % words) == 4)) { tmp2 =(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp )&0xff) ; tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>> 8)&0xff)<< 8; tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>>16)&0xff)<<16; tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>>24) )<<24; tmp=tmp2; }
/* * Process a client hello message. */ static int ICACHE_FLASH_ATTR process_client_hello(SSL *ssl) { uint8_t *buf = ssl->bm_data; int pkt_size = ssl->bm_index; int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE; int ret = SSL_OK; uint8_t version = (buf[4] << 4) + buf[5]; ssl->version = ssl->client_version = version; if (version > SSL_PROTOCOL_VERSION_MAX) { /* use client's version instead */ ssl->version = SSL_PROTOCOL_VERSION_MAX; } else if (version < SSL_PROTOCOL_MIN_VERSION) /* old version supported? */ { ret = SSL_ERROR_INVALID_VERSION; //ssl_display_error(ret); goto error; } memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE); /* process the session id */ id_len = buf[offset++]; if (id_len > SSL_SESSION_ID_SIZE) { return SSL_ERROR_INVALID_SESSION; } #ifndef CONFIG_SSL_SKELETON_MODE ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions, ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL); #endif offset += id_len; cs_len = (buf[offset]<<8) + buf[offset+1]; offset += 3; /* add 1 due to all cipher suites being 8 bit */ PARANOIA_CHECK(pkt_size, offset); /* work out what cipher suite we are going to use - client defines the preference */ for (i = 0; i < cs_len; i += 2) { for (j = 0; j < NUM_PROTOCOLS; j++) { if (system_get_data_of_array_8(ssl_prot_prefs, j) == ((buf[offset+i]<<8) + buf[offset+i+1])) /* got a match? */ { ssl->cipher = system_get_data_of_array_8(ssl_prot_prefs, j); goto do_state; } } } /* ouch! protocol is not supported */ ret = SSL_ERROR_NO_CIPHER; do_state: error: return ret; }