1*0Sstevel@tonic-gate /* ssl/t1_enc.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate /* ==================================================================== 59*0Sstevel@tonic-gate * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 60*0Sstevel@tonic-gate * 61*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 62*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 63*0Sstevel@tonic-gate * are met: 64*0Sstevel@tonic-gate * 65*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 66*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 67*0Sstevel@tonic-gate * 68*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 69*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 70*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 71*0Sstevel@tonic-gate * distribution. 72*0Sstevel@tonic-gate * 73*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 74*0Sstevel@tonic-gate * software must display the following acknowledgment: 75*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 76*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77*0Sstevel@tonic-gate * 78*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79*0Sstevel@tonic-gate * endorse or promote products derived from this software without 80*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 81*0Sstevel@tonic-gate * openssl-core@openssl.org. 82*0Sstevel@tonic-gate * 83*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 84*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 85*0Sstevel@tonic-gate * permission of the OpenSSL Project. 86*0Sstevel@tonic-gate * 87*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 88*0Sstevel@tonic-gate * acknowledgment: 89*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 90*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91*0Sstevel@tonic-gate * 92*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 104*0Sstevel@tonic-gate * ==================================================================== 105*0Sstevel@tonic-gate * 106*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 107*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 108*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 109*0Sstevel@tonic-gate * 110*0Sstevel@tonic-gate */ 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate #include <stdio.h> 113*0Sstevel@tonic-gate #include "ssl_locl.h" 114*0Sstevel@tonic-gate #include <openssl/comp.h> 115*0Sstevel@tonic-gate #include <openssl/evp.h> 116*0Sstevel@tonic-gate #include <openssl/hmac.h> 117*0Sstevel@tonic-gate #include <openssl/md5.h> 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, 120*0Sstevel@tonic-gate int sec_len, unsigned char *seed, int seed_len, 121*0Sstevel@tonic-gate unsigned char *out, int olen) 122*0Sstevel@tonic-gate { 123*0Sstevel@tonic-gate int chunk,n; 124*0Sstevel@tonic-gate unsigned int j; 125*0Sstevel@tonic-gate HMAC_CTX ctx; 126*0Sstevel@tonic-gate HMAC_CTX ctx_tmp; 127*0Sstevel@tonic-gate unsigned char A1[EVP_MAX_MD_SIZE]; 128*0Sstevel@tonic-gate unsigned int A1_len; 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate chunk=EVP_MD_size(md); 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate HMAC_CTX_init(&ctx); 133*0Sstevel@tonic-gate HMAC_CTX_init(&ctx_tmp); 134*0Sstevel@tonic-gate HMAC_Init_ex(&ctx,sec,sec_len,md, NULL); 135*0Sstevel@tonic-gate HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL); 136*0Sstevel@tonic-gate HMAC_Update(&ctx,seed,seed_len); 137*0Sstevel@tonic-gate HMAC_Final(&ctx,A1,&A1_len); 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate n=0; 140*0Sstevel@tonic-gate for (;;) 141*0Sstevel@tonic-gate { 142*0Sstevel@tonic-gate HMAC_Init_ex(&ctx,NULL,0,NULL,NULL); /* re-init */ 143*0Sstevel@tonic-gate HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */ 144*0Sstevel@tonic-gate HMAC_Update(&ctx,A1,A1_len); 145*0Sstevel@tonic-gate HMAC_Update(&ctx_tmp,A1,A1_len); 146*0Sstevel@tonic-gate HMAC_Update(&ctx,seed,seed_len); 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate if (olen > chunk) 149*0Sstevel@tonic-gate { 150*0Sstevel@tonic-gate HMAC_Final(&ctx,out,&j); 151*0Sstevel@tonic-gate out+=j; 152*0Sstevel@tonic-gate olen-=j; 153*0Sstevel@tonic-gate HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */ 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate else /* last one */ 156*0Sstevel@tonic-gate { 157*0Sstevel@tonic-gate HMAC_Final(&ctx,A1,&A1_len); 158*0Sstevel@tonic-gate memcpy(out,A1,olen); 159*0Sstevel@tonic-gate break; 160*0Sstevel@tonic-gate } 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate HMAC_CTX_cleanup(&ctx); 163*0Sstevel@tonic-gate HMAC_CTX_cleanup(&ctx_tmp); 164*0Sstevel@tonic-gate OPENSSL_cleanse(A1,sizeof(A1)); 165*0Sstevel@tonic-gate } 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1, 168*0Sstevel@tonic-gate unsigned char *label, int label_len, 169*0Sstevel@tonic-gate const unsigned char *sec, int slen, unsigned char *out1, 170*0Sstevel@tonic-gate unsigned char *out2, int olen) 171*0Sstevel@tonic-gate { 172*0Sstevel@tonic-gate int len,i; 173*0Sstevel@tonic-gate const unsigned char *S1,*S2; 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate len=slen/2; 176*0Sstevel@tonic-gate S1=sec; 177*0Sstevel@tonic-gate S2= &(sec[len]); 178*0Sstevel@tonic-gate len+=(slen&1); /* add for odd, make longer */ 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen); 182*0Sstevel@tonic-gate tls1_P_hash(sha1,S2,len,label,label_len,out2,olen); 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate for (i=0; i<olen; i++) 185*0Sstevel@tonic-gate out1[i]^=out2[i]; 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate static void tls1_generate_key_block(SSL *s, unsigned char *km, 189*0Sstevel@tonic-gate unsigned char *tmp, int num) 190*0Sstevel@tonic-gate { 191*0Sstevel@tonic-gate unsigned char *p; 192*0Sstevel@tonic-gate unsigned char buf[SSL3_RANDOM_SIZE*2+ 193*0Sstevel@tonic-gate TLS_MD_MAX_CONST_SIZE]; 194*0Sstevel@tonic-gate p=buf; 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate memcpy(p,TLS_MD_KEY_EXPANSION_CONST, 197*0Sstevel@tonic-gate TLS_MD_KEY_EXPANSION_CONST_SIZE); 198*0Sstevel@tonic-gate p+=TLS_MD_KEY_EXPANSION_CONST_SIZE; 199*0Sstevel@tonic-gate memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); 200*0Sstevel@tonic-gate p+=SSL3_RANDOM_SIZE; 201*0Sstevel@tonic-gate memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); 202*0Sstevel@tonic-gate p+=SSL3_RANDOM_SIZE; 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf), 205*0Sstevel@tonic-gate s->session->master_key,s->session->master_key_length, 206*0Sstevel@tonic-gate km,tmp,num); 207*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 208*0Sstevel@tonic-gate printf("tls1_generate_key_block() ==> %d byte master_key =\n\t", 209*0Sstevel@tonic-gate s->session->master_key_length); 210*0Sstevel@tonic-gate { 211*0Sstevel@tonic-gate int i; 212*0Sstevel@tonic-gate for (i=0; i < s->session->master_key_length; i++) 213*0Sstevel@tonic-gate { 214*0Sstevel@tonic-gate printf("%02X", s->session->master_key[i]); 215*0Sstevel@tonic-gate } 216*0Sstevel@tonic-gate printf("\n"); } 217*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate int tls1_change_cipher_state(SSL *s, int which) 221*0Sstevel@tonic-gate { 222*0Sstevel@tonic-gate static const unsigned char empty[]=""; 223*0Sstevel@tonic-gate unsigned char *p,*key_block,*mac_secret; 224*0Sstevel@tonic-gate unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+ 225*0Sstevel@tonic-gate SSL3_RANDOM_SIZE*2]; 226*0Sstevel@tonic-gate unsigned char tmp1[EVP_MAX_KEY_LENGTH]; 227*0Sstevel@tonic-gate unsigned char tmp2[EVP_MAX_KEY_LENGTH]; 228*0Sstevel@tonic-gate unsigned char iv1[EVP_MAX_IV_LENGTH*2]; 229*0Sstevel@tonic-gate unsigned char iv2[EVP_MAX_IV_LENGTH*2]; 230*0Sstevel@tonic-gate unsigned char *ms,*key,*iv,*er1,*er2; 231*0Sstevel@tonic-gate int client_write; 232*0Sstevel@tonic-gate EVP_CIPHER_CTX *dd; 233*0Sstevel@tonic-gate const EVP_CIPHER *c; 234*0Sstevel@tonic-gate const SSL_COMP *comp; 235*0Sstevel@tonic-gate const EVP_MD *m; 236*0Sstevel@tonic-gate int is_export,n,i,j,k,exp_label_len,cl; 237*0Sstevel@tonic-gate int reuse_dd = 0; 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); 240*0Sstevel@tonic-gate c=s->s3->tmp.new_sym_enc; 241*0Sstevel@tonic-gate m=s->s3->tmp.new_hash; 242*0Sstevel@tonic-gate comp=s->s3->tmp.new_compression; 243*0Sstevel@tonic-gate key_block=s->s3->tmp.key_block; 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 246*0Sstevel@tonic-gate printf("tls1_change_cipher_state(which= %d) w/\n", which); 247*0Sstevel@tonic-gate printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms, 248*0Sstevel@tonic-gate comp); 249*0Sstevel@tonic-gate printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); 250*0Sstevel@tonic-gate printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", 251*0Sstevel@tonic-gate c->nid,c->block_size,c->key_len,c->iv_len); 252*0Sstevel@tonic-gate printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length); 253*0Sstevel@tonic-gate { 254*0Sstevel@tonic-gate int i; 255*0Sstevel@tonic-gate for (i=0; i<s->s3->tmp.key_block_length; i++) 256*0Sstevel@tonic-gate printf("%02x", key_block[i]); printf("\n"); 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate if (which & SSL3_CC_READ) 261*0Sstevel@tonic-gate { 262*0Sstevel@tonic-gate if (s->enc_read_ctx != NULL) 263*0Sstevel@tonic-gate reuse_dd = 1; 264*0Sstevel@tonic-gate else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) 265*0Sstevel@tonic-gate goto err; 266*0Sstevel@tonic-gate dd= s->enc_read_ctx; 267*0Sstevel@tonic-gate s->read_hash=m; 268*0Sstevel@tonic-gate if (s->expand != NULL) 269*0Sstevel@tonic-gate { 270*0Sstevel@tonic-gate COMP_CTX_free(s->expand); 271*0Sstevel@tonic-gate s->expand=NULL; 272*0Sstevel@tonic-gate } 273*0Sstevel@tonic-gate if (comp != NULL) 274*0Sstevel@tonic-gate { 275*0Sstevel@tonic-gate s->expand=COMP_CTX_new(comp->method); 276*0Sstevel@tonic-gate if (s->expand == NULL) 277*0Sstevel@tonic-gate { 278*0Sstevel@tonic-gate SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); 279*0Sstevel@tonic-gate goto err2; 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate if (s->s3->rrec.comp == NULL) 282*0Sstevel@tonic-gate s->s3->rrec.comp=(unsigned char *) 283*0Sstevel@tonic-gate OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); 284*0Sstevel@tonic-gate if (s->s3->rrec.comp == NULL) 285*0Sstevel@tonic-gate goto err; 286*0Sstevel@tonic-gate } 287*0Sstevel@tonic-gate memset(&(s->s3->read_sequence[0]),0,8); 288*0Sstevel@tonic-gate mac_secret= &(s->s3->read_mac_secret[0]); 289*0Sstevel@tonic-gate } 290*0Sstevel@tonic-gate else 291*0Sstevel@tonic-gate { 292*0Sstevel@tonic-gate if (s->enc_write_ctx != NULL) 293*0Sstevel@tonic-gate reuse_dd = 1; 294*0Sstevel@tonic-gate else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) 295*0Sstevel@tonic-gate goto err; 296*0Sstevel@tonic-gate if ((s->enc_write_ctx == NULL) && 297*0Sstevel@tonic-gate ((s->enc_write_ctx=(EVP_CIPHER_CTX *) 298*0Sstevel@tonic-gate OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) 299*0Sstevel@tonic-gate goto err; 300*0Sstevel@tonic-gate dd= s->enc_write_ctx; 301*0Sstevel@tonic-gate s->write_hash=m; 302*0Sstevel@tonic-gate if (s->compress != NULL) 303*0Sstevel@tonic-gate { 304*0Sstevel@tonic-gate COMP_CTX_free(s->compress); 305*0Sstevel@tonic-gate s->compress=NULL; 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate if (comp != NULL) 308*0Sstevel@tonic-gate { 309*0Sstevel@tonic-gate s->compress=COMP_CTX_new(comp->method); 310*0Sstevel@tonic-gate if (s->compress == NULL) 311*0Sstevel@tonic-gate { 312*0Sstevel@tonic-gate SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); 313*0Sstevel@tonic-gate goto err2; 314*0Sstevel@tonic-gate } 315*0Sstevel@tonic-gate } 316*0Sstevel@tonic-gate memset(&(s->s3->write_sequence[0]),0,8); 317*0Sstevel@tonic-gate mac_secret= &(s->s3->write_mac_secret[0]); 318*0Sstevel@tonic-gate } 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate if (reuse_dd) 321*0Sstevel@tonic-gate EVP_CIPHER_CTX_cleanup(dd); 322*0Sstevel@tonic-gate EVP_CIPHER_CTX_init(dd); 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate p=s->s3->tmp.key_block; 325*0Sstevel@tonic-gate i=EVP_MD_size(m); 326*0Sstevel@tonic-gate cl=EVP_CIPHER_key_length(c); 327*0Sstevel@tonic-gate j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? 328*0Sstevel@tonic-gate cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; 329*0Sstevel@tonic-gate /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ 330*0Sstevel@tonic-gate k=EVP_CIPHER_iv_length(c); 331*0Sstevel@tonic-gate er1= &(s->s3->client_random[0]); 332*0Sstevel@tonic-gate er2= &(s->s3->server_random[0]); 333*0Sstevel@tonic-gate if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || 334*0Sstevel@tonic-gate (which == SSL3_CHANGE_CIPHER_SERVER_READ)) 335*0Sstevel@tonic-gate { 336*0Sstevel@tonic-gate ms= &(p[ 0]); n=i+i; 337*0Sstevel@tonic-gate key= &(p[ n]); n+=j+j; 338*0Sstevel@tonic-gate iv= &(p[ n]); n+=k+k; 339*0Sstevel@tonic-gate exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; 340*0Sstevel@tonic-gate exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; 341*0Sstevel@tonic-gate client_write=1; 342*0Sstevel@tonic-gate } 343*0Sstevel@tonic-gate else 344*0Sstevel@tonic-gate { 345*0Sstevel@tonic-gate n=i; 346*0Sstevel@tonic-gate ms= &(p[ n]); n+=i+j; 347*0Sstevel@tonic-gate key= &(p[ n]); n+=j+k; 348*0Sstevel@tonic-gate iv= &(p[ n]); n+=k; 349*0Sstevel@tonic-gate exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; 350*0Sstevel@tonic-gate exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; 351*0Sstevel@tonic-gate client_write=0; 352*0Sstevel@tonic-gate } 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate if (n > s->s3->tmp.key_block_length) 355*0Sstevel@tonic-gate { 356*0Sstevel@tonic-gate SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); 357*0Sstevel@tonic-gate goto err2; 358*0Sstevel@tonic-gate } 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate memcpy(mac_secret,ms,i); 361*0Sstevel@tonic-gate #ifdef TLS_DEBUG 362*0Sstevel@tonic-gate printf("which = %04X\nmac key=",which); 363*0Sstevel@tonic-gate { int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); } 364*0Sstevel@tonic-gate #endif 365*0Sstevel@tonic-gate if (is_export) 366*0Sstevel@tonic-gate { 367*0Sstevel@tonic-gate /* In here I set both the read and write key/iv to the 368*0Sstevel@tonic-gate * same value since only the correct one will be used :-). 369*0Sstevel@tonic-gate */ 370*0Sstevel@tonic-gate p=buf; 371*0Sstevel@tonic-gate memcpy(p,exp_label,exp_label_len); 372*0Sstevel@tonic-gate p+=exp_label_len; 373*0Sstevel@tonic-gate memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); 374*0Sstevel@tonic-gate p+=SSL3_RANDOM_SIZE; 375*0Sstevel@tonic-gate memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); 376*0Sstevel@tonic-gate p+=SSL3_RANDOM_SIZE; 377*0Sstevel@tonic-gate tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),key,j, 378*0Sstevel@tonic-gate tmp1,tmp2,EVP_CIPHER_key_length(c)); 379*0Sstevel@tonic-gate key=tmp1; 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate if (k > 0) 382*0Sstevel@tonic-gate { 383*0Sstevel@tonic-gate p=buf; 384*0Sstevel@tonic-gate memcpy(p,TLS_MD_IV_BLOCK_CONST, 385*0Sstevel@tonic-gate TLS_MD_IV_BLOCK_CONST_SIZE); 386*0Sstevel@tonic-gate p+=TLS_MD_IV_BLOCK_CONST_SIZE; 387*0Sstevel@tonic-gate memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); 388*0Sstevel@tonic-gate p+=SSL3_RANDOM_SIZE; 389*0Sstevel@tonic-gate memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); 390*0Sstevel@tonic-gate p+=SSL3_RANDOM_SIZE; 391*0Sstevel@tonic-gate tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,empty,0, 392*0Sstevel@tonic-gate iv1,iv2,k*2); 393*0Sstevel@tonic-gate if (client_write) 394*0Sstevel@tonic-gate iv=iv1; 395*0Sstevel@tonic-gate else 396*0Sstevel@tonic-gate iv= &(iv1[k]); 397*0Sstevel@tonic-gate } 398*0Sstevel@tonic-gate } 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate s->session->key_arg_length=0; 401*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 402*0Sstevel@tonic-gate { 403*0Sstevel@tonic-gate int i; 404*0Sstevel@tonic-gate printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); 405*0Sstevel@tonic-gate printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]); 406*0Sstevel@tonic-gate printf("\n"); 407*0Sstevel@tonic-gate printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]); 408*0Sstevel@tonic-gate printf("\n"); 409*0Sstevel@tonic-gate } 410*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); 413*0Sstevel@tonic-gate #ifdef TLS_DEBUG 414*0Sstevel@tonic-gate printf("which = %04X\nkey=",which); 415*0Sstevel@tonic-gate { int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); } 416*0Sstevel@tonic-gate printf("\niv="); 417*0Sstevel@tonic-gate { int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); } 418*0Sstevel@tonic-gate printf("\n"); 419*0Sstevel@tonic-gate #endif 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate OPENSSL_cleanse(tmp1,sizeof(tmp1)); 422*0Sstevel@tonic-gate OPENSSL_cleanse(tmp2,sizeof(tmp1)); 423*0Sstevel@tonic-gate OPENSSL_cleanse(iv1,sizeof(iv1)); 424*0Sstevel@tonic-gate OPENSSL_cleanse(iv2,sizeof(iv2)); 425*0Sstevel@tonic-gate return(1); 426*0Sstevel@tonic-gate err: 427*0Sstevel@tonic-gate SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); 428*0Sstevel@tonic-gate err2: 429*0Sstevel@tonic-gate return(0); 430*0Sstevel@tonic-gate } 431*0Sstevel@tonic-gate 432*0Sstevel@tonic-gate int tls1_setup_key_block(SSL *s) 433*0Sstevel@tonic-gate { 434*0Sstevel@tonic-gate unsigned char *p1,*p2; 435*0Sstevel@tonic-gate const EVP_CIPHER *c; 436*0Sstevel@tonic-gate const EVP_MD *hash; 437*0Sstevel@tonic-gate int num; 438*0Sstevel@tonic-gate SSL_COMP *comp; 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 441*0Sstevel@tonic-gate printf ("tls1_setup_key_block()\n"); 442*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 443*0Sstevel@tonic-gate 444*0Sstevel@tonic-gate if (s->s3->tmp.key_block_length != 0) 445*0Sstevel@tonic-gate return(1); 446*0Sstevel@tonic-gate 447*0Sstevel@tonic-gate if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) 448*0Sstevel@tonic-gate { 449*0Sstevel@tonic-gate SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); 450*0Sstevel@tonic-gate return(0); 451*0Sstevel@tonic-gate } 452*0Sstevel@tonic-gate 453*0Sstevel@tonic-gate s->s3->tmp.new_sym_enc=c; 454*0Sstevel@tonic-gate s->s3->tmp.new_hash=hash; 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gate num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); 457*0Sstevel@tonic-gate num*=2; 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate ssl3_cleanup_key_block(s); 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL) 462*0Sstevel@tonic-gate goto err; 463*0Sstevel@tonic-gate if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) 464*0Sstevel@tonic-gate goto err; 465*0Sstevel@tonic-gate 466*0Sstevel@tonic-gate s->s3->tmp.key_block_length=num; 467*0Sstevel@tonic-gate s->s3->tmp.key_block=p1; 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate #ifdef TLS_DEBUG 471*0Sstevel@tonic-gate printf("client random\n"); 472*0Sstevel@tonic-gate { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); } 473*0Sstevel@tonic-gate printf("server random\n"); 474*0Sstevel@tonic-gate { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); } 475*0Sstevel@tonic-gate printf("pre-master\n"); 476*0Sstevel@tonic-gate { int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } 477*0Sstevel@tonic-gate #endif 478*0Sstevel@tonic-gate tls1_generate_key_block(s,p1,p2,num); 479*0Sstevel@tonic-gate OPENSSL_cleanse(p2,num); 480*0Sstevel@tonic-gate OPENSSL_free(p2); 481*0Sstevel@tonic-gate #ifdef TLS_DEBUG 482*0Sstevel@tonic-gate printf("\nkey block\n"); 483*0Sstevel@tonic-gate { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } 484*0Sstevel@tonic-gate #endif 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) 487*0Sstevel@tonic-gate { 488*0Sstevel@tonic-gate /* enable vulnerability countermeasure for CBC ciphers with 489*0Sstevel@tonic-gate * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) 490*0Sstevel@tonic-gate */ 491*0Sstevel@tonic-gate s->s3->need_empty_fragments = 1; 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate if (s->session->cipher != NULL) 494*0Sstevel@tonic-gate { 495*0Sstevel@tonic-gate if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL) 496*0Sstevel@tonic-gate s->s3->need_empty_fragments = 0; 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RC4 499*0Sstevel@tonic-gate if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4) 500*0Sstevel@tonic-gate s->s3->need_empty_fragments = 0; 501*0Sstevel@tonic-gate #endif 502*0Sstevel@tonic-gate } 503*0Sstevel@tonic-gate } 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gate return(1); 506*0Sstevel@tonic-gate err: 507*0Sstevel@tonic-gate SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); 508*0Sstevel@tonic-gate return(0); 509*0Sstevel@tonic-gate } 510*0Sstevel@tonic-gate 511*0Sstevel@tonic-gate int tls1_enc(SSL *s, int send) 512*0Sstevel@tonic-gate { 513*0Sstevel@tonic-gate SSL3_RECORD *rec; 514*0Sstevel@tonic-gate EVP_CIPHER_CTX *ds; 515*0Sstevel@tonic-gate unsigned long l; 516*0Sstevel@tonic-gate int bs,i,ii,j,k,n=0; 517*0Sstevel@tonic-gate const EVP_CIPHER *enc; 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate if (send) 520*0Sstevel@tonic-gate { 521*0Sstevel@tonic-gate if (s->write_hash != NULL) 522*0Sstevel@tonic-gate n=EVP_MD_size(s->write_hash); 523*0Sstevel@tonic-gate ds=s->enc_write_ctx; 524*0Sstevel@tonic-gate rec= &(s->s3->wrec); 525*0Sstevel@tonic-gate if (s->enc_write_ctx == NULL) 526*0Sstevel@tonic-gate enc=NULL; 527*0Sstevel@tonic-gate else 528*0Sstevel@tonic-gate enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); 529*0Sstevel@tonic-gate } 530*0Sstevel@tonic-gate else 531*0Sstevel@tonic-gate { 532*0Sstevel@tonic-gate if (s->read_hash != NULL) 533*0Sstevel@tonic-gate n=EVP_MD_size(s->read_hash); 534*0Sstevel@tonic-gate ds=s->enc_read_ctx; 535*0Sstevel@tonic-gate rec= &(s->s3->rrec); 536*0Sstevel@tonic-gate if (s->enc_read_ctx == NULL) 537*0Sstevel@tonic-gate enc=NULL; 538*0Sstevel@tonic-gate else 539*0Sstevel@tonic-gate enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx); 540*0Sstevel@tonic-gate } 541*0Sstevel@tonic-gate 542*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 543*0Sstevel@tonic-gate printf("tls1_enc(%d)\n", send); 544*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 545*0Sstevel@tonic-gate 546*0Sstevel@tonic-gate if ((s->session == NULL) || (ds == NULL) || 547*0Sstevel@tonic-gate (enc == NULL)) 548*0Sstevel@tonic-gate { 549*0Sstevel@tonic-gate memmove(rec->data,rec->input,rec->length); 550*0Sstevel@tonic-gate rec->input=rec->data; 551*0Sstevel@tonic-gate } 552*0Sstevel@tonic-gate else 553*0Sstevel@tonic-gate { 554*0Sstevel@tonic-gate l=rec->length; 555*0Sstevel@tonic-gate bs=EVP_CIPHER_block_size(ds->cipher); 556*0Sstevel@tonic-gate 557*0Sstevel@tonic-gate if ((bs != 1) && send) 558*0Sstevel@tonic-gate { 559*0Sstevel@tonic-gate i=bs-((int)l%bs); 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate /* Add weird padding of upto 256 bytes */ 562*0Sstevel@tonic-gate 563*0Sstevel@tonic-gate /* we need to add 'i' padding bytes of value j */ 564*0Sstevel@tonic-gate j=i-1; 565*0Sstevel@tonic-gate if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) 566*0Sstevel@tonic-gate { 567*0Sstevel@tonic-gate if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) 568*0Sstevel@tonic-gate j++; 569*0Sstevel@tonic-gate } 570*0Sstevel@tonic-gate for (k=(int)l; k<(int)(l+i); k++) 571*0Sstevel@tonic-gate rec->input[k]=j; 572*0Sstevel@tonic-gate l+=i; 573*0Sstevel@tonic-gate rec->length+=i; 574*0Sstevel@tonic-gate } 575*0Sstevel@tonic-gate 576*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 577*0Sstevel@tonic-gate { 578*0Sstevel@tonic-gate unsigned long ui; 579*0Sstevel@tonic-gate printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", 580*0Sstevel@tonic-gate ds,rec->data,rec->input,l); 581*0Sstevel@tonic-gate printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", 582*0Sstevel@tonic-gate ds->buf_len, ds->cipher->key_len, 583*0Sstevel@tonic-gate DES_KEY_SZ, DES_SCHEDULE_SZ, 584*0Sstevel@tonic-gate ds->cipher->iv_len); 585*0Sstevel@tonic-gate printf("\t\tIV: "); 586*0Sstevel@tonic-gate for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); 587*0Sstevel@tonic-gate printf("\n"); 588*0Sstevel@tonic-gate printf("\trec->input="); 589*0Sstevel@tonic-gate for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]); 590*0Sstevel@tonic-gate printf("\n"); 591*0Sstevel@tonic-gate } 592*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 593*0Sstevel@tonic-gate 594*0Sstevel@tonic-gate if (!send) 595*0Sstevel@tonic-gate { 596*0Sstevel@tonic-gate if (l == 0 || l%bs != 0) 597*0Sstevel@tonic-gate { 598*0Sstevel@tonic-gate SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); 599*0Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); 600*0Sstevel@tonic-gate return 0; 601*0Sstevel@tonic-gate } 602*0Sstevel@tonic-gate } 603*0Sstevel@tonic-gate 604*0Sstevel@tonic-gate EVP_Cipher(ds,rec->data,rec->input,l); 605*0Sstevel@tonic-gate 606*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 607*0Sstevel@tonic-gate { 608*0Sstevel@tonic-gate unsigned long i; 609*0Sstevel@tonic-gate printf("\trec->data="); 610*0Sstevel@tonic-gate for (i=0; i<l; i++) 611*0Sstevel@tonic-gate printf(" %02x", rec->data[i]); printf("\n"); 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 614*0Sstevel@tonic-gate 615*0Sstevel@tonic-gate if ((bs != 1) && !send) 616*0Sstevel@tonic-gate { 617*0Sstevel@tonic-gate ii=i=rec->data[l-1]; /* padding_length */ 618*0Sstevel@tonic-gate i++; 619*0Sstevel@tonic-gate if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) 620*0Sstevel@tonic-gate { 621*0Sstevel@tonic-gate /* First packet is even in size, so check */ 622*0Sstevel@tonic-gate if ((memcmp(s->s3->read_sequence, 623*0Sstevel@tonic-gate "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) 624*0Sstevel@tonic-gate s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; 625*0Sstevel@tonic-gate if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) 626*0Sstevel@tonic-gate i--; 627*0Sstevel@tonic-gate } 628*0Sstevel@tonic-gate /* TLS 1.0 does not bound the number of padding bytes by the block size. 629*0Sstevel@tonic-gate * All of them must have value 'padding_length'. */ 630*0Sstevel@tonic-gate if (i > (int)rec->length) 631*0Sstevel@tonic-gate { 632*0Sstevel@tonic-gate /* Incorrect padding. SSLerr() and ssl3_alert are done 633*0Sstevel@tonic-gate * by caller: we don't want to reveal whether this is 634*0Sstevel@tonic-gate * a decryption error or a MAC verification failure 635*0Sstevel@tonic-gate * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ 636*0Sstevel@tonic-gate return -1; 637*0Sstevel@tonic-gate } 638*0Sstevel@tonic-gate for (j=(int)(l-i); j<(int)l; j++) 639*0Sstevel@tonic-gate { 640*0Sstevel@tonic-gate if (rec->data[j] != ii) 641*0Sstevel@tonic-gate { 642*0Sstevel@tonic-gate /* Incorrect padding */ 643*0Sstevel@tonic-gate return -1; 644*0Sstevel@tonic-gate } 645*0Sstevel@tonic-gate } 646*0Sstevel@tonic-gate rec->length-=i; 647*0Sstevel@tonic-gate } 648*0Sstevel@tonic-gate } 649*0Sstevel@tonic-gate return(1); 650*0Sstevel@tonic-gate } 651*0Sstevel@tonic-gate 652*0Sstevel@tonic-gate int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in_ctx, unsigned char *out) 653*0Sstevel@tonic-gate { 654*0Sstevel@tonic-gate unsigned int ret; 655*0Sstevel@tonic-gate EVP_MD_CTX ctx; 656*0Sstevel@tonic-gate 657*0Sstevel@tonic-gate EVP_MD_CTX_init(&ctx); 658*0Sstevel@tonic-gate EVP_MD_CTX_copy_ex(&ctx,in_ctx); 659*0Sstevel@tonic-gate EVP_DigestFinal_ex(&ctx,out,&ret); 660*0Sstevel@tonic-gate EVP_MD_CTX_cleanup(&ctx); 661*0Sstevel@tonic-gate return((int)ret); 662*0Sstevel@tonic-gate } 663*0Sstevel@tonic-gate 664*0Sstevel@tonic-gate int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx, 665*0Sstevel@tonic-gate const char *str, int slen, unsigned char *out) 666*0Sstevel@tonic-gate { 667*0Sstevel@tonic-gate unsigned int i; 668*0Sstevel@tonic-gate EVP_MD_CTX ctx; 669*0Sstevel@tonic-gate unsigned char buf[TLS_MD_MAX_CONST_SIZE+MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; 670*0Sstevel@tonic-gate unsigned char *q,buf2[12]; 671*0Sstevel@tonic-gate 672*0Sstevel@tonic-gate q=buf; 673*0Sstevel@tonic-gate memcpy(q,str,slen); 674*0Sstevel@tonic-gate q+=slen; 675*0Sstevel@tonic-gate 676*0Sstevel@tonic-gate EVP_MD_CTX_init(&ctx); 677*0Sstevel@tonic-gate EVP_MD_CTX_copy_ex(&ctx,in1_ctx); 678*0Sstevel@tonic-gate EVP_DigestFinal_ex(&ctx,q,&i); 679*0Sstevel@tonic-gate q+=i; 680*0Sstevel@tonic-gate EVP_MD_CTX_copy_ex(&ctx,in2_ctx); 681*0Sstevel@tonic-gate EVP_DigestFinal_ex(&ctx,q,&i); 682*0Sstevel@tonic-gate q+=i; 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(q-buf), 685*0Sstevel@tonic-gate s->session->master_key,s->session->master_key_length, 686*0Sstevel@tonic-gate out,buf2,sizeof buf2); 687*0Sstevel@tonic-gate EVP_MD_CTX_cleanup(&ctx); 688*0Sstevel@tonic-gate 689*0Sstevel@tonic-gate return sizeof buf2; 690*0Sstevel@tonic-gate } 691*0Sstevel@tonic-gate 692*0Sstevel@tonic-gate int tls1_mac(SSL *ssl, unsigned char *md, int send) 693*0Sstevel@tonic-gate { 694*0Sstevel@tonic-gate SSL3_RECORD *rec; 695*0Sstevel@tonic-gate unsigned char *mac_sec,*seq; 696*0Sstevel@tonic-gate const EVP_MD *hash; 697*0Sstevel@tonic-gate unsigned int md_size; 698*0Sstevel@tonic-gate int i; 699*0Sstevel@tonic-gate HMAC_CTX hmac; 700*0Sstevel@tonic-gate unsigned char buf[5]; 701*0Sstevel@tonic-gate 702*0Sstevel@tonic-gate if (send) 703*0Sstevel@tonic-gate { 704*0Sstevel@tonic-gate rec= &(ssl->s3->wrec); 705*0Sstevel@tonic-gate mac_sec= &(ssl->s3->write_mac_secret[0]); 706*0Sstevel@tonic-gate seq= &(ssl->s3->write_sequence[0]); 707*0Sstevel@tonic-gate hash=ssl->write_hash; 708*0Sstevel@tonic-gate } 709*0Sstevel@tonic-gate else 710*0Sstevel@tonic-gate { 711*0Sstevel@tonic-gate rec= &(ssl->s3->rrec); 712*0Sstevel@tonic-gate mac_sec= &(ssl->s3->read_mac_secret[0]); 713*0Sstevel@tonic-gate seq= &(ssl->s3->read_sequence[0]); 714*0Sstevel@tonic-gate hash=ssl->read_hash; 715*0Sstevel@tonic-gate } 716*0Sstevel@tonic-gate 717*0Sstevel@tonic-gate md_size=EVP_MD_size(hash); 718*0Sstevel@tonic-gate 719*0Sstevel@tonic-gate buf[0]=rec->type; 720*0Sstevel@tonic-gate buf[1]=TLS1_VERSION_MAJOR; 721*0Sstevel@tonic-gate buf[2]=TLS1_VERSION_MINOR; 722*0Sstevel@tonic-gate buf[3]=rec->length>>8; 723*0Sstevel@tonic-gate buf[4]=rec->length&0xff; 724*0Sstevel@tonic-gate 725*0Sstevel@tonic-gate /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ 726*0Sstevel@tonic-gate HMAC_CTX_init(&hmac); 727*0Sstevel@tonic-gate HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL); 728*0Sstevel@tonic-gate HMAC_Update(&hmac,seq,8); 729*0Sstevel@tonic-gate HMAC_Update(&hmac,buf,5); 730*0Sstevel@tonic-gate HMAC_Update(&hmac,rec->input,rec->length); 731*0Sstevel@tonic-gate HMAC_Final(&hmac,md,&md_size); 732*0Sstevel@tonic-gate HMAC_CTX_cleanup(&hmac); 733*0Sstevel@tonic-gate 734*0Sstevel@tonic-gate #ifdef TLS_DEBUG 735*0Sstevel@tonic-gate printf("sec="); 736*0Sstevel@tonic-gate {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); } 737*0Sstevel@tonic-gate printf("seq="); 738*0Sstevel@tonic-gate {int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); } 739*0Sstevel@tonic-gate printf("buf="); 740*0Sstevel@tonic-gate {int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); } 741*0Sstevel@tonic-gate printf("rec="); 742*0Sstevel@tonic-gate {unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); } 743*0Sstevel@tonic-gate #endif 744*0Sstevel@tonic-gate 745*0Sstevel@tonic-gate for (i=7; i>=0; i--) 746*0Sstevel@tonic-gate { 747*0Sstevel@tonic-gate ++seq[i]; 748*0Sstevel@tonic-gate if (seq[i] != 0) break; 749*0Sstevel@tonic-gate } 750*0Sstevel@tonic-gate 751*0Sstevel@tonic-gate #ifdef TLS_DEBUG 752*0Sstevel@tonic-gate {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); } 753*0Sstevel@tonic-gate #endif 754*0Sstevel@tonic-gate return(md_size); 755*0Sstevel@tonic-gate } 756*0Sstevel@tonic-gate 757*0Sstevel@tonic-gate int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, 758*0Sstevel@tonic-gate int len) 759*0Sstevel@tonic-gate { 760*0Sstevel@tonic-gate unsigned char buf[SSL3_RANDOM_SIZE*2+TLS_MD_MASTER_SECRET_CONST_SIZE]; 761*0Sstevel@tonic-gate unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; 762*0Sstevel@tonic-gate 763*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 764*0Sstevel@tonic-gate printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len); 765*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 766*0Sstevel@tonic-gate 767*0Sstevel@tonic-gate /* Setup the stuff to munge */ 768*0Sstevel@tonic-gate memcpy(buf,TLS_MD_MASTER_SECRET_CONST, 769*0Sstevel@tonic-gate TLS_MD_MASTER_SECRET_CONST_SIZE); 770*0Sstevel@tonic-gate memcpy(&(buf[TLS_MD_MASTER_SECRET_CONST_SIZE]), 771*0Sstevel@tonic-gate s->s3->client_random,SSL3_RANDOM_SIZE); 772*0Sstevel@tonic-gate memcpy(&(buf[SSL3_RANDOM_SIZE+TLS_MD_MASTER_SECRET_CONST_SIZE]), 773*0Sstevel@tonic-gate s->s3->server_random,SSL3_RANDOM_SIZE); 774*0Sstevel@tonic-gate tls1_PRF(s->ctx->md5,s->ctx->sha1, 775*0Sstevel@tonic-gate buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len, 776*0Sstevel@tonic-gate s->session->master_key,buff,sizeof buff); 777*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 778*0Sstevel@tonic-gate printf ("tls1_generate_master_secret() complete\n"); 779*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 780*0Sstevel@tonic-gate return(SSL3_MASTER_SECRET_SIZE); 781*0Sstevel@tonic-gate } 782*0Sstevel@tonic-gate 783*0Sstevel@tonic-gate int tls1_alert_code(int code) 784*0Sstevel@tonic-gate { 785*0Sstevel@tonic-gate switch (code) 786*0Sstevel@tonic-gate { 787*0Sstevel@tonic-gate case SSL_AD_CLOSE_NOTIFY: return(SSL3_AD_CLOSE_NOTIFY); 788*0Sstevel@tonic-gate case SSL_AD_UNEXPECTED_MESSAGE: return(SSL3_AD_UNEXPECTED_MESSAGE); 789*0Sstevel@tonic-gate case SSL_AD_BAD_RECORD_MAC: return(SSL3_AD_BAD_RECORD_MAC); 790*0Sstevel@tonic-gate case SSL_AD_DECRYPTION_FAILED: return(TLS1_AD_DECRYPTION_FAILED); 791*0Sstevel@tonic-gate case SSL_AD_RECORD_OVERFLOW: return(TLS1_AD_RECORD_OVERFLOW); 792*0Sstevel@tonic-gate case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE); 793*0Sstevel@tonic-gate case SSL_AD_HANDSHAKE_FAILURE: return(SSL3_AD_HANDSHAKE_FAILURE); 794*0Sstevel@tonic-gate case SSL_AD_NO_CERTIFICATE: return(-1); 795*0Sstevel@tonic-gate case SSL_AD_BAD_CERTIFICATE: return(SSL3_AD_BAD_CERTIFICATE); 796*0Sstevel@tonic-gate case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE); 797*0Sstevel@tonic-gate case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED); 798*0Sstevel@tonic-gate case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED); 799*0Sstevel@tonic-gate case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN); 800*0Sstevel@tonic-gate case SSL_AD_ILLEGAL_PARAMETER: return(SSL3_AD_ILLEGAL_PARAMETER); 801*0Sstevel@tonic-gate case SSL_AD_UNKNOWN_CA: return(TLS1_AD_UNKNOWN_CA); 802*0Sstevel@tonic-gate case SSL_AD_ACCESS_DENIED: return(TLS1_AD_ACCESS_DENIED); 803*0Sstevel@tonic-gate case SSL_AD_DECODE_ERROR: return(TLS1_AD_DECODE_ERROR); 804*0Sstevel@tonic-gate case SSL_AD_DECRYPT_ERROR: return(TLS1_AD_DECRYPT_ERROR); 805*0Sstevel@tonic-gate case SSL_AD_EXPORT_RESTRICTION: return(TLS1_AD_EXPORT_RESTRICTION); 806*0Sstevel@tonic-gate case SSL_AD_PROTOCOL_VERSION: return(TLS1_AD_PROTOCOL_VERSION); 807*0Sstevel@tonic-gate case SSL_AD_INSUFFICIENT_SECURITY:return(TLS1_AD_INSUFFICIENT_SECURITY); 808*0Sstevel@tonic-gate case SSL_AD_INTERNAL_ERROR: return(TLS1_AD_INTERNAL_ERROR); 809*0Sstevel@tonic-gate case SSL_AD_USER_CANCELLED: return(TLS1_AD_USER_CANCELLED); 810*0Sstevel@tonic-gate case SSL_AD_NO_RENEGOTIATION: return(TLS1_AD_NO_RENEGOTIATION); 811*0Sstevel@tonic-gate default: return(-1); 812*0Sstevel@tonic-gate } 813*0Sstevel@tonic-gate } 814*0Sstevel@tonic-gate 815