More tweaks for comments due indent issues
[openssl.git] / ssl / t1_enc.c
index aa2e7820b81bc85c98f22e9bda3465334ee444a3..7416f732b66c30e77b64692e11be3c064f5f91ed 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;
        }
@@ -303,105 +302,69 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km,
                 s->session->master_key,s->session->master_key_length,
                 km,tmp,num);
 #ifdef KSSL_DEBUG
-       printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
+       fprintf(stderr,"tls1_generate_key_block() ==> %d byte master_key =\n\t",
                 s->session->master_key_length);
        {
         int i;
         for (i=0; i < s->session->master_key_length; i++)
                 {
-                printf("%02X", s->session->master_key[i]);
+                fprintf(stderr,"%02X", s->session->master_key[i]);
                 }
-        printf("\n");  }
+        fprintf(stderr,"\n");  }
 #endif    /* KSSL_DEBUG */
        return ret;
        }
 
-/* tls1_aead_ctx_init allocates |*aead_ctx|, if needed and returns 1. It
- * returns 0 on malloc error. */
-static int tls1_aead_ctx_init(SSL_AEAD_CTX **aead_ctx)
-       {
-       if (*aead_ctx != NULL)
-               EVP_AEAD_CTX_cleanup(&(*aead_ctx)->ctx);
-       else
-               {
-               *aead_ctx = (SSL_AEAD_CTX*) OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
-               if (*aead_ctx == NULL)
-                       {
-                       SSLerr(SSL_F_TLS1_AEAD_CTX_INIT, ERR_R_MALLOC_FAILURE);
-                       return 0;
-                       }
-               }
-
-       return 1;
-       }
-
-static int tls1_change_cipher_state_aead(SSL *s, char is_read,
-       const unsigned char *key, unsigned key_len,
-       const unsigned char *iv, unsigned iv_len)
+int tls1_change_cipher_state(SSL *s, int which)
        {
-       const EVP_AEAD *aead = s->s3->tmp.new_aead;
-       SSL_AEAD_CTX *aead_ctx;
-
-       if (is_read)
-               {
-               if (!tls1_aead_ctx_init(&s->aead_read_ctx))
-                       return 0;
-               aead_ctx = s->aead_read_ctx;
-               }
-       else
-               {
-               if (!tls1_aead_ctx_init(&s->aead_write_ctx))
-                       return 0;
-               aead_ctx = s->aead_write_ctx;
-               }
-
-       if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len,
-                              EVP_AEAD_DEFAULT_TAG_LENGTH, NULL /* engine */))
-               return 0;
-       if (iv_len > sizeof(aead_ctx->fixed_nonce))
-               {
-               SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, ERR_R_INTERNAL_ERROR);
-               return 0;
-               }
-       memcpy(aead_ctx->fixed_nonce, iv, iv_len);
-       aead_ctx->fixed_nonce_len = iv_len;
-       aead_ctx->variable_nonce_len = 8;  /* always the case, currently. */
-       aead_ctx->variable_nonce_included_in_record =
-               (s->s3->tmp.new_cipher->algorithm2 & SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
-       if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len != EVP_AEAD_nonce_length(aead))
-               {
-               SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, ERR_R_INTERNAL_ERROR);
-               return 0;
-               }
-       aead_ctx->tag_len = EVP_AEAD_max_overhead(aead);
+       static const unsigned char empty[]="";
+       unsigned char *p,*mac_secret;
+       unsigned char *exp_label;
+       unsigned char tmp1[EVP_MAX_KEY_LENGTH];
+       unsigned char tmp2[EVP_MAX_KEY_LENGTH];
+       unsigned char iv1[EVP_MAX_IV_LENGTH*2];
+       unsigned char iv2[EVP_MAX_IV_LENGTH*2];
+       unsigned char *ms,*key,*iv;
+       int client_write;
+       EVP_CIPHER_CTX *dd;
+       const EVP_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
+       const SSL_COMP *comp;
+#endif
+       const EVP_MD *m;
+       int mac_type;
+       int *mac_secret_size;
+       EVP_MD_CTX *mac_ctx;
+       EVP_PKEY *mac_key;
+       int is_export,n,i,j,k,exp_label_len,cl;
+       int reuse_dd = 0;
 
-       return 1;
-       }
+       is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
+       c=s->s3->tmp.new_sym_enc;
+       m=s->s3->tmp.new_hash;
+       mac_type = s->s3->tmp.new_mac_pkey_type;
+#ifndef OPENSSL_NO_COMP
+       comp=s->s3->tmp.new_compression;
+#endif
 
-/* tls1_change_cipher_state_cipher performs the work needed to switch cipher
- * states when using EVP_CIPHER. The argument |is_read| is true iff this
- * function is being called due to reading, as opposed to writing, a
- * ChangeCipherSpec message. In order to support export ciphersuites,
- * use_client_keys indicates whether the key material provided is in the
- * "client write" direction. */
-static int tls1_change_cipher_state_cipher(SSL *s,
-       char is_read, char use_client_keys,
-       const unsigned char *mac_secret, unsigned mac_secret_len,
-       const unsigned char *key, unsigned key_len,
-       const unsigned char *iv, unsigned iv_len)
+#ifdef KSSL_DEBUG
+       fprintf(stderr,"tls1_change_cipher_state(which= %d) w/\n", which);
+       fprintf(stderr,"\talg= %ld/%ld, comp= %p\n",
+              s->s3->tmp.new_cipher->algorithm_mkey,
+              s->s3->tmp.new_cipher->algorithm_auth,
+              comp);
+       fprintf(stderr,"\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
+       fprintf(stderr,"\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
+                c->nid,c->block_size,c->key_len,c->iv_len);
+       fprintf(stderr,"\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
        {
-       const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
-       const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0;
-       EVP_CIPHER_CTX *cipher_ctx;
-       EVP_MD_CTX *mac_ctx;
-       char is_aead_cipher;
-
-       unsigned char export_tmp1[EVP_MAX_KEY_LENGTH];
-       unsigned char export_tmp2[EVP_MAX_KEY_LENGTH];
-       unsigned char export_iv1[EVP_MAX_IV_LENGTH * 2];
-       unsigned char export_iv2[EVP_MAX_IV_LENGTH * 2];
+        int i;
+        for (i=0; i<s->s3->tmp.key_block_length; i++)
+               fprintf(stderr,"%02x", s->s3->tmp.key_block[i]);  fprintf(stderr,"\n");
+        }
+#endif /* KSSL_DEBUG */
 
-       if (is_read)
+       if (which & SSL3_CC_READ)
                {
                if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
                        s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
@@ -409,168 +372,19 @@ static int tls1_change_cipher_state_cipher(SSL *s,
                        s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
 
                if (s->enc_read_ctx != NULL)
-                       EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
+                       reuse_dd = 1;
                else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
                        goto err;
                else
                        /* make sure it's intialized in case we exit later with an error */
                        EVP_CIPHER_CTX_init(s->enc_read_ctx);
-
-               cipher_ctx = s->enc_read_ctx;
-               mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
-
-               memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len);
-               s->s3->read_mac_secret_size = mac_secret_len;
-               }
-       else
-               {
-               if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
-                       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)
-                       EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
-               else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == 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);
-
-               cipher_ctx = s->enc_write_ctx;
-               mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
-
-               memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len);
-               s->s3->write_mac_secret_size = mac_secret_len;
-               }
-
-       if (is_export)
-               {
-               /* In here I set both the read and write key/iv to the
-                * same value since only the correct one will be used :-).
-                */
-               const unsigned char *label;
-               unsigned label_len;
-
-               if (use_client_keys)
-                       {
-                       label = (const unsigned char*) TLS_MD_CLIENT_WRITE_KEY_CONST;
-                       label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
-                       }
-               else
-                       {
-                       label = (const unsigned char*) TLS_MD_SERVER_WRITE_KEY_CONST;
-                       label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
-                       }
-
-               if (!tls1_PRF(ssl_get_algorithm2(s),
-                               label, label_len,
-                               s->s3->client_random, SSL3_RANDOM_SIZE,
-                               s->s3->server_random, SSL3_RANDOM_SIZE,
-                               NULL, 0, NULL, 0,
-                               key /* secret */, key_len /* secret length */,
-                               export_tmp1 /* output */,
-                               export_tmp2 /* scratch space */,
-                               EVP_CIPHER_key_length(s->s3->tmp.new_sym_enc) /* output length */))
-                       return 0;
-               key = export_tmp1;
-
-               if (iv_len > 0)
-                       {
-                       static const unsigned char empty[] = "";
-
-                       if (!tls1_PRF(ssl_get_algorithm2(s),
-                                       TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE,
-                                       s->s3->client_random, SSL3_RANDOM_SIZE,
-                                       s->s3->server_random, SSL3_RANDOM_SIZE,
-                                       NULL, 0, NULL, 0,
-                                       empty /* secret */ ,0 /* secret length */,
-                                       export_iv1 /* output */,
-                                       export_iv2 /* scratch space */,
-                                       iv_len * 2 /* output length */))
-                               return 0;
-
-                       if (use_client_keys)
-                               iv = export_iv1;
-                       else
-                               iv = &export_iv1[iv_len];
-                       }
-               }
-
-       /* is_aead_cipher indicates whether the EVP_CIPHER implements an AEAD
-        * interface. This is different from the newer EVP_AEAD interface. */
-       is_aead_cipher = (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0;
-
-       if (!is_aead_cipher)
-               {
-               EVP_PKEY *mac_key =
-                       EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type,
-                                            NULL, mac_secret, mac_secret_len);
-               if (!mac_key)
-                       return 0;
-               EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key);
-               EVP_PKEY_free(mac_key);
-               }
-
-       if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE)
-               {
-               EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key,
-                                 NULL /* iv */, !is_read);
-               EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, iv_len, (void*) iv);
-               }
-       else
-               EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv, !is_read);
-
-       /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
-       if (is_aead_cipher && mac_secret_len > 0)
-               EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
-                                   mac_secret_len, (void*) mac_secret);
-
-       if (is_export)
-               {
-               OPENSSL_cleanse(export_tmp1, sizeof(export_tmp1));
-               OPENSSL_cleanse(export_tmp2, sizeof(export_tmp1));
-               OPENSSL_cleanse(export_iv1, sizeof(export_iv1));
-               OPENSSL_cleanse(export_iv2, sizeof(export_iv2));
-               }
-
-       return 1;
-
-err:
-       SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER, ERR_R_MALLOC_FAILURE);
-       return 0;
-       }
-
-int tls1_change_cipher_state(SSL *s, int which)
-       {
-       /* is_read is true if we have just read a ChangeCipherSpec message -
-        * i.e. we need to update the read cipherspec. Otherwise we have just
-        * written one. */
-       const char is_read = (which & SSL3_CC_READ) != 0;
-       /* use_client_keys is true if we wish to use the keys for the "client
-        * write" direction. This is the case if we're a client sending a
-        * ChangeCipherSpec, or a server reading a client's ChangeCipherSpec. */
-       const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE ||
-                                    which == SSL3_CHANGE_CIPHER_SERVER_READ;
-       const unsigned char *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
-       const unsigned char *client_write_key, *server_write_key, *key;
-       const unsigned char *client_write_iv, *server_write_iv, *iv;
-       const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
-       const EVP_AEAD *aead = s->s3->tmp.new_aead;
-       unsigned key_len, iv_len, mac_secret_len;
-       const unsigned char *key_data;
-       const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0;
-
-       /* Update compression contexts. */
+               dd= s->enc_read_ctx;
+               mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
 #ifndef OPENSSL_NO_COMP
-       const SSL_COMP *comp = s->s3->tmp.new_compression;
-
-       if (is_read)
-               {
                if (s->expand != NULL)
                        {
                        COMP_CTX_free(s->expand);
-                       s->expand = NULL;
+                       s->expand=NULL;
                        }
                if (comp != NULL)
                        {
@@ -578,180 +392,245 @@ int tls1_change_cipher_state(SSL *s, int which)
                        if (s->expand == NULL)
                                {
                                SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
-                               return 0;
+                               goto err2;
                                }
                        if (s->s3->rrec.comp == NULL)
-                               s->s3->rrec.comp =
-                                       (unsigned char *)OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
+                               s->s3->rrec.comp=(unsigned char *)
+                                       OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
                        if (s->s3->rrec.comp == NULL)
                                goto err;
                        }
+#endif
+               /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
+               if (s->version != DTLS1_VERSION)
+                       memset(&(s->s3->read_sequence[0]),0,8);
+               mac_secret= &(s->s3->read_mac_secret[0]);
+               mac_secret_size=&(s->s3->read_mac_secret_size);
                }
        else
                {
+               if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+                       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 && !SSL_IS_DTLS(s))
+                       reuse_dd = 1;
+               else if ((s->enc_write_ctx=EVP_CIPHER_CTX_new()) == NULL)
+                       goto err;
+               dd= s->enc_write_ctx;
+               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)
                        {
                        COMP_CTX_free(s->compress);
-                       s->compress = NULL;
+                       s->compress=NULL;
                        }
                if (comp != NULL)
                        {
-                       s->compress = COMP_CTX_new(comp->method);
+                       s->compress=COMP_CTX_new(comp->method);
                        if (s->compress == NULL)
                                {
                                SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
-                               return 0;
+                               goto err2;
                                }
                        }
+#endif
+               /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
+               if (s->version != DTLS1_VERSION)
+                       memset(&(s->s3->write_sequence[0]),0,8);
+               mac_secret= &(s->s3->write_mac_secret[0]);
+               mac_secret_size = &(s->s3->write_mac_secret_size);
                }
-#endif  /* OPENSSL_NO_COMP */
 
-       /* Reset sequence number to zero. */
-       memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8);
+       if (reuse_dd)
+               EVP_CIPHER_CTX_cleanup(dd);
 
-       /* key_arg is used for SSLv2. We don't need it for TLS. */
-       s->session->key_arg_length = 0;
+       p=s->s3->tmp.key_block;
+       i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;
 
-       mac_secret_len = s->s3->tmp.new_mac_secret_size;
-
-       if (aead != NULL)
+       cl=EVP_CIPHER_key_length(c);
+       j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
+                      cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
+       /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
+       /* If GCM mode only part of IV comes from PRF */
+       if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+               k = EVP_GCM_TLS_FIXED_IV_LEN;
+       else
+               k=EVP_CIPHER_iv_length(c);
+       if (    (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
+               (which == SSL3_CHANGE_CIPHER_SERVER_READ))
                {
-               key_len = EVP_AEAD_key_length(aead);
-               iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->s3->tmp.new_cipher);
+               ms=  &(p[ 0]); n=i+i;
+               key= &(p[ n]); n+=j+j;
+               iv=  &(p[ n]); n+=k+k;
+               exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
+               exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
+               client_write=1;
                }
        else
                {
-               key_len = EVP_CIPHER_key_length(cipher);
-               if (is_export && key_len > SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher))
-                       key_len = SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher);
+               n=i;
+               ms=  &(p[ n]); n+=i+j;
+               key= &(p[ n]); n+=j+k;
+               iv=  &(p[ n]); n+=k;
+               exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
+               exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
+               client_write=0;
+               }
 
-               if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE)
-                       iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
-               else
-                       iv_len = EVP_CIPHER_iv_length(cipher);
+       if (n > s->s3->tmp.key_block_length)
+               {
+               SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
+               goto err2;
                }
 
-       key_data = s->s3->tmp.key_block;
-       client_write_mac_secret = key_data; key_data += mac_secret_len;
-       server_write_mac_secret = key_data; key_data += mac_secret_len;
-       client_write_key =        key_data; key_data += key_len;
-       server_write_key =        key_data; key_data += key_len;
-       client_write_iv  =        key_data; key_data += iv_len;
-       server_write_iv  =        key_data; key_data += iv_len;
+       memcpy(mac_secret,ms,i);
 
-       if (use_client_keys)
+       if (!(EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER))
                {
-               mac_secret = client_write_mac_secret;
-               key = client_write_key;
-               iv = client_write_iv;
+               mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
+                               mac_secret,*mac_secret_size);
+               EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
+               EVP_PKEY_free(mac_key);
                }
-       else
+#ifdef TLS_DEBUG
+printf("which = %04X\nmac key=",which);
+{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
+#endif
+       if (is_export)
                {
-               mac_secret = server_write_mac_secret;
-               key = server_write_key;
-               iv = server_write_iv;
+               /* In here I set both the read and write key/iv to the
+                * same value since only the correct one will be used :-).
+                */
+               if (!tls1_PRF(ssl_get_algorithm2(s),
+                               exp_label,exp_label_len,
+                               s->s3->client_random,SSL3_RANDOM_SIZE,
+                               s->s3->server_random,SSL3_RANDOM_SIZE,
+                               NULL,0,NULL,0,
+                               key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)))
+                       goto err2;
+               key=tmp1;
+
+               if (k > 0)
+                       {
+                       if (!tls1_PRF(ssl_get_algorithm2(s),
+                                       TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
+                                       s->s3->client_random,SSL3_RANDOM_SIZE,
+                                       s->s3->server_random,SSL3_RANDOM_SIZE,
+                                       NULL,0,NULL,0,
+                                       empty,0,iv1,iv2,k*2))
+                               goto err2;
+                       if (client_write)
+                               iv=iv1;
+                       else
+                               iv= &(iv1[k]);
+                       }
                }
 
-       if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length)
-               {
-               SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
-               return 0;
-               }
+       s->session->key_arg_length=0;
+#ifdef KSSL_DEBUG
+       {
+        int i;
+       fprintf(stderr,"EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
+       fprintf(stderr,"\tkey= "); for (i=0; i<c->key_len; i++) fprintf(stderr,"%02x", key[i]);
+       fprintf(stderr,"\n");
+       fprintf(stderr,"\t iv= "); for (i=0; i<c->iv_len; i++) fprintf(stderr,"%02x", iv[i]);
+       fprintf(stderr,"\n");
+       }
+#endif /* KSSL_DEBUG */
 
-       if (aead != NULL)
+       if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
                {
-               if (!tls1_change_cipher_state_aead(s, is_read,
-                                                  key, key_len, iv, iv_len))
-                       return 0;
-               }
-       else
-               {
-               if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys,
-                                                    mac_secret, mac_secret_len,
-                                                    key, key_len,
-                                                    iv, iv_len))
-                       return 0;
+               EVP_CipherInit_ex(dd,c,NULL,key,NULL,(which & SSL3_CC_WRITE));
+               EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv);
                }
+       else    
+               EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
+
+       /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
+       if ((EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size)
+               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_len)
+               if (*mac_secret_size)
                        s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
-                                               mac_secret, mac_secret_len,
+                                               mac_secret, *mac_secret_size,
                                                s, s->msg_callback_arg);
-               if (key_len)
+               if (c->key_len)
                        s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
-                                               key, key_len,
+                                               key, c->key_len,
                                                s, s->msg_callback_arg);
-               if (iv_len)
+               if (k)
                        {
-                       if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE)
+                       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, iv_len,
+                       s->msg_callback(2, s->version, wh, iv, k,
                                                s, s->msg_callback_arg);
                        }
                }
 #endif
 
-       return 1;
+#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'); }
+printf("\niv=");
+{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); }
+printf("\n");
+#endif
+
+       OPENSSL_cleanse(tmp1,sizeof(tmp1));
+       OPENSSL_cleanse(tmp2,sizeof(tmp1));
+       OPENSSL_cleanse(iv1,sizeof(iv1));
+       OPENSSL_cleanse(iv2,sizeof(iv2));
+       return(1);
 err:
-       SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
-       return 0;
+       SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
+err2:
+       return(0);
        }
 
 int tls1_setup_key_block(SSL *s)
        {
        unsigned char *p1,*p2=NULL;
-       const EVP_CIPHER *c = NULL;
-       const EVP_MD *hash = NULL;
-       const EVP_AEAD *aead = NULL;
+       const EVP_CIPHER *c;
+       const EVP_MD *hash;
        int num;
        SSL_COMP *comp;
        int mac_type= NID_undef,mac_secret_size=0;
        int ret=0;
-       unsigned key_len, iv_len;
 
 #ifdef KSSL_DEBUG
-       printf ("tls1_setup_key_block()\n");
+       fprintf(stderr,"tls1_setup_key_block()\n");
 #endif /* KSSL_DEBUG */
 
        if (s->s3->tmp.key_block_length != 0)
                return(1);
 
-       if (!ssl_cipher_get_comp(s->session, &comp))
-               goto cipher_unavailable_err;
-
-       if (s->session->cipher &&
-           (s->session->cipher->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD))
+       if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp))
                {
-               if (!ssl_cipher_get_evp_aead(s->session, &aead))
-                       goto cipher_unavailable_err;
-               key_len = EVP_AEAD_key_length(aead);
-               iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->session->cipher);
+               SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+               return(0);
                }
-       else
-               {
-               if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size))
-                       goto cipher_unavailable_err;
-               key_len = EVP_CIPHER_key_length(c);
 
-               if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
-                       iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
-               else
-                       iv_len = EVP_CIPHER_iv_length(c);
-               }
-
-       s->s3->tmp.new_aead=aead;
        s->s3->tmp.new_sym_enc=c;
        s->s3->tmp.new_hash=hash;
        s->s3->tmp.new_mac_pkey_type = mac_type;
        s->s3->tmp.new_mac_secret_size = mac_secret_size;
-
-       num=key_len+mac_secret_size+iv_len;
+       num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c);
        num*=2;
 
        ssl3_cleanup_key_block(s);
@@ -814,13 +693,10 @@ err:
                OPENSSL_free(p2);
                }
        return(ret);
-
-cipher_unavailable_err:
-       SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
-       return 0;
        }
 
-/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+/*-
+ * 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
@@ -836,134 +712,6 @@ int tls1_enc(SSL *s, int send)
        unsigned long l;
        int bs,i,j,k,pad=0,ret,mac_size=0;
        const EVP_CIPHER *enc;
-       const SSL_AEAD_CTX *aead;
-
-       if (send)
-               rec = &s->s3->wrec;
-       else
-               rec = &s->s3->rrec;
-
-       if (send)
-               aead = s->aead_write_ctx;
-       else
-               aead = s->aead_read_ctx;
-
-       if (aead)
-               {
-               unsigned char ad[13], *seq, *in, *out, nonce[16];
-               unsigned nonce_used;
-               ssize_t n;
-
-               seq = send ? s->s3->write_sequence : s->s3->read_sequence;
-
-               if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
-                       {
-                       unsigned char dtlsseq[9], *p = dtlsseq;
-
-                       s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
-                       memcpy(p, &seq[2], 6);
-                       memcpy(ad, dtlsseq, 8);
-                       }
-               else
-                       {
-                       memcpy(ad, seq, 8);
-                       for (i=7; i>=0; i--)    /* increment */
-                               {
-                               ++seq[i];
-                               if (seq[i] != 0)
-                                       break;
-                               }
-                       }
-
-               ad[8]  = rec->type;
-               ad[9]  = (unsigned char)(s->version>>8);
-               ad[10] = (unsigned char)(s->version);
-
-               if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce) ||
-                   aead->variable_nonce_len > 8)
-                       return -1;  /* internal error - should never happen. */
-
-               memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
-               nonce_used = aead->fixed_nonce_len;
-
-               if (send)
-                       {
-                       size_t len = rec->length;
-                       size_t eivlen = 0;
-                       in = rec->input;
-                       out = rec->data;
-
-                       /* When sending we use the sequence number as the
-                        * variable part of the nonce. */
-                       if (aead->variable_nonce_len > 8)
-                               return -1;
-                       memcpy(nonce + nonce_used, ad, aead->variable_nonce_len);
-                       nonce_used += aead->variable_nonce_len;
-
-                       /* in do_ssl3_write, rec->input is moved forward by
-                        * variable_nonce_len in order to leave space for the
-                        * variable nonce. Thus we can copy the sequence number
-                        * bytes into place without overwriting any of the
-                        * plaintext. */
-                       if (aead->variable_nonce_included_in_record)
-                               {
-                               memcpy(out, ad, aead->variable_nonce_len);
-                               len -= aead->variable_nonce_len;
-                               eivlen = aead->variable_nonce_len;
-                               }
-
-                       ad[11] = len >> 8;
-                       ad[12] = len & 0xff;
-
-                       n = EVP_AEAD_CTX_seal(&aead->ctx,
-                                             out + eivlen, len + aead->tag_len,
-                                             nonce, nonce_used,
-                                             in + eivlen, len,
-                                             ad, sizeof(ad));
-                       if (n >= 0 && aead->variable_nonce_included_in_record)
-                               n += aead->variable_nonce_len;
-                       }
-               else
-                       {
-                       /* receive */
-                       size_t len = rec->length;
-
-                       if (rec->data != rec->input)
-                               return -1;  /* internal error - should never happen. */
-                       out = in = rec->input;
-
-                       if (len < aead->variable_nonce_len)
-                               return 0;
-                       memcpy(nonce + nonce_used,
-                              aead->variable_nonce_included_in_record ? in : ad,
-                              aead->variable_nonce_len);
-                       nonce_used += aead->variable_nonce_len;
-
-                       if (aead->variable_nonce_included_in_record)
-                               {
-                               in += aead->variable_nonce_len;
-                               len -= aead->variable_nonce_len;
-                               out += aead->variable_nonce_len;
-                               }
-
-                       if (len < aead->tag_len)
-                               return 0;
-                       len -= aead->tag_len;
-
-                       ad[11] = len >> 8;
-                       ad[12] = len & 0xff;
-
-                       n = EVP_AEAD_CTX_open(&aead->ctx, out, len, nonce, nonce_used,
-                                             in, len + aead->tag_len, ad, sizeof(ad));
-
-                       rec->data = rec->input = out;
-                       }
-
-               if (n == -1)
-                       return -1;
-               rec->length = n;
-               return 1;
-               }
 
        if (send)
                {
@@ -1016,7 +764,7 @@ int tls1_enc(SSL *s, int send)
                }
 
 #ifdef KSSL_DEBUG
-       printf("tls1_enc(%d)\n", send);
+       fprintf(stderr,"tls1_enc(%d)\n", send);
 #endif    /* KSSL_DEBUG */
 
        if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
@@ -1088,18 +836,18 @@ int tls1_enc(SSL *s, int send)
 #ifdef KSSL_DEBUG
                {
                unsigned long ui;
-               printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
+               fprintf(stderr,"EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
                        ds,rec->data,rec->input,l);
-               printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+               fprintf(stderr,"\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n",
                        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");
-               printf("\trec->input=");
-               for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
-               printf("\n");
+               fprintf(stderr,"\t\tIV: ");
+               for (i=0; i<ds->cipher->iv_len; i++) fprintf(stderr,"%02X", ds->iv[i]);
+               fprintf(stderr,"\n");
+               fprintf(stderr,"\trec->input=");
+               for (ui=0; ui<l; ui++) fprintf(stderr," %02x", rec->input[ui]);
+               fprintf(stderr,"\n");
                }
 #endif /* KSSL_DEBUG */
 
@@ -1124,9 +872,9 @@ int tls1_enc(SSL *s, int send)
 #ifdef KSSL_DEBUG
                {
                unsigned long i;
-               printf("\trec->data=");
+               fprintf(stderr,"\trec->data=");
                for (i=0; i<l; i++)
-                       printf(" %02x", rec->data[i]);  printf("\n");
+                       fprintf(stderr," %02x", rec->data[i]);  fprintf(stderr,"\n");
                }
 #endif /* KSSL_DEBUG */
 
@@ -1196,18 +944,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;
                                }
                        }
                }
@@ -1261,7 +1010,8 @@ 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;
                }
 
@@ -1295,6 +1045,7 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
                 * timing-side channel information about how many blocks of
                 * data we are hashing because that gives an attacker a
                 * timing-oracle. */
+                /* Final param == not SSLv3 */
                ssl3_cbc_digest_record(
                        mac_ctx,
                        md, &md_size,
@@ -1302,7 +1053,7 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
                        rec->length + md_size, orig_len,
                        ssl->s3->read_mac_secret,
                        ssl->s3->read_mac_secret_size,
-                       0 /* not SSLv3 */);
+                       0);
                }
        else
                {
@@ -1322,14 +1073,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
        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"); }
-printf("seq=");
-{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
-printf("buf=");
-{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
-printf("rec=");
-{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
+fprintf(stderr,"seq=");
+{int z; for (z=0; z<8; z++) fprintf(stderr,"%02X ",seq[z]); fprintf(stderr,"\n"); }
+fprintf(stderr,"rec=");
+{unsigned int z; for (z=0; z<rec->length; z++) fprintf(stderr,"%02X ",rec->data[z]); fprintf(stderr,"\n"); }
 #endif
 
        if (!SSL_IS_DTLS(ssl))
@@ -1342,7 +1089,7 @@ printf("rec=");
                }
 
 #ifdef TLS_DEBUG
-{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
+{unsigned int z; for (z=0; z<md_size; z++) fprintf(stderr,"%02X ",md[z]); fprintf(stderr,"\n"); }
 #endif
        return(md_size);
        }
@@ -1356,7 +1103,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 
 
 #ifdef KSSL_DEBUG
-       printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
+       fprintf(stderr,"tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
 #endif /* KSSL_DEBUG */
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
@@ -1367,7 +1114,8 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
                co = s->s3->client_opaque_prf_input;
                col = s->s3->server_opaque_prf_input_len;
                so = s->s3->server_opaque_prf_input;
-               sol = s->s3->client_opaque_prf_input_len; /* must be same as col (see draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) */
+               /* must be same as col (see draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) */
+               sol = s->s3->client_opaque_prf_input_len;
                }
 #endif
 
@@ -1409,7 +1157,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 #endif
 
 #ifdef KSSL_DEBUG
-       printf ("tls1_generate_master_secret() complete\n");
+       fprintf(stderr,"tls1_generate_master_secret() complete\n");
 #endif /* KSSL_DEBUG */
        return(SSL3_MASTER_SECRET_SIZE);
        }
@@ -1424,7 +1172,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
        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);
+       fprintf(stderr,"tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n", s, out, olen, label, llen, context, contextlen);
 #endif /* KSSL_DEBUG */
 
        buff = OPENSSL_malloc(olen);
@@ -1477,7 +1225,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
        if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
                 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
 
-       rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+       rv = tls1_PRF(ssl_get_algorithm2(s),
                      val, vallen,
                      NULL, 0,
                      NULL, 0,
@@ -1487,7 +1235,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                      out,buff,olen);
 
 #ifdef KSSL_DEBUG
-       printf ("tls1_export_keying_material() complete\n");
+       fprintf(stderr,"tls1_export_keying_material() complete\n");
 #endif /* KSSL_DEBUG */
        goto ret;
 err1:
@@ -1537,7 +1285,9 @@ int tls1_alert_code(int code)
        case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
        case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
        case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
-#if 0 /* not appropriate for TLS, not used for DTLS */
+       case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
+#if 0
+       /* not appropriate for TLS, not used for DTLS */
        case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
                                          (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
 #endif