[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Thu Dec 1 09:44:28 UTC 2016


The branch master has been updated
       via  bcd62c2512dd031cc524d058494aadebaaf1fc4c (commit)
       via  f60d68dc5385722608f3813d430842c3f5216e37 (commit)
       via  6606d600545b28dbcfb391f3c5adf03dd6ad0ca7 (commit)
       via  d3ab93e9c372c98c4ee3bcf8bc3c406a19e62f95 (commit)
       via  6c670174242e10414ebde212ab3a1a3fea51c773 (commit)
       via  f01675c6b7bad65af49c20c8920fa93e751423c8 (commit)
       via  bebc0c7d85a7484f1c5d0123f24cdc3c6b150243 (commit)
      from  54d028aa0f5dc50ec64a8d99ed43b81519b0443b (commit)


- Log -----------------------------------------------------------------
commit bcd62c2512dd031cc524d058494aadebaaf1fc4c
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Nov 30 10:57:10 2016 +0000

    Make refdata in tls13encryptest static
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit f60d68dc5385722608f3813d430842c3f5216e37
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Nov 30 10:53:57 2016 +0000

    Convert tls13encryptiontest so that we pass around a pointer not an index
    
    We also split the long string literals into 3 to avoid problems where we
    go over the 509 character limit.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 6606d600545b28dbcfb391f3c5adf03dd6ad0ca7
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Nov 29 23:27:27 2016 +0000

    Fix some style issues in the TLSv1.3 nonce construction code
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit d3ab93e9c372c98c4ee3bcf8bc3c406a19e62f95
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Nov 22 10:12:55 2016 +0000

    Fix a double free in tls13encryptiontest
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 6c670174242e10414ebde212ab3a1a3fea51c773
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Nov 21 17:26:22 2016 +0000

    Fix a travis compilation error
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit f01675c6b7bad65af49c20c8920fa93e751423c8
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Nov 17 22:58:46 2016 +0000

    Add a test for TLSv1.3 encryption using the new nonce construction
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit bebc0c7d85a7484f1c5d0123f24cdc3c6b150243
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Nov 17 18:00:17 2016 +0000

    Use the TLSv1.3 nonce construction
    
    This updates the record layer to use the TLSv1.3 style nonce construciton.
    It also updates TLSProxy and ossltest to be able to recognise the new
    layout.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 engines/e_ossltest.c                               |  36 +-
 ssl/build.info                                     |   2 +-
 ssl/record/record.h                                |   1 +
 ssl/record/ssl3_record_tls13.c                     | 104 ++++++
 ssl/ssl_locl.h                                     |   2 +
 ssl/t1_lib.c                                       |   5 +-
 ssl/tls13_enc.c                                    |  64 +---
 test/build.info                                    |   7 +-
 ...st_tls13secrets.t => 90-test_tls13encryption.t} |   6 +-
 test/tls13encryptiontest.c                         | 383 +++++++++++++++++++++
 util/TLSProxy/Record.pm                            |   2 -
 11 files changed, 537 insertions(+), 75 deletions(-)
 create mode 100644 ssl/record/ssl3_record_tls13.c
 copy test/recipes/{90-test_tls13secrets.t => 90-test_tls13encryption.t} (76%)
 create mode 100644 test/tls13encryptiontest.c

diff --git a/engines/e_ossltest.c b/engines/e_ossltest.c
index afa5edf..3c9f08c 100644
--- a/engines/e_ossltest.c
+++ b/engines/e_ossltest.c
@@ -617,33 +617,43 @@ int ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 int ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                const unsigned char *in, size_t inl)
 {
-    const size_t datalen = inl - EVP_GCM_TLS_EXPLICIT_IV_LEN
-                           - EVP_GCM_TLS_TAG_LEN;
-    unsigned char *tmpbuf = OPENSSL_malloc(datalen);
+    unsigned char *tmpbuf = OPENSSL_malloc(inl);
 
-    if (tmpbuf == NULL)
+    /* OPENSSL_malloc will return NULL if inl == 0 */
+    if (tmpbuf == NULL && inl > 0)
         return -1;
 
     /* Remember what we were asked to encrypt */
-    memcpy(tmpbuf, in + EVP_GCM_TLS_EXPLICIT_IV_LEN, datalen);
+    memcpy(tmpbuf, in, inl);
 
     /* Go through the motions of encrypting it */
     EVP_CIPHER_meth_get_do_cipher(EVP_aes_128_gcm())(ctx, out, in, inl);
 
-    /*
-     * Throw it all away and just use the plaintext as the output with empty
-     * IV and tag
-     */
-    memset(out, 0, inl);
-    memcpy(out + EVP_GCM_TLS_EXPLICIT_IV_LEN, tmpbuf, datalen);
+    /* Throw it all away and just use the plaintext as the output */
+    memcpy(out, tmpbuf, inl);
     OPENSSL_free(tmpbuf);
 
-    return 1;
+    return inl;
 }
 
 static int ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
                                     void *ptr)
 {
     /* Pass the ctrl down */
-    return EVP_CIPHER_meth_get_ctrl(EVP_aes_128_gcm())(ctx, type, arg, ptr);
+    int ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_gcm())(ctx, type, arg, ptr);
+
+    if (ret <= 0)
+        return ret;
+
+    switch(type) {
+    case EVP_CTRL_AEAD_GET_TAG:
+        /* Always give the same tag */
+        memset(ptr, 0, EVP_GCM_TLS_TAG_LEN);
+        break;
+
+    default:
+        break;
+    }
+
+    return 1;
 }
diff --git a/ssl/build.info b/ssl/build.info
index 72b8dfc..23d33d3 100644
--- a/ssl/build.info
+++ b/ssl/build.info
@@ -11,4 +11,4 @@ SOURCE[../libssl]=\
         ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c  ssl_mcnf.c \
         bio_ssl.c ssl_err.c t1_reneg.c tls_srp.c t1_trce.c ssl_utst.c \
         record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \
-        statem/statem.c
+        statem/statem.c record/ssl3_record_tls13.c
diff --git a/ssl/record/record.h b/ssl/record/record.h
index e30010d..e995196 100644
--- a/ssl/record/record.h
+++ b/ssl/record/record.h
@@ -230,6 +230,7 @@ __owur int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t
                               size_t *written);
 __owur int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send);
 __owur int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send);
+__owur int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send);
 int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl);
 void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl);
 void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl);
diff --git a/ssl/record/ssl3_record_tls13.c b/ssl/record/ssl3_record_tls13.c
new file mode 100644
index 0000000..44c08b0
--- /dev/null
+++ b/ssl/record/ssl3_record_tls13.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "../ssl_locl.h"
+#include "record_locl.h"
+
+/*-
+ * tls13_enc encrypts/decrypts |n_recs| in |recs|.
+ *
+ * Returns:
+ *    0: (in non-constant time) if the record is publically invalid (i.e. too
+ *        short etc).
+ *    1: if the record encryption was successful.
+ *   -1: if the record's AEAD-authenticator is invalid or, if sending,
+ *       an internal error occurred.
+ */
+int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send)
+{
+    EVP_CIPHER_CTX *ctx;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+    size_t ivlen, offset, loop;
+    unsigned char *staticiv;
+    unsigned char *seq;
+    int lenu, lenf;
+    SSL3_RECORD *rec = &recs[0];
+
+    if (n_recs != 1) {
+        /* Should not happen */
+        /* TODO(TLS1.3): Support pipelining */
+        return -1;
+    }
+
+    if (send) {
+        ctx = s->enc_write_ctx;
+        staticiv = s->write_iv;
+        seq = RECORD_LAYER_get_write_sequence(&s->rlayer);
+    } else {
+        ctx = s->enc_read_ctx;
+        staticiv = s->read_iv;
+        seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
+    }
+
+    if (ctx == NULL) {
+        memmove(rec->data, rec->input, rec->length);
+        rec->input = rec->data;
+        return 1;
+    }
+    ivlen = EVP_CIPHER_CTX_iv_length(ctx);
+
+    if (!send) {
+        /*
+         * Take off tag. There must be at least one byte of content type as
+         * well as the tag
+         */
+        /*
+         * TODO(TLS1.3): We're going to need to figure out the tag len based on
+         * the cipher. For now we just support GCM tags.
+         * TODO(TLS1.3): When we've swapped over the record layer to TLSv1.3
+         * then the length must be 1 + the tag len to account for the content
+         * byte that we know must have been encrypted.
+         */
+        if (rec->length < EVP_GCM_TLS_TAG_LEN)
+            return 0;
+        rec->length -= EVP_GCM_TLS_TAG_LEN;
+    }
+
+    /* Set up IV */
+    if (ivlen < SEQ_NUM_SIZE) {
+        /* Should not happen */
+        return -1;
+    }
+    offset = ivlen - SEQ_NUM_SIZE;
+    memcpy(iv, staticiv, offset);
+    for (loop = 0; loop < SEQ_NUM_SIZE; loop++)
+        iv[offset + loop] = staticiv[offset + loop] ^ seq[loop];
+
+    /* TODO(size_t): lenu/lenf should be a size_t but EVP doesn't support it */
+    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, send) <= 0
+            || EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input,
+                                (unsigned int)rec->length) <= 0
+            || (!send && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
+                                             EVP_GCM_TLS_TAG_LEN,
+                                             rec->data + rec->length) <= 0)
+            || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0
+            || (size_t)(lenu + lenf) != rec->length) {
+        return -1;
+    }
+
+    if (send) {
+        /* Add the tag */
+        if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, EVP_GCM_TLS_TAG_LEN,
+                                rec->data + rec->length) <= 0)
+            return -1;
+        rec->length += EVP_GCM_TLS_TAG_LEN;
+    }
+
+    return 1;
+}
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index e909cad..cb29b99 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -960,10 +960,12 @@ struct ssl_st {
     unsigned char client_finished_secret[EVP_MAX_MD_SIZE];
     unsigned char server_finished_secret[EVP_MAX_MD_SIZE];
     EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
+    unsigned char read_iv[EVP_MAX_IV_LENGTH]; /* TLSv1.3 static read IV */
     EVP_MD_CTX *read_hash;      /* used for mac generation */
     COMP_CTX *compress;         /* compression */
     COMP_CTX *expand;           /* uncompress */
     EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
+    unsigned char write_iv[EVP_MAX_IV_LENGTH]; /* TLSv1.3 static write IV */
     EVP_MD_CTX *write_hash;     /* used for mac generation */
     /* session info */
     /* client cert? */
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index ce728b0..778f84e 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -79,7 +79,7 @@ SSL3_ENC_METHOD const TLSv1_2_enc_data = {
 };
 
 SSL3_ENC_METHOD const TLSv1_3_enc_data = {
-    tls1_enc,
+    tls13_enc,
     tls1_mac,
     tls13_setup_key_block,
     tls13_generate_master_secret,
@@ -89,8 +89,7 @@ SSL3_ENC_METHOD const TLSv1_3_enc_data = {
     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
     tls1_alert_code,
     tls1_export_keying_material,
-    SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF
-        | SSL_ENC_FLAG_TLS1_2_CIPHERS,
+    SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF,
     ssl3_set_handshake_header,
     tls_close_construct_packet,
     ssl3_handshake_write
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index 698b9be..5896a5f 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -284,7 +284,7 @@ int tls13_change_cipher_state(SSL *s, int which)
     static const unsigned char server_application_traffic[] =
         "server application traffic secret";
     unsigned char key[EVP_MAX_KEY_LENGTH];
-    unsigned char iv[EVP_MAX_IV_LENGTH];
+    unsigned char *iv;
     unsigned char secret[EVP_MAX_MD_SIZE];
     unsigned char *insecret;
     unsigned char *finsecret = NULL;
@@ -306,6 +306,7 @@ int tls13_change_cipher_state(SSL *s, int which)
             }
         }
         ciph_ctx = s->enc_read_ctx;
+        iv = s->read_iv;
 
         RECORD_LAYER_reset_read_sequence(&s->rlayer);
     } else {
@@ -319,6 +320,7 @@ int tls13_change_cipher_state(SSL *s, int which)
             }
         }
         ciph_ctx = s->enc_write_ctx;
+        iv = s->write_iv;
 
         RECORD_LAYER_reset_write_sequence(&s->rlayer);
     }
@@ -357,13 +359,7 @@ int tls13_change_cipher_state(SSL *s, int which)
 
     /* TODO(size_t): convert me */
     keylen = EVP_CIPHER_key_length(ciph);
-
-    if (EVP_CIPHER_mode(ciph) == EVP_CIPH_GCM_MODE)
-        ivlen = EVP_GCM_TLS_FIXED_IV_LEN;
-    else if (EVP_CIPHER_mode(ciph) == EVP_CIPH_CCM_MODE)
-        ivlen = EVP_CCM_TLS_FIXED_IV_LEN;
-    else
-        ivlen = EVP_CIPHER_iv_length(ciph);
+    ivlen = EVP_CIPHER_iv_length(ciph);
 
     if (!tls13_derive_key(s, secret, key, keylen)
             || !tls13_derive_iv(s, secret, iv, ivlen)
@@ -374,40 +370,10 @@ int tls13_change_cipher_state(SSL *s, int which)
         goto err;
     }
 
-    if (EVP_CIPHER_mode(ciph) == EVP_CIPH_GCM_MODE) {
-        if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, NULL,
-                               (which & SSL3_CC_WRITE))
-                || !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_GCM_SET_IV_FIXED,
-                                        (int)ivlen, iv)) {
-            SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_EVP_LIB);
-            goto err;
-        }
-    } else if (EVP_CIPHER_mode(ciph) == EVP_CIPH_CCM_MODE) {
-        int taglen;
-
-        if (s->s3->tmp.new_cipher->algorithm_enc
-                & (SSL_AES128CCM8 | SSL_AES256CCM8))
-            taglen = 8;
-        else
-            taglen = 16;
-        if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL,
-                               (which & SSL3_CC_WRITE))
-                || !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, 12,
-                                        NULL)
-                || !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, taglen,
-                                        NULL)
-                || !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_CCM_SET_IV_FIXED,
-                                        (int)ivlen, iv)
-                || !EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1)) {
-            SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_EVP_LIB);
-            goto err;
-        }
-    } else {
-        if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, iv,
-                               (which & SSL3_CC_WRITE))) {
-            SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_EVP_LIB);
-            goto err;
-        }
+    if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, NULL,
+                          (which & SSL3_CC_WRITE)) <= 0) {
+        SSLerr(SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_EVP_LIB);
+        goto err;
     }
 
 #ifdef OPENSSL_SSL_TRACE_CRYPTO
@@ -417,22 +383,16 @@ int tls13_change_cipher_state(SSL *s, int which)
         if (ciph->key_len)
             s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
                             key, ciph->key_len, s, s->msg_callback_arg);
-        if (ivlen) {
-            if (EVP_CIPHER_mode(ciph) == EVP_CIPH_GCM_MODE)
-                wh |= TLS1_RT_CRYPTO_FIXED_IV;
-            else
-                wh |= TLS1_RT_CRYPTO_IV;
-            s->msg_callback(2, s->version, wh, iv, ivlen, s,
-                            s->msg_callback_arg);
-        }
+
+        wh |= TLS1_RT_CRYPTO_IV;
+        s->msg_callback(2, s->version, wh, iv, ivlen, s,
+                        s->msg_callback_arg);
     }
 #endif
 
     ret = 1;
-
  err:
     OPENSSL_cleanse(secret, sizeof(secret));
     OPENSSL_cleanse(key, sizeof(key));
-    OPENSSL_cleanse(iv, sizeof(iv));
     return ret;
 }
diff --git a/test/build.info b/test/build.info
index efaf661..882f2da 100644
--- a/test/build.info
+++ b/test/build.info
@@ -321,7 +321,8 @@ IF[{- !$disabled{tests} -}]
   # Windows when building shared libraries, since the static libraries share
   # names with the DLL import libraries.
   IF[{- $disabled{shared} || $target{build_scheme}->[1] ne 'windows' -}]
-    PROGRAMS_NO_INST=asn1_internal_test modes_internal_test x509_internal_test
+    PROGRAMS_NO_INST=asn1_internal_test modes_internal_test x509_internal_test \
+                     tls13encryptiontest
     IF[{- !$disabled{poly1305} -}]
       PROGRAMS_NO_INST=poly1305_internal_test
     ENDIF
@@ -341,6 +342,10 @@ IF[{- !$disabled{tests} -}]
     SOURCE[x509_internal_test]=x509_internal_test.c testutil.c test_main.c
     INCLUDE[x509_internal_test]=.. ../include
     DEPEND[x509_internal_test]=../libcrypto.a
+
+    SOURCE[tls13encryptiontest]=tls13encryptiontest.c testutil.c test_main.c
+    INCLUDE[tls13encryptiontest]=.. ../include
+    DEPEND[tls13encryptiontest]=../libcrypto ../libssl.a
   ENDIF
 
   IF[{- !$disabled{mdc2} -}]
diff --git a/test/recipes/90-test_tls13secrets.t b/test/recipes/90-test_tls13encryption.t
similarity index 76%
copy from test/recipes/90-test_tls13secrets.t
copy to test/recipes/90-test_tls13encryption.t
index 5490885..63e62db 100644
--- a/test/recipes/90-test_tls13secrets.t
+++ b/test/recipes/90-test_tls13encryption.t
@@ -9,12 +9,12 @@
 use OpenSSL::Test;
 use OpenSSL::Test::Utils;
 
-my $test_name = "tls13secrets";
+my $test_name = "tls13encryption";
 setup($test_name);
 
 plan skip_all => "$test_name is not supported in this build"
-    if disabled("tls1_3") || disabled("shared");
+    if disabled("tls1_3");
 
 plan tests => 1;
 
-ok(run(test(["tls13secretstest"])), "running tls13secretstest");
+ok(run(test(["tls13encryptiontest"])), "running tls13encryptiontest");
diff --git a/test/tls13encryptiontest.c b/test/tls13encryptiontest.c
new file mode 100644
index 0000000..06bbbb3
--- /dev/null
+++ b/test/tls13encryptiontest.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include "../ssl/ssl_locl.h"
+#include "../ssl/record/record_locl.h"
+
+#include "testutil.h"
+#include "test_main.h"
+
+/*
+ * Based on the test vectors provided in:
+ * https://www.ietf.org/id/draft-thomson-tls-tls13-vectors-01.txt
+ */
+
+typedef struct {
+    /*
+     * We split these into 3 chunks in order to work around the 509 character
+     * limit that the standard specifies for string literals
+     */
+    const char *plaintext[3];
+    const char *ciphertext[3];
+    const char *key;
+    const char *iv;
+    const char *seq;
+} RECORD_DATA;
+
+static RECORD_DATA refdata[] = {
+    {
+        {
+            "0800001e001c000a00140012001d001700180019010001010102010301040000"
+            "00000b0001b9000001b50001b0308201ac30820115a003020102020102300d06"
+            "092a864886f70d01010b0500300e310c300a06035504031303727361301e170d"
+            "3136303733303031323335395a170d3236303733303031323335395a300e310c"
+            "300a0603550403130372736130819f300d06092a864886f70d01010105000381"
+            "8d0030818902818100b4bb498f8279303d980836399b36c6988c0c68de55e1bd"
+            "b826d3901a2461eafd2de49a91d015abbc9a95137ace6c1af19eaa6af98c7ced",
+            "43120998e187a80ee0ccb0524b1b018c3e0b63264d449a6d38e22a5fda430846"
+            "748030530ef0461c8ca9d9efbfae8ea6d1d03e2bd193eff0ab9a8002c47428a6"
+            "d35a8d88d79f7f1e3f0203010001a31a301830090603551d1304023000300b06"
+            "03551d0f0404030205a0300d06092a864886f70d01010b05000381810085aad2"
+            "a0e5b9276b908c65f73a7267170618a54c5f8a7b337d2df7a594365417f2eae8"
+            "f8a58c8f8172f9319cf36b7fd6c55b80f21a03015156726096fd335e5e67f2db"
+            "f102702e608ccae6bec1fc63a42a99be5c3eb7107c3c54e9b9eb2bd5203b1c3b",
+            "84e0a8b2f759409ba3eac9d91d402dcc0cc8f8961229ac9187b42b4de100000f"
+            "00008408040080134e22eac57321ab47db6b38b2992cec2dd79bd065a034a9af"
+            "6b9e3d03475e4309e6523ccdf055453fb480804a3a7e996229eb28e734f6702b"
+            "ea2b32149899ac043a4b44468197868da77147ce9f73c0543c4e3fc33e306cac"
+            "8506faa80a959c5f1edccbee76eda1ad7a4fa440de35dcb87e82ec94e8725355"
+            "ce7507713a609e140000207304bb73321f01b71dd94622fae98daf634490d220"
+            "e4c8f3ffa2559911a56e5116"
+        },
+        {
+            "40ae92071a3a548b26af31e116dfc0ba4549210b17e70da16cfbda9ccdad844d"
+            "94264a9ae65b786b3eaf0de20aa89c6babb448b6f32d07f233584296eefe1931"
+            "6bd979659472ee8567cb01d70b0366cddb3c60eb9e1d789a3691dc254c14de73"
+            "f4f20100504544ce184d44547e124b1f18303b4859f8f2e2b04423d23a866b43"
+            "866374d54af41649d25f4a3ec2cecd5d4e6de1b24953440b46fbb74c1dbec6fb"
+            "b1f16bc21d4aa0e1e936a49c07127e19719bc652a2f0b7f8df4a150b2b3c9e9e"
+            "353d6ed101970ddc611abad0632c6793f9379c9d06846c311fcbd6f85edd569b",
+            "8782c4c5f62294c4611ae60f83230a53aa95e3bcbed204f19a7a1db83c0fbfec"
+            "1edd2c17498fa7b5aa2321248a92592d891e4947df6bcef52f4481797d032ad3"
+            "32046a384abece6454b3e356d7249bfa5696793c7f7d3048dc87fa7409a46918"
+            "87caaf0982c402b902d699f62dc4d5e153f13e8589e4a6206c7f74eb26ddefbb"
+            "92309fb753decfea972dec7de02eda9c6d26acd7be53a8aa20f1a93f082ae6eb"
+            "927a6a1b7bd9153551aedfaf94f61dd4cb9355ad7ab09f615d9f92c21712c732"
+            "c0e7e117797f38cbdc184e3a65e15a89f46cb3624f5fdb8dbbd275f2c8492f8d",
+            "95bdbd8d1dc1b9f21107bd433acbbac247239c073a2f24a4a9f8074f325f277d"
+            "579b6bff0269ff19aed3809a9ddd21dd29c1363c9dc44812dd41d2111f9c2e83"
+            "42046c14133b853262676f15e94de18660e04ae5c0c661ea43559af5842e161c"
+            "83dd29f64508b2ec3e635a2134fc0e1a39d3ecb51dcddfcf8382c88ffe2a7378"
+            "42ad1de7fe505b6c4d1673870f6fc2a0f2f7972acaee368a1599d64ba18798f1"
+            "0333f9779bd5b05f9b084d03dab2f3d80c2eb74ec70c9866ea31c18b491cd597"
+            "aae3e941205fcc38a3a10ce8c0269f02ccc9c51278e25f1a0f0731a9"
+        },
+        "d2dd45f87ad87801a85ac38187f9023b",
+        "f0a14f808692cef87a3daf70",
+        "0000000000000000"
+    },
+    {
+        {
+            "1400002078367856d3c8cc4e0a95eb98906ca7a48bd3cc7029f48bd4ae0dc91a"
+            "b903ca8916","",""
+        },
+        {
+            "fa15e92daa21cd05d8f9c3152a61748d9aaf049da559718e583f95aacecad657"
+            "b52a6562da09a5819e864d86ac2989360a1eb22795","",""
+        },
+        "40e1201d75d419627f04c88530a15c9d",
+        "a0f073f3b35e18f96969696b",
+        "0000000000000000"
+    },
+    {
+        {
+            "040000a60002a3004abe594b00924e535321cadc96238da09caf9b02fecafdd6"
+            "5e3e418f03e43772cf512ed8066100503b1c08abbbf298a9d138ce821dd12fe1"
+            "710e2137cd12e6a85cd3fd7f73706e7f5dddefb87c1ef83824638464099c9d13"
+            "63e3c64ed2075c16b8ccd8e524a6bbd7a6a6e34ea1579782b15bbe7dfed5c0c0"
+            "d980fb330f9d8ab252ffe7be1277d418b6828ead4dae3b30d448442417ef76af"
+            "0008002e00040002000016","",""
+        },
+        {
+            "45a6626fa13b66ce2c5b3ef807e299a118296f26a2dd9ec7487a0673e2460d4c"
+            "79f40087dcd014c59c51379c90d26b4e4f9bb2b78f5b6761594f013ff3e4c78d"
+            "836905229eac811c4ef8b2faa89867e9ffc586f7f03c216591aa5e620eac3c62"
+            "dfe60f846036bd7ecc4464b584af184e9644e94ee1d7834dba408a51cbe42480"
+            "04796ed9c558e0f5f96115a6f6ba487e17d16a2e20a3d3a650a9a070fb53d9da"
+            "82864b5621d77650bd0c7947e9889917b53d0515627c72b0ded521","",""
+        },
+        "3381f6b3f94500f16226de440193e858",
+        "4f1d73cc1d465eb30021c41f",
+        "0000000000000000"
+    },
+    {
+        {
+            "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
+            "202122232425262728292a2b2c2d2e2f303117","",""
+        },
+        {
+            "e306178ad97f74bb64f35eaf3c39846b83aef8472cbc9046749b81a949dfb12c"
+            "fbc65cbabd20ade92c1f944605892ceeb12fdee8a927bce77c83036ac5a794a8"
+            "f54a69","",""
+        },
+        "eb23a804904b80ba4fe8399e09b1ce42",
+        "efa8c50c06b9c9b8c483e174",
+        "0000000000000000"
+    },
+    {
+        {
+            "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
+            "202122232425262728292a2b2c2d2e2f303117","",""
+        },
+        {
+            "467d99a807dbf778e6ffd8be52456c70665f890811ef2f3c495d5bbe983feeda"
+            "b0c251dde596bc7e2b135909ec9f9166fb0152e8c16a84e4b1039256467f9538"
+            "be4463","",""
+        },
+        "3381f6b3f94500f16226de440193e858",
+        "4f1d73cc1d465eb30021c41f",
+        "0000000000000001"
+    },
+    {
+        {
+            "010015","",""
+        },
+        {
+            "6bdf60847ba6fb650da36e872adc684a4af2e8","",""
+        },
+        "eb23a804904b80ba4fe8399e09b1ce42",
+        "efa8c50c06b9c9b8c483e174",
+        "0000000000000001"
+    },
+    {
+        {
+            "010015","",""
+        },
+        {
+            "621b7cc1962cd8a70109fee68a52efedf87d2e","",""
+        },
+        "3381f6b3f94500f16226de440193e858",
+        "4f1d73cc1d465eb30021c41f",
+        "0000000000000002"
+    }
+};
+
+/*
+ * Same thing as OPENSSL_hexstr2buf() but enables us to pass the string in
+ * 3 chunks
+ */
+static unsigned char *multihexstr2buf(const char *str[3], size_t *len)
+{
+    size_t outer, inner, curr = 0;
+    unsigned char *outbuf;
+    size_t totlen = 0;
+
+    /* Check lengths of all input strings are even */
+    for (outer = 0; outer < 3; outer++) {
+        totlen += strlen(str[outer]);
+        if ((totlen & 1) != 0)
+            return NULL;
+    }
+
+    totlen /= 2;
+    outbuf = OPENSSL_malloc(totlen);
+    if (outbuf == NULL)
+        return NULL;
+
+    for (outer = 0; outer < 3; outer++) {
+        for (inner = 0; str[outer][inner] != 0; inner += 2) {
+            int hi, lo;
+
+            hi = OPENSSL_hexchar2int(str[outer][inner]);
+            lo = OPENSSL_hexchar2int(str[outer][inner + 1]);
+
+            if (hi < 0 || lo < 0) {
+                OPENSSL_free(outbuf);
+                return NULL;
+            }
+            outbuf[curr++] = (hi << 4) | lo;
+        }
+    }
+
+    *len = totlen;
+    return outbuf;
+}
+
+static int load_record(SSL3_RECORD *rec, RECORD_DATA *recd, unsigned char **key,
+                       unsigned char *iv, size_t ivlen, unsigned char *seq)
+{
+    unsigned char *pt = NULL, *sq = NULL, *ivtmp = NULL;
+    size_t ptlen;
+
+    *key = OPENSSL_hexstr2buf(recd->key, NULL);
+    ivtmp = OPENSSL_hexstr2buf(recd->iv, NULL);
+    sq = OPENSSL_hexstr2buf(recd->seq, NULL);
+    pt = multihexstr2buf(recd->plaintext, &ptlen);
+
+    if (*key == NULL || ivtmp == NULL || sq == NULL || pt == NULL)
+        goto err;
+
+    rec->data = rec->input = OPENSSL_malloc(ptlen + EVP_GCM_TLS_TAG_LEN);
+
+    if (rec->data == NULL)
+        goto err;
+
+    rec->length = ptlen;
+    memcpy(rec->data, pt, ptlen);
+    OPENSSL_free(pt);
+    memcpy(seq, sq, SEQ_NUM_SIZE);
+    OPENSSL_free(sq);
+    memcpy(iv, ivtmp, ivlen);
+    OPENSSL_free(ivtmp);
+
+    return 1;
+ err:
+    OPENSSL_free(*key);
+    *key = NULL;
+    OPENSSL_free(ivtmp);
+    OPENSSL_free(sq);
+    OPENSSL_free(pt);
+    return 0;
+}
+
+static int test_record(SSL3_RECORD *rec, RECORD_DATA *recd, int enc)
+{
+    int ret = 0;
+    unsigned char *refd;
+    size_t refdatalen;
+
+    if (enc)
+        refd = multihexstr2buf(recd->ciphertext, &refdatalen);
+    else
+        refd = multihexstr2buf(recd->plaintext, &refdatalen);
+
+    if (refd == NULL) {
+        fprintf(stderr, "Failed to get reference data\n");
+        goto err;
+    }
+
+    if (rec->length != refdatalen) {
+        fprintf(stderr, "Unexpected length\n");
+        goto err;
+    }
+
+    if (memcmp(rec->data, refd, refdatalen) != 0) {
+        fprintf(stderr, "Data does not match\n");
+        goto err;
+    }
+
+    ret = 1;
+
+ err:
+    OPENSSL_free(refd);
+    return ret;
+}
+
+static int test_tls13_encryption(void)
+{
+    SSL_CTX *ctx = NULL;
+    SSL *s = NULL;
+    SSL3_RECORD rec;
+    unsigned char *key = NULL, *iv = NULL, *seq = NULL;
+    const EVP_CIPHER *ciph = EVP_aes_128_gcm();
+    int ret = 0;
+    size_t ivlen, ctr;
+
+    rec.data = NULL;
+
+    ctx = SSL_CTX_new(TLS_method());
+    if (ctx == NULL) {
+        fprintf(stderr, "Failed creating SSL_CTX\n");
+        goto err;
+    }
+
+    s = SSL_new(ctx);
+    if (s == NULL) {
+        fprintf(stderr, "Failed creating SSL\n");
+        goto err;
+    }
+
+    s->enc_read_ctx = EVP_CIPHER_CTX_new();
+    s->enc_write_ctx = EVP_CIPHER_CTX_new();
+    if (s->enc_read_ctx == NULL || s->enc_write_ctx == NULL) {
+        fprintf(stderr, "Failed creating EVP_CIPHER_CTX\n");
+        goto err;
+    }
+
+    for (ctr = 0; ctr < OSSL_NELEM(refdata); ctr++) {
+        /* Load the record */
+        ivlen = EVP_CIPHER_iv_length(ciph);
+        if (!load_record(&rec, &refdata[ctr], &key, s->read_iv, ivlen,
+                         RECORD_LAYER_get_read_sequence(&s->rlayer))) {
+            fprintf(stderr, "Failed loading key into EVP_CIPHER_CTX\n");
+            goto err;
+        }
+
+        /* Set up the read/write sequences */
+        memcpy(RECORD_LAYER_get_write_sequence(&s->rlayer),
+               RECORD_LAYER_get_read_sequence(&s->rlayer), SEQ_NUM_SIZE);
+        memcpy(s->write_iv, s->read_iv, ivlen);
+
+        /* Load the key into the EVP_CIPHER_CTXs */
+        if (EVP_CipherInit_ex(s->enc_write_ctx, ciph, NULL, key, NULL, 1) <= 0
+                || EVP_CipherInit_ex(s->enc_read_ctx, ciph, NULL, key, NULL, 0)
+                   <= 0) {
+            fprintf(stderr, "Failed loading key into EVP_CIPHER_CTX\n");
+            goto err;
+        }
+
+        /* Encrypt it */
+        if (tls13_enc(s, &rec, 1, 1) != 1) {
+            fprintf(stderr, "Failed to encrypt record %"OSSLzu"\n", ctr);
+            goto err;
+        }
+        if (!test_record(&rec, &refdata[ctr], 1)) {
+            fprintf(stderr, "Record %"OSSLzu" encryption test failed\n", ctr);
+            goto err;
+        }
+
+        /* Decrypt it */
+        if (tls13_enc(s, &rec, 1, 0) != 1) {
+            fprintf(stderr, "Failed to decrypt record %"OSSLzu"\n", ctr);
+            goto err;
+        }
+        if (!test_record(&rec, &refdata[ctr], 0)) {
+            fprintf(stderr, "Record %"OSSLzu" decryption test failed\n", ctr);
+            goto err;
+        }
+
+        OPENSSL_free(rec.data);
+        OPENSSL_free(key);
+        OPENSSL_free(iv);
+        OPENSSL_free(seq);
+        rec.data = NULL;
+        key = NULL;
+        iv = NULL;
+        seq = NULL;
+    }
+
+    fprintf(stderr, "PASS: %"OSSLzu" records tested\n", ctr);
+    ret = 1;
+
+ err:
+    OPENSSL_free(rec.data);
+    OPENSSL_free(key);
+    OPENSSL_free(iv);
+    OPENSSL_free(seq);
+    SSL_free(s);
+    SSL_CTX_free(ctx);
+    return ret;
+}
+
+void register_tests(void)
+{
+    ADD_TEST(test_tls13_encryption);
+}
diff --git a/util/TLSProxy/Record.pm b/util/TLSProxy/Record.pm
index 7189035..5a35925 100644
--- a/util/TLSProxy/Record.pm
+++ b/util/TLSProxy/Record.pm
@@ -242,8 +242,6 @@ sub decrypt()
             #an unecrypted alert, so don't try to decrypt
             return $data if (length($data) == 2);
         }
-        #8 bytes for a GCM IV
-        $data = substr($data, 8);
         $mactaglen = 16;
     } elsif ($self->version >= VERS_TLS_1_1()) {
         #16 bytes for a standard IV


More information about the openssl-commits mailing list