Set security level to zero is ssltest
[openssl.git] / ssl / t1_enc.c
index 1c6fe5d82ae92dbf574b4b2ab10666245bab3685..a98f6fe882d7362d76e2fe273a7e4ccefd16b748 100644 (file)
@@ -160,7 +160,7 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
        {
        int chunk;
        size_t j;
-       EVP_MD_CTX ctx, ctx_tmp;
+       EVP_MD_CTX ctx, ctx_tmp, ctx_init;
        EVP_PKEY *mac_key;
        unsigned char A1[EVP_MAX_MD_SIZE];
        size_t A1_len;
@@ -171,14 +171,14 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
 
        EVP_MD_CTX_init(&ctx);
        EVP_MD_CTX_init(&ctx_tmp);
-       EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-       EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+       EVP_MD_CTX_init(&ctx_init);
+       EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
        if (!mac_key)
                goto err;
-       if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
+       if (!EVP_DigestSignInit(&ctx_init,NULL,md, NULL, mac_key))
                goto err;
-       if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
+       if (!EVP_MD_CTX_copy_ex(&ctx,&ctx_init))
                goto err;
        if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
                goto err;
@@ -196,13 +196,11 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
        for (;;)
                {
                /* Reinit mac contexts */
-               if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
-                       goto err;
-               if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
+               if (!EVP_MD_CTX_copy_ex(&ctx,&ctx_init))
                        goto err;
                if (!EVP_DigestSignUpdate(&ctx,A1,A1_len))
                        goto err;
-               if (!EVP_DigestSignUpdate(&ctx_tmp,A1,A1_len))
+               if (olen>chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp,&ctx))
                        goto err;
                if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
                        goto err;
@@ -238,6 +236,7 @@ err:
        EVP_PKEY_free(mac_key);
        EVP_MD_CTX_cleanup(&ctx);
        EVP_MD_CTX_cleanup(&ctx_tmp);
+       EVP_MD_CTX_cleanup(&ctx_init);
        OPENSSL_cleanse(A1,sizeof(A1));
        return ret;
        }
@@ -361,7 +360,7 @@ int tls1_change_cipher_state(SSL *s, int which)
        {
         int i;
         for (i=0; i<s->s3->tmp.key_block_length; i++)
-               printf("%02x", key_block[i]);  printf("\n");
+               printf("%02x", s->s3->tmp.key_block[i]);  printf("\n");
         }
 #endif /* KSSL_DEBUG */
 
@@ -414,15 +413,20 @@ int tls1_change_cipher_state(SSL *s, int which)
                        s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
                        else
                        s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
-               if (s->enc_write_ctx != NULL)
+               if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s))
                        reuse_dd = 1;
-               else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
+               else if ((s->enc_write_ctx=EVP_CIPHER_CTX_new()) == NULL)
                        goto err;
-               else
-                       /* make sure it's intialized in case we exit later with an error */
-                       EVP_CIPHER_CTX_init(s->enc_write_ctx);
                dd= s->enc_write_ctx;
-               mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
+               if (SSL_IS_DTLS(s))
+                       {
+                       mac_ctx = EVP_MD_CTX_create();
+                       if (!mac_ctx)
+                               goto err;
+                       s->write_hash = mac_ctx;
+                       }
+               else
+                       mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
 #ifndef OPENSSL_NO_COMP
                if (s->compress != NULL)
                        {
@@ -556,6 +560,30 @@ printf("which = %04X\nmac key=",which);
                EVP_CIPHER_CTX_ctrl(dd,EVP_CTRL_AEAD_SET_MAC_KEY,
                                *mac_secret_size,mac_secret);
 
+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+       if (s->msg_callback)
+               {
+               int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0;
+               if (*mac_secret_size)
+                       s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
+                                               mac_secret, *mac_secret_size,
+                                               s, s->msg_callback_arg);
+               if (c->key_len)
+                       s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
+                                               key, c->key_len,
+                                               s, s->msg_callback_arg);
+               if (k)
+                       {
+                       if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+                               wh |= TLS1_RT_CRYPTO_FIXED_IV;
+                       else
+                               wh |= TLS1_RT_CRYPTO_IV;
+                       s->msg_callback(2, s->version, wh, iv, k,
+                                               s, s->msg_callback_arg);
+                       }
+               }
+#endif
+
 #ifdef TLS_DEBUG
 printf("which = %04X\nkey=",which);
 { int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
@@ -592,7 +620,7 @@ int tls1_setup_key_block(SSL *s)
        if (s->s3->tmp.key_block_length != 0)
                return(1);
 
-       if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp))
+       if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp, SSL_USE_ETM(s)))
                {
                SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
                return(0);
@@ -667,12 +695,21 @@ err:
        return(ret);
        }
 
+/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ *       an internal error occurred.
+ */
 int tls1_enc(SSL *s, int send)
        {
        SSL3_RECORD *rec;
        EVP_CIPHER_CTX *ds;
        unsigned long l;
-       int bs,i,ii,j,k,pad=0;
+       int bs,i,j,k,pad=0,ret,mac_size=0;
        const EVP_CIPHER *enc;
 
        if (send)
@@ -691,7 +728,7 @@ int tls1_enc(SSL *s, int send)
                        int ivlen;
                        enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
                        /* For TLSv1.1 and later explicit IV */
-                       if (s->version >= TLS1_1_VERSION
+                       if (SSL_USE_EXPLICIT_IV(s)
                                && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
                                ivlen = EVP_CIPHER_iv_length(enc);
                        else
@@ -729,11 +766,11 @@ int tls1_enc(SSL *s, int send)
        printf("tls1_enc(%d)\n", send);
 #endif    /* KSSL_DEBUG */
 
-       if ((s->session == NULL) || (ds == NULL) ||
-               (enc == NULL))
+       if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
                {
                memmove(rec->data,rec->input,rec->length);
                rec->input=rec->data;
+               ret = 1;
                }
        else
                {
@@ -746,7 +783,7 @@ int tls1_enc(SSL *s, int send)
 
                        seq = send?s->s3->write_sequence:s->s3->read_sequence;
 
-                       if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
+                       if (SSL_IS_DTLS(s))
                                {
                                unsigned char dtlsseq[9],*p=dtlsseq;
 
@@ -797,13 +834,13 @@ int tls1_enc(SSL *s, int send)
 
 #ifdef KSSL_DEBUG
                {
-                unsigned long ui;
+               unsigned long ui;
                printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
-                        ds,rec->data,rec->input,l);
+                       ds,rec->data,rec->input,l);
                printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
-                        ds->buf_len, ds->cipher->key_len,
-                        DES_KEY_SZ, DES_SCHEDULE_SZ,
-                        ds->cipher->iv_len);
+                       ds->buf_len, ds->cipher->key_len,
+                       DES_KEY_SZ, DES_SCHEDULE_SZ,
+                       ds->cipher->iv_len);
                printf("\t\tIV: ");
                for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
                printf("\n");
@@ -816,16 +853,13 @@ int tls1_enc(SSL *s, int send)
                if (!send)
                        {
                        if (l == 0 || l%bs != 0)
-                               {
-                               if (s->version >= TLS1_1_VERSION)
-                                       return -1;
-                               SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
-                               ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
                                return 0;
-                               }
                        }
                
-               if (EVP_Cipher(ds,rec->data,rec->input,l) < 0)
+               i = EVP_Cipher(ds,rec->data,rec->input,l);
+               if ((EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_CUSTOM_CIPHER)
+                                               ?(i<0)
+                                               :(i==0))
                        return -1;      /* AEAD can fail to verify MAC */
                if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send)
                        {
@@ -836,66 +870,24 @@ int tls1_enc(SSL *s, int send)
 
 #ifdef KSSL_DEBUG
                {
-                unsigned long i;
-                printf("\trec->data=");
+               unsigned long i;
+               printf("\trec->data=");
                for (i=0; i<l; i++)
-                        printf(" %02x", rec->data[i]);  printf("\n");
-                }
+                       printf(" %02x", rec->data[i]);  printf("\n");
+               }
 #endif /* KSSL_DEBUG */
 
+               ret = 1;
+               if (!SSL_USE_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)
+                       mac_size = EVP_MD_CTX_size(s->read_hash);
                if ((bs != 1) && !send)
-                       {
-                       ii=i=rec->data[l-1]; /* padding_length */
-                       i++;
-                       /* NB: if compression is in operation the first packet
-                        * may not be of even length so the padding bug check
-                        * cannot be performed. This bug workaround has been
-                        * around since SSLeay so hopefully it is either fixed
-                        * now or no buggy implementation supports compression 
-                        * [steve]
-                        */
-                       if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
-                               && !s->expand)
-                               {
-                               /* First packet is even in size, so check */
-                               if ((memcmp(s->s3->read_sequence,
-                                       "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
-                                       s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
-                               if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
-                                       i--;
-                               }
-                       /* TLS 1.0 does not bound the number of padding bytes by the block size.
-                        * All of them must have value 'padding_length'. */
-                       if (i > (int)rec->length)
-                               {
-                               /* Incorrect padding. SSLerr() and ssl3_alert are done
-                                * by caller: we don't want to reveal whether this is
-                                * a decryption error or a MAC verification failure
-                                * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
-                               return -1;
-                               }
-                       for (j=(int)(l-i); j<(int)l; j++)
-                               {
-                               if (rec->data[j] != ii)
-                                       {
-                                       /* Incorrect padding */
-                                       return -1;
-                                       }
-                               }
-                       rec->length -=i;
-                       if (s->version >= TLS1_1_VERSION
-                               && EVP_CIPHER_CTX_mode(ds) == EVP_CIPH_CBC_MODE)
-                               {
-                               rec->data += bs;    /* skip the explicit IV */
-                               rec->input += bs;
-                               rec->length -= bs;
-                               }
-                       }
+                       ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
                if (pad && !send)
                        rec->length -= pad;
                }
-       return(1);
+       return ret;
        }
+
 int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
        {
        unsigned int ret;
@@ -951,18 +943,19 @@ int tls1_final_finish_mac(SSL *s,
                if (mask & ssl_get_algorithm2(s))
                        {
                        int hashsize = EVP_MD_size(md);
-                       if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+                       EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
+                       if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
                                {
                                /* internal error: 'buf' is too small for this cipersuite! */
                                err = 1;
                                }
                        else
                                {
-                               EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
-                               EVP_DigestFinal_ex(&ctx,q,&i);
-                               if (i != (unsigned int)hashsize) /* can't really happen */
+                               if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+                                       !EVP_DigestFinal_ex(&ctx,q,&i) ||
+                                       (i != (unsigned int)hashsize))
                                        err = 1;
-                               q+=i;
+                               q+=hashsize;
                                }
                        }
                }
@@ -988,7 +981,7 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
        size_t md_size;
        int i;
        EVP_MD_CTX hmac, *mac_ctx;
-       unsigned char buf[5]; 
+       unsigned char header[13];
        int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
        int t;
 
@@ -1009,12 +1002,6 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
        OPENSSL_assert(t >= 0);
        md_size=t;
 
-       buf[0]=rec->type;
-       buf[1]=(unsigned char)(ssl->version>>8);
-       buf[2]=(unsigned char)(ssl->version);
-       buf[3]=rec->length>>8;
-       buf[4]=rec->length&0xff;
-
        /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
        if (stream_mac) 
                {
@@ -1022,28 +1009,63 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
                }
                else
                {
-                       EVP_MD_CTX_copy(&hmac,hash);
+                       if (!EVP_MD_CTX_copy(&hmac,hash))
+                               return -1;
                        mac_ctx = &hmac;
                }
 
-       if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER)
+       if (SSL_IS_DTLS(ssl))
                {
                unsigned char dtlsseq[8],*p=dtlsseq;
 
                s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
                memcpy (p,&seq[2],6);
 
-               EVP_DigestSignUpdate(mac_ctx,dtlsseq,8);
+               memcpy(header, dtlsseq, 8);
                }
        else
-               EVP_DigestSignUpdate(mac_ctx,seq,8);
+               memcpy(header, seq, 8);
 
-       EVP_DigestSignUpdate(mac_ctx,buf,5);
-       EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
-       t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
-       OPENSSL_assert(t > 0);
+       header[8]=rec->type;
+       header[9]=(unsigned char)(ssl->version>>8);
+       header[10]=(unsigned char)(ssl->version);
+       header[11]=(rec->length)>>8;
+       header[12]=(rec->length)&0xff;
+
+       if (!send && !SSL_USE_ETM(ssl) &&
+           EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+           ssl3_cbc_record_digest_supported(mac_ctx))
+               {
+               /* This is a CBC-encrypted record. We must avoid leaking any
+                * timing-side channel information about how many blocks of
+                * data we are hashing because that gives an attacker a
+                * timing-oracle. */
+               ssl3_cbc_digest_record(
+                       mac_ctx,
+                       md, &md_size,
+                       header, rec->input,
+                       rec->length + md_size, rec->orig_len,
+                       ssl->s3->read_mac_secret,
+                       ssl->s3->read_mac_secret_size,
+                       0 /* not SSLv3 */);
+               }
+       else
+               {
+               EVP_DigestSignUpdate(mac_ctx,header,sizeof(header));
+               EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
+               t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
+               OPENSSL_assert(t > 0);
+#ifdef OPENSSL_FIPS
+               if (!send && !SSL_USE_ETM(ssl) && FIPS_mode())
+                       tls_fips_digest_extra(
+                                       ssl->enc_read_ctx,
+                                       mac_ctx, rec->input,
+                                       rec->length, rec->orig_len);
+#endif
+               }
                
-       if (!stream_mac) EVP_MD_CTX_cleanup(&hmac);
+       if (!stream_mac)
+               EVP_MD_CTX_cleanup(&hmac);
 #ifdef TLS_DEBUG
 printf("sec=");
 {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
@@ -1055,7 +1077,7 @@ printf("rec=");
 {unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
 #endif
 
-       if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
+       if (!SSL_IS_DTLS(ssl))
                {
                for (i=7; i>=0; i--)
                        {
@@ -1113,22 +1135,41 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
        BIO_dump_fp(stderr, (char *)s->session->master_key, SSL3_MASTER_SECRET_SIZE);
 #endif
 
+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+       if (s->msg_callback)
+               {
+               s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
+                                               p, len, s, s->msg_callback_arg);
+               s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
+                                       s->s3->client_random, SSL3_RANDOM_SIZE,
+                                               s, s->msg_callback_arg);
+               s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM,
+                                       s->s3->server_random, SSL3_RANDOM_SIZE,
+                                       s, s->msg_callback_arg);
+               s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER,
+                                       s->session->master_key,
+                                       SSL3_MASTER_SECRET_SIZE,
+                                       s, s->msg_callback_arg);
+               }
+#endif
+
 #ifdef KSSL_DEBUG
        printf ("tls1_generate_master_secret() complete\n");
 #endif /* KSSL_DEBUG */
        return(SSL3_MASTER_SECRET_SIZE);
        }
 
-int tls1_export_keying_material(SSL *s, unsigned char *out, unsigned int olen, 
-         const char *label, unsigned int llen, const unsigned char *context, 
-         unsigned int contextlen, int use_context)
+int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+        const char *label, size_t llen, const unsigned char *context,
+        size_t contextlen, int use_context)
        {
        unsigned char *buff;
-       unsigned char *val;
-       unsigned int vallen, currentvalpos, rv;
+       unsigned char *val = NULL;
+       size_t vallen, currentvalpos;
+       int rv;
 
 #ifdef KSSL_DEBUG
-       printf ("tls1_export_keying_material(%p, %p,%d, %s,%d, %p,%d)\n", s, out,olen, label,llen, p,plen);
+       printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
 #endif /* KSSL_DEBUG */
 
        buff = OPENSSL_malloc(olen);
@@ -1140,10 +1181,10 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, unsigned int olen,
         * does not create a prohibited label.
         */
        vallen = llen + SSL3_RANDOM_SIZE * 2;
-        if (use_context) 
-                {
-                vallen +=  2 + contextlen;
-                }
+       if (use_context)
+               {
+               vallen += 2 + contextlen;
+               }
 
        val = OPENSSL_malloc(vallen);
        if (val == NULL) goto err2;
@@ -1155,17 +1196,17 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, unsigned int olen,
        memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
        currentvalpos += SSL3_RANDOM_SIZE;
 
-        if (use_context)
-                {
-                val[currentvalpos] = (contextlen << 8) & 0xff;
-                currentvalpos++;
-                val[currentvalpos] = contextlen & 0xff;
-                currentvalpos++;
-                if ((contextlen > 0) || (context != NULL)) 
-                        {
-                        memcpy(val + currentvalpos, context, contextlen);
-                        }
-                }
+       if (use_context)
+               {
+               val[currentvalpos] = (contextlen >> 8) & 0xff;
+               currentvalpos++;
+               val[currentvalpos] = contextlen & 0xff;
+               currentvalpos++;
+               if ((contextlen > 0) || (context != NULL))
+                       {
+                       memcpy(val + currentvalpos, context, contextlen);
+                       }
+               }
 
        /* disallow prohibited labels
         * note that SSL3_RANDOM_SIZE > max(prohibited label len) =
@@ -1181,19 +1222,18 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, unsigned int olen,
        if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
                 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
 
-       tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
-               val, vallen,
-               NULL, 0,
-               NULL, 0,
-               NULL, 0,
-               NULL, 0,
-               s->session->master_key,s->session->master_key_length,
-               out,buff,olen);
+       rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+                     val, vallen,
+                     NULL, 0,
+                     NULL, 0,
+                     NULL, 0,
+                     NULL, 0,
+                     s->session->master_key,s->session->master_key_length,
+                     out,buff,olen);
 
 #ifdef KSSL_DEBUG
        printf ("tls1_export_keying_material() complete\n");
 #endif /* KSSL_DEBUG */
-       rv = olen;
        goto ret;
 err1:
        SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
@@ -1249,27 +1289,3 @@ int tls1_alert_code(int code)
        default:                        return(-1);
                }
        }
-
-int SSL_tls1_key_exporter(SSL *s, unsigned char *label, int label_len,
-                           unsigned char *context, int context_len,
-                           unsigned char *out, int olen)
-       {
-       unsigned char *tmp;
-       int rv;
-
-       tmp = OPENSSL_malloc(olen);
-
-       if (!tmp)
-               return 0;
-       
-       rv = tls1_PRF(ssl_get_algorithm2(s),
-                        label, label_len,
-                        s->s3->client_random,SSL3_RANDOM_SIZE,
-                        s->s3->server_random,SSL3_RANDOM_SIZE,
-                        context, context_len, NULL, 0,
-                        s->session->master_key, s->session->master_key_length,
-                        out, tmp, olen);
-
-       OPENSSL_free(tmp);
-       return rv;
-       }