]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
DTLS 1.3 record number encryption
authorFrederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk>
Wed, 7 Feb 2024 12:30:00 +0000 (13:30 +0100)
committerTomas Mraz <tomas@openssl.org>
Thu, 9 Jan 2025 17:07:49 +0000 (18:07 +0100)
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23511)

24 files changed:
include/internal/recordmethod.h
include/openssl/dtls1.h
ssl/d1_lib.c
ssl/quic/quic_tls.c
ssl/record/methods/dtls_meth.c
ssl/record/methods/ktls_meth.c
ssl/record/methods/recmethod_local.h
ssl/record/methods/ssl3_meth.c
ssl/record/methods/tls13_meth.c
ssl/record/methods/tls1_meth.c
ssl/record/methods/tls_common.c
ssl/record/methods/tlsany_meth.c
ssl/record/rec_layer_s3.c
ssl/record/record.h
ssl/s3_enc.c
ssl/s3_lib.c
ssl/ssl_ciph.c
ssl/ssl_local.h
ssl/ssl_txt.c
ssl/statem/statem_clnt.c
ssl/t1_enc.c
ssl/tls13_enc.c
test/tls13encryptiontest.c
test/tls13secretstest.c

index 53bd4ca6d2b11cb956c40b75dc1ff9599f3ce3fb..d68c1c56f9a19ed14e68f250bc14bf1e6d96eb77 100644 (file)
@@ -126,12 +126,15 @@ struct ossl_record_method_st {
                             uint16_t epoch,
                             unsigned char *secret,
                             size_t secretlen,
+                            unsigned char *snkey,
                             unsigned char *key,
                             size_t keylen,
                             unsigned char *iv,
                             size_t ivlen,
                             unsigned char *mackey,
                             size_t mackeylen,
+                            const EVP_CIPHER *snciph,
+                            size_t snoffs,
                             const EVP_CIPHER *ciph,
                             size_t taglen,
                             int mactype,
index 024584f426e9c48eaee0804d3075410cb9416440..e5096d1ef5344b2b47e3cb69cda090bc117b6edd 100644 (file)
@@ -34,10 +34,11 @@ extern "C" {
 /* Special value for method supporting multiple versions */
 # define DTLS_ANY_VERSION                0x1FFFF
 
-/* lengths of messages */
+/* DTLS records and messages lengths and offsets */
 
 # define DTLS1_COOKIE_LENGTH                     255
 
+# define DTLS1_RT_HEADER_SEQ_OFFS                5
 # define DTLS1_RT_HEADER_LENGTH                  13
 
 # define DTLS1_HM_HEADER_LENGTH                  12
index 2db9fb110501aaccb54867bc4e96e086688fa443..681c50889a9d548c6728d91b36689d79eb6f0f8e 100644 (file)
@@ -845,12 +845,11 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client)
      * Reset the record layer - but this time we can use the record we just
      * buffered in s->rlayer.rrlnext
      */
-    if (!ssl_set_new_record_layer(s,
-                                  DTLS_ANY_VERSION,
+    if (!ssl_set_new_record_layer(s, DTLS_ANY_VERSION,
                                   OSSL_RECORD_DIRECTION_READ,
                                   OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0,
-                                  NULL, 0, NULL, 0, NULL,  0, NULL, 0,
-                                  NID_undef, NULL, NULL, NULL)) {
+                                  NULL, NULL, 0, NULL, 0, NULL,  0, NULL, 0, NULL,
+                                  0, NID_undef, NULL, NULL, NULL)) {
         /* SSLfatal already called */
         ret = -1;
         goto end;
index bd560c9a91a3091316303c0cead52ec12c10f8b5..eaf49dc5b757e43594034eac5343cb147c14531c 100644 (file)
@@ -91,8 +91,10 @@ static int
 quic_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
                       int role, int direction, int level, uint16_t epoch,
                       unsigned char *secret, size_t secretlen,
-                      unsigned char *key, size_t keylen, unsigned char *iv,
-                      size_t ivlen, unsigned char *mackey, size_t mackeylen,
+                      unsigned char *snkey, unsigned char *key, size_t keylen,
+                      unsigned char *iv, size_t ivlen,
+                      unsigned char *mackey, size_t mackeylen,
+                      const EVP_CIPHER *snciph, size_t snoffs,
                       const EVP_CIPHER *ciph, size_t taglen,
                       int mactype,
                       const EVP_MD *md, COMP_METHOD *comp,
index 7ed4450e1b9dc707c64513c79743f93ef55e311a..a939238ddefa07075a65c054b2d46c5e322d041e 100644 (file)
@@ -365,6 +365,42 @@ static int dtls_retrieve_rlayer_buffered_record(OSSL_RECORD_LAYER *rl,
     return 0;
 }
 
+/* rfc9147 section 4.2.3 */
+int dtls_crypt_sequence_number(EVP_CIPHER_CTX *ctx, unsigned char *seq,
+                               unsigned char *rec_data, size_t rec_data_offs)
+{
+    unsigned char mask[16];
+    int outlen, inlen;
+    unsigned char *iv, *in;
+    size_t i;
+    size_t seq_len = 6;
+
+    if (ossl_assert(sizeof(mask) > rec_data_offs))
+        inlen = (int)(sizeof(mask) - rec_data_offs);
+    else
+        return 0;
+
+    iv = rec_data_offs == 0 ? NULL : rec_data;
+    in = rec_data + rec_data_offs;
+    memset(mask, 0, sizeof(mask));
+
+    if (!ossl_assert(inlen >= 0)
+            || (size_t)inlen > sizeof(mask)
+            || EVP_CipherInit_ex2(ctx, NULL, NULL, iv, 1, NULL) <= 0
+            || EVP_CipherUpdate(ctx, mask, &outlen, in, inlen) <= 0
+            || outlen != inlen
+            || EVP_CipherFinal_ex(ctx, mask + outlen, &outlen) <= 0
+            || outlen != 0)
+        return 0;
+
+    for (i = 0; i < seq_len; i++)
+        seq[i] ^= mask[i];
+
+    OPENSSL_cleanse(mask, sizeof(mask));
+
+    return 1;
+}
+
 /*-
  * Call this to get a new input record.
  * It will return <= 0 if more data is needed, normally due to an error
@@ -516,6 +552,24 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
     /* set state for later operations */
     rl->rstate = SSL_ST_READ_HEADER;
 
+    /*
+     * rfc9147:
+     * This procedure requires the ciphertext length to be at least 16 bytes.
+     * Receivers MUST reject shorter records as if they had failed deprotection
+     * TODO(DTLSv1.3): This check will need to be modified when support for variable
+     * length headers is added.
+     */
+    if (rl->sn_enc_ctx != NULL
+            && (rl->packet_length < DTLS1_RT_HEADER_LENGTH + 16
+                || !dtls_crypt_sequence_number(rl->sn_enc_ctx, &(rl->sequence[2]),
+                                               rl->packet + DTLS1_RT_HEADER_LENGTH,
+                                               rl->sn_enc_offs))) {
+        /* sequence number encryption failed dump record */
+        rr->length = 0;
+        rl->packet_length = 0;
+        goto again;
+    }
+
     /* match epochs.  NULL means the packet is dropped on the floor */
     bitmap = dtls_get_bitmap(rl, rr, &is_next_epoch);
     if (bitmap == NULL) {
@@ -628,8 +682,10 @@ static int
 dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
                       int role, int direction, int level, uint16_t epoch,
                       unsigned char *secret, size_t secretlen,
-                      unsigned char *key, size_t keylen, unsigned char *iv,
-                      size_t ivlen, unsigned char *mackey, size_t mackeylen,
+                      unsigned char *snkey, unsigned char *key, size_t keylen,
+                      unsigned char *iv, size_t ivlen,
+                      unsigned char *mackey, size_t mackeylen,
+                      const EVP_CIPHER *snciph, size_t snoffs,
                       const EVP_CIPHER *ciph, size_t taglen,
                       int mactype,
                       const EVP_MD *md, COMP_METHOD *comp,
@@ -683,9 +739,10 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
         goto err;
     }
 
-    ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
-                                            ivlen, mackey, mackeylen, ciph,
-                                            taglen, mactype, md, comp);
+    ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen,
+                                            iv, ivlen, mackey, mackeylen,
+                                            snciph, snoffs, ciph, taglen, mactype, md,
+                                            comp);
 
  err:
     if (ret != OSSL_RECORD_RETURN_SUCCESS) {
index 33c7140e151f0b87da103454f697f5fa37a33ea2..3d1225d40910c8a42594ec7d9466879ee034296c 100644 (file)
@@ -287,9 +287,11 @@ int ktls_configure_crypto(OSSL_LIB_CTX *libctx, int version, const EVP_CIPHER *c
 #endif /* OPENSSL_SYS_LINUX */
 
 static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
+                                 unsigned char *snkey,
                                  unsigned char *key, size_t keylen,
                                  unsigned char *iv, size_t ivlen,
                                  unsigned char *mackey, size_t mackeylen,
+                                 const EVP_CIPHER *snciph, size_t snoffs,
                                  const EVP_CIPHER *ciph,
                                  size_t taglen,
                                  int mactype,
@@ -403,8 +405,10 @@ static int
 ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
                       int role, int direction, int level, uint16_t epoch,
                       unsigned char *secret, size_t secretlen,
-                      unsigned char *key, size_t keylen, unsigned char *iv,
-                      size_t ivlen, unsigned char *mackey, size_t mackeylen,
+                      unsigned char *snkey, unsigned char *key, size_t keylen,
+                      unsigned char *iv, size_t ivlen,
+                      unsigned char *mackey, size_t mackeylen,
+                      const EVP_CIPHER *snciph, size_t snoffs,
                       const EVP_CIPHER *ciph, size_t taglen,
                       int mactype,
                       const EVP_MD *md, COMP_METHOD *comp,
@@ -426,9 +430,10 @@ ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
 
     (*retrl)->funcs = &ossl_ktls_funcs;
 
-    ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
-                                            ivlen, mackey, mackeylen, ciph,
-                                            taglen, mactype, md, comp);
+    ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen,
+                                            iv, ivlen, mackey, mackeylen,
+                                            snciph, snoffs, ciph, taglen, mactype, md,
+                                            comp);
 
     if (ret != OSSL_RECORD_RETURN_SUCCESS) {
         OPENSSL_free(*retrl);
index 73c45436f8f8e2eb44b143423685c92f55eb114a..d38ee2c7cd7b612d76a9273bb2f00dc47e51f808 100644 (file)
@@ -98,9 +98,11 @@ struct record_functions_st {
      * alternative record layer.
      */
     int (*set_crypto_state)(OSSL_RECORD_LAYER *rl, int level,
+                            unsigned char *snkey,
                             unsigned char *key, size_t keylen,
                             unsigned char *iv, size_t ivlen,
                             unsigned char *mackey, size_t mackeylen,
+                            const EVP_CIPHER *snciph, size_t snoffs,
                             const EVP_CIPHER *ciph,
                             size_t taglen,
                             int mactype,
@@ -292,6 +294,9 @@ struct ossl_record_layer_st {
 
     /* cryptographic state */
     EVP_CIPHER_CTX *enc_ctx;
+    /* cryptographic state for DTLS sequence numbers */
+    EVP_CIPHER_CTX *sn_enc_ctx;
+    size_t sn_enc_offs;
 
     /* TLSv1.3 MAC ctx, only used with integrity-only cipher */
     EVP_MAC_CTX *mac_ctx;
@@ -417,6 +422,9 @@ int tls_free_buffers(OSSL_RECORD_LAYER *rl);
 int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
                        int clearold, size_t *readbytes);
 int tls_get_more_records(OSSL_RECORD_LAYER *rl);
+
+int dtls_crypt_sequence_number(EVP_CIPHER_CTX *ctx, unsigned char *seq,
+                               unsigned char *rec_data, size_t rec_data_offs);
 int dtls_get_more_records(OSSL_RECORD_LAYER *rl);
 
 int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl,
index 6b5a1bed23ebe6a6792672f1fd8035a867fb4dcc..b424cef278eb7fed253aba0263627bdd7c3b02bd 100644 (file)
 #include "recmethod_local.h"
 
 static int ssl3_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
+                                 unsigned char *snkey,
                                  unsigned char *key, size_t keylen,
                                  unsigned char *iv, size_t ivlen,
                                  unsigned char *mackey, size_t mackeylen,
+                                 const EVP_CIPHER *snciph, size_t snoffs,
                                  const EVP_CIPHER *ciph,
                                  size_t taglen,
                                  int mactype,
index 53acb6f7a614204faad040cefac635c237a5cc34..dd44764059c718c1b14769288e3fef67a6b2fc75 100644 (file)
 #include "recmethod_local.h"
 
 static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
+                                  unsigned char *snkey,
                                   unsigned char *key, size_t keylen,
                                   unsigned char *iv, size_t ivlen,
                                   unsigned char *mackey, size_t mackeylen,
+                                  const EVP_CIPHER *snciph, size_t snoffs,
                                   const EVP_CIPHER *ciph,
                                   size_t taglen,
                                   int mactype,
@@ -78,6 +80,27 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
         ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
         return OSSL_RECORD_RETURN_FATAL;
     }
+
+    if (rl->isdtls && snciph != NULL) {
+        EVP_CIPHER_CTX *sn_ciph_ctx;
+
+        sn_ciph_ctx = rl->sn_enc_ctx = EVP_CIPHER_CTX_new();
+
+        if (sn_ciph_ctx == NULL) {
+            ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
+            return OSSL_RECORD_RETURN_FATAL;
+        }
+
+        rl->sn_enc_offs = snoffs;
+
+        if (EVP_CIPHER_CTX_set_padding(sn_ciph_ctx, 0)
+                || EVP_CipherInit_ex(sn_ciph_ctx, snciph, NULL,
+                                     snkey, NULL, 1) <= 0) {
+            ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
+            return OSSL_RECORD_RETURN_FATAL;
+        }
+    }
+
  end:
     return OSSL_RECORD_RETURN_SUCCESS;
 }
index 9275e19fbd3fb3dead52ea31b94c256d8ea5c63d..aaf13051c476ccfd1af1224283355c725003a2b1 100644 (file)
 #include "recmethod_local.h"
 
 static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
+                                 unsigned char *snkey,
                                  unsigned char *key, size_t keylen,
                                  unsigned char *iv, size_t ivlen,
                                  unsigned char *mackey, size_t mackeylen,
+                                 const EVP_CIPHER *snciph, size_t snoffs,
                                  const EVP_CIPHER *ciph,
                                  size_t taglen,
                                  int mactype,
index 317ec169fb63c22e15cd11af93e022102544bd2b..77b09720136d75371f9638f82676e1a1a83e02b2 100644 (file)
@@ -1387,8 +1387,10 @@ static int
 tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
                      int role, int direction, int level, uint16_t epoch,
                      unsigned char *secret, size_t secretlen,
-                     unsigned char *key, size_t keylen, unsigned char *iv,
-                     size_t ivlen, unsigned char *mackey, size_t mackeylen,
+                     unsigned char *snkey, unsigned char *key, size_t keylen,
+                     unsigned char *iv, size_t ivlen,
+                     unsigned char *mackey, size_t mackeylen,
+                     const EVP_CIPHER *snciph, size_t snoffs,
                      const EVP_CIPHER *ciph, size_t taglen,
                      int mactype,
                      const EVP_MD *md, COMP_METHOD *comp,
@@ -1430,9 +1432,10 @@ tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
         goto err;
     }
 
-    ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
-                                            ivlen, mackey, mackeylen, ciph,
-                                            taglen, mactype, md, comp);
+    ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen,
+                                            iv, ivlen, mackey, mackeylen,
+                                            snciph, snoffs, ciph, taglen, mactype, md,
+                                            comp);
 
  err:
     if (ret != OSSL_RECORD_RETURN_SUCCESS) {
@@ -1452,6 +1455,7 @@ static void tls_int_free(OSSL_RECORD_LAYER *rl)
     tls_release_write_buffer(rl);
 
     EVP_CIPHER_CTX_free(rl->enc_ctx);
+    EVP_CIPHER_CTX_free(rl->sn_enc_ctx);
     EVP_MAC_CTX_free(rl->mac_ctx);
     EVP_MD_CTX_free(rl->md_ctx);
 #ifndef OPENSSL_NO_COMP
@@ -1720,6 +1724,19 @@ int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl,
         return 0;
     }
 
+    if (rl->sn_enc_ctx != NULL) {
+        unsigned char *recordstart;
+
+        recordstart = WPACKET_get_curr(thispkt) - len - headerlen;
+
+        if (!dtls_crypt_sequence_number(rl->sn_enc_ctx, recordstart + DTLS1_RT_HEADER_SEQ_OFFS,
+                                        recordstart + DTLS1_RT_HEADER_LENGTH,
+                                        rl->sn_enc_offs)) {
+            RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
+
     if (rl->msg_callback != NULL) {
         unsigned char *recordstart;
         const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;
index 0cf04d7fa7b252318cad4d40788eac9e06b0b81d..6d6555a715c374cc25393a326e71d6935013f09b 100644 (file)
 #define MIN_SSL2_RECORD_LEN     9
 
 static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
+                                    unsigned char *snkey,
                                     unsigned char *key, size_t keylen,
                                     unsigned char *iv, size_t ivlen,
                                     unsigned char *mackey, size_t mackeylen,
+                                    const EVP_CIPHER *snciph, size_t snoffs,
                                     const EVP_CIPHER *ciph,
                                     size_t taglen,
                                     int mactype,
index 7022d08cea11f4ec5cbdbebca4d81a7bee2cad2c..10d3b864d86479311d839a1971635d6080163cc2 100644 (file)
@@ -81,16 +81,16 @@ int RECORD_LAYER_reset(RECORD_LAYER *rl)
                                         ? DTLS_ANY_VERSION : TLS_ANY_VERSION,
                                     OSSL_RECORD_DIRECTION_READ,
                                     OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0,
-                                    NULL, 0, NULL, 0, NULL,  0, NULL, 0,
-                                    NID_undef, NULL, NULL, NULL);
+                                    NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL,
+                                    0, NID_undef, NULL, NULL, NULL);
 
     ret &= ssl_set_new_record_layer(rl->s,
                                     SSL_CONNECTION_IS_DTLS(rl->s)
                                         ? DTLS_ANY_VERSION : TLS_ANY_VERSION,
                                     OSSL_RECORD_DIRECTION_WRITE,
                                     OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0,
-                                    NULL, 0, NULL, 0, NULL,  0, NULL, 0,
-                                    NID_undef, NULL, NULL, NULL);
+                                    NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL,
+                                    0, NID_undef, NULL, NULL, NULL);
 
     /* SSLfatal already called in the event of failure */
     return ret;
@@ -1235,9 +1235,11 @@ static int ssl_post_record_layer_select(SSL_CONNECTION *s, int direction)
 int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
                              int direction, int level,
                              unsigned char *secret, size_t secretlen,
+                             unsigned char *snkey,
                              unsigned char *key, size_t keylen,
                              unsigned char *iv,  size_t ivlen,
                              unsigned char *mackey, size_t mackeylen,
+                             const EVP_CIPHER *snciph, size_t snoffs,
                              const EVP_CIPHER *ciph, size_t taglen,
                              int mactype, const EVP_MD *md,
                              const SSL_COMP *comp, const EVP_MD *kdfdigest)
@@ -1413,9 +1415,11 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
 
         rlret = meth->new_record_layer(sctx->libctx, sctx->propq, version,
                                        s->server, direction, level, epoch,
-                                       secret, secretlen, key, keylen, iv,
-                                       ivlen, mackey, mackeylen, ciph, taglen,
-                                       mactype, md, compm, kdfdigest, prev,
+                                       secret, secretlen, snkey, key, keylen,
+                                       iv,
+                                       ivlen, mackey, mackeylen, snciph, snoffs, ciph,
+                                       taglen, mactype, md, compm, kdfdigest,
+                                       prev,
                                        thisbio, next, NULL, NULL, settings,
                                        options, rlayer_dispatch_tmp, s,
                                        s->rlayer.rlarg, &newrl);
index 13f09fda8ccb771d70ab9d9ca727f91f16187f93..9bdf4f23bdda615c34bc1c4770ac3b68535637f5 100644 (file)
@@ -174,9 +174,11 @@ int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int writing, int ret,
 int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
                              int direction, int level,
                              unsigned char *secret, size_t secretlen,
+                             unsigned char *snkey,
                              unsigned char *key, size_t keylen,
-                             unsigned char *iv,  size_t ivlen,
+                             unsigned char *iv, size_t ivlen,
                              unsigned char *mackey, size_t mackeylen,
+                             const EVP_CIPHER *snciph, size_t snoffs,
                              const EVP_CIPHER *ciph, size_t taglen,
                              int mactype, const EVP_MD *md,
                              const SSL_COMP *comp, const EVP_MD *kdfdigest);
index cda1f7f83bcd0073f1c2dc8aa4f68c9a334c5e1f..6cad3c07778fb1e2c45d5db8783da16d27f0b83c 100644 (file)
@@ -144,11 +144,11 @@ int ssl3_change_cipher_state(SSL_CONNECTION *s, int which)
         goto err;
     }
 
-    if (!ssl_set_new_record_layer(s, SSL3_VERSION,
-                                  direction,
+    if (!ssl_set_new_record_layer(s, SSL3_VERSION, direction,
                                   OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
-                                  NULL, 0, key, key_len, iv, iv_len, mac_secret,
-                                  md_len, ciph, 0, NID_undef, md, comp, NULL)) {
+                                  NULL, 0, NULL, key, key_len, iv, iv_len,
+                                  mac_secret, md_len, NULL, 0, ciph, 0, NID_undef,
+                                  md, comp, NULL)) {
         /* SSLfatal already called */
         goto err;
     }
@@ -170,8 +170,8 @@ int ssl3_setup_key_block(SSL_CONNECTION *s)
     if (s->s3.tmp.key_block_length != 0)
         return 1;
 
-    if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash,
-                            NULL, NULL, &comp, 0)) {
+    if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, NULL, NULL, &c,
+                            &hash, NULL, NULL, &comp, 0)) {
         /* Error is already recorded */
         SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
         return 0;
index beece1153ab88a12a4d1b540b179c0911be81efc..e4f9bcbd8ae2dcf4a603d81a2248f7318f7fdfe6 100644 (file)
@@ -3415,6 +3415,7 @@ void ssl3_free(SSL *s)
     sc->s3.tmp.pkey = NULL;
 
     ssl_evp_cipher_free(sc->s3.tmp.new_sym_enc);
+    ssl_evp_cipher_free(sc->s3.tmp.new_sym_enc_sn);
     ssl_evp_md_free(sc->s3.tmp.new_hash);
 
     OPENSSL_free(sc->s3.tmp.ctype);
index 2e9c26a231b30be6451304eafff71a0e195a1395..ea057f8a5769c4243f0ae1e8fbb9ddc1b1baa336 100644 (file)
@@ -494,8 +494,51 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
     return 1;
 }
 
+int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc,
+                                 const EVP_CIPHER **enc, size_t *inputoffs)
+{
+    int i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, sslc->algorithm_enc);
+
+    if (i == -1) {
+        *enc = NULL;
+    } else {
+        if (i == SSL_ENC_NULL_IDX) {
+            /*
+             * We assume we don't care about this coming from an ENGINE so
+             * just do a normal EVP_CIPHER_fetch instead of
+             * ssl_evp_cipher_fetch()
+             */
+            *enc = EVP_CIPHER_fetch(ctx->libctx, "NULL", ctx->propq);
+        } else {
+            int ecbnid = NID_undef;
+
+            *enc = NULL;
+
+            if ((sslc->algorithm_enc & SSL_AES128_ANY) != 0) {
+                ecbnid = NID_aes_128_ecb;
+                *inputoffs = 0;
+            } else if ((sslc->algorithm_enc & SSL_AES256_ANY) != 0) {
+                ecbnid = NID_aes_256_ecb;
+                *inputoffs = 0;
+            } else if (ossl_assert((sslc->algorithm_enc & SSL_CHACHA20) != 0)) {
+                ecbnid = NID_chacha20;
+                *inputoffs = 4;
+            }
+
+            if (ecbnid != NID_undef)
+                *enc = ssl_evp_cipher_fetch(ctx->libctx, ecbnid, ctx->propq);
+        }
+
+        if (*enc == NULL)
+            return 0;
+    }
+    return 1;
+}
+
 int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
-                       const EVP_CIPHER **enc, const EVP_MD **md,
+                       const EVP_CIPHER **snenc, size_t *snencoffs,
+                       const EVP_CIPHER **enc,
+                       const EVP_MD **md,
                        int *mac_pkey_type, size_t *mac_secret_size,
                        SSL_COMP **comp, int use_etm)
 {
@@ -525,12 +568,18 @@ int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
     if ((enc == NULL) || (md == NULL))
         return 0;
 
-    if (!ssl_cipher_get_evp_cipher(ctx, c, enc))
+    if (!ssl_cipher_get_evp_cipher(ctx, c, enc)
+            || (snenc != NULL
+                && !ssl_cipher_get_evp_cipher_sn(ctx, c, snenc, snencoffs)))
         return 0;
 
     if (!ssl_cipher_get_evp_md_mac(ctx, c, md, mac_pkey_type,
                                    mac_secret_size)) {
         ssl_evp_cipher_free(*enc);
+
+        if (snenc != NULL)
+            ssl_evp_cipher_free(*snenc);
+
         return 0;
     }
 
index 4f606c3ef0eb0af68d67e74a1e97f2748e607aa0..ac4e516ac8e06742c735f64b20f7dd1cf247cc49 100644 (file)
 # define SSL_AESGCM              (SSL_AES128GCM | SSL_AES256GCM)
 # define SSL_AESCCM              (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8)
 # define SSL_AES                 (SSL_AES128|SSL_AES256|SSL_AESGCM|SSL_AESCCM)
+# define SSL_AES128_ANY          (SSL_AES128 | SSL_AES128CCM | SSL_AES128CCM8 \
+                                  | SSL_AES128GCM)
+# define SSL_AES256_ANY          (SSL_AES256 | SSL_AES256CCM | SSL_AES256CCM8 \
+                                  | SSL_AES256GCM)
 # define SSL_CAMELLIA            (SSL_CAMELLIA128|SSL_CAMELLIA256)
 # define SSL_CHACHA20            (SSL_CHACHA20POLY1305)
 # define SSL_ARIAGCM             (SSL_ARIA128GCM | SSL_ARIA256GCM)
@@ -1379,6 +1383,8 @@ struct ssl_connection_st {
             size_t key_block_length;
             unsigned char *key_block;
             const EVP_CIPHER *new_sym_enc;
+            const EVP_CIPHER *new_sym_enc_sn;
+            size_t new_sym_enc_sn_offs;
             const EVP_MD *new_hash;
             int new_mac_pkey_type;
             size_t new_mac_secret_size;
@@ -2593,11 +2599,15 @@ __owur int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites,
 void ssl_update_cache(SSL_CONNECTION *s, int mode);
 __owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc,
                                      const EVP_CIPHER **enc);
+__owur int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc,
+                                        const EVP_CIPHER **enc, size_t *inputoffs);
 __owur int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
                                      const EVP_MD **md,
                                      int *mac_pkey_type, size_t *mac_secret_size);
-__owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s,
-                              const EVP_CIPHER **enc, const EVP_MD **md,
+__owur int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
+                              const EVP_CIPHER **snenc, size_t *snencoffs,
+                              const EVP_CIPHER **enc,
+                              const EVP_MD **md,
                               int *mac_pkey_type, size_t *mac_secret_size,
                               SSL_COMP **comp, int use_etm);
 __owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
index 7f7af8a53a2d468246b5648314885b766bfbc2e4..e0afdb62adecb2a6a1dde0cde006b643bea21a93 100644 (file)
@@ -119,7 +119,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
     if (x->compress_meth != 0) {
         SSL_COMP *comp = NULL;
 
-        if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, &comp, 0))
+        if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, NULL, NULL, &comp, 0))
             goto err;
         if (comp == NULL) {
             if (BIO_printf(bp, "\n    Compression: %d", x->compress_meth) <= 0)
index f64df4bd546db49a395d9e962fa3e195cca000e5..5dd1cd6e408b790a0ff9cfe8831a839c2b751896 100644 (file)
@@ -727,9 +727,9 @@ WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst)
                                           TLS_ANY_VERSION,
                                           OSSL_RECORD_DIRECTION_WRITE,
                                           OSSL_RECORD_PROTECTION_LEVEL_NONE,
-                                          NULL, 0, NULL, 0, NULL, 0, NULL,  0,
-                                          NULL, 0, NID_undef, NULL, NULL,
-                                          NULL)) {
+                                          NULL, 0, NULL, NULL, 0, NULL, 0,
+                                          NULL, 0, NULL, 0, NULL, 0, NID_undef,
+                                          NULL, NULL, NULL)) {
                 /* SSLfatal already called */
                 return WORK_ERROR;
             }
@@ -1849,8 +1849,9 @@ static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL_CONNECTION *s,
             && !ssl_set_new_record_layer(s, versionany,
                                          OSSL_RECORD_DIRECTION_WRITE,
                                          OSSL_RECORD_PROTECTION_LEVEL_NONE,
-                                         NULL, 0, NULL, 0, NULL, 0, NULL,  0,
-                                         NULL, 0, NID_undef, NULL, NULL, NULL)) {
+                                         NULL, 0, NULL, NULL, 0, NULL, 0, NULL,
+                                         0, NULL, 0, NULL, 0, NID_undef, NULL,
+                                         NULL, NULL)) {
         /* SSLfatal already called */
         goto err;
     }
index 2e9e24a8cf94a320e9f840cbb9668f237abeef41..cbb3b0519692116f0d59e4ae3fdcf3727d23f13e 100644 (file)
@@ -232,10 +232,10 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which)
         dtls1_increment_epoch(s, which);
 
     if (!ssl_set_new_record_layer(s, s->version, direction,
-                                    OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
-                                    NULL, 0, key, cl, iv, (size_t)k, mac_secret,
-                                    mac_secret_size, c, taglen, mac_type,
-                                    m, comp, NULL)) {
+                                  OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
+                                  NULL, 0, NULL, key, cl, iv, (size_t)k,
+                                  mac_secret, mac_secret_size, NULL, 0, c, taglen,
+                                  mac_type, m, comp, NULL)) {
         /* SSLfatal already called */
         goto err;
     }
@@ -266,8 +266,8 @@ int tls1_setup_key_block(SSL_CONNECTION *s)
     if (s->s3.tmp.key_block_length != 0)
         return 1;
 
-    if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash,
-                            &mac_type, &mac_secret_size, &comp,
+    if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, NULL, NULL, &c,
+                            &hash, &mac_type, &mac_secret_size, &comp,
                             s->ext.use_etm)) {
         /* Error is already recorded */
         SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
index dacf72488893f58d03f32e5a84485beb0754d09f..c10472370db0b00b2478995e93251cdbef362058 100644 (file)
@@ -178,6 +178,21 @@ int tls13_derive_finishedkey(SSL_CONNECTION *s, const EVP_MD *md,
                              sizeof(finishedlabel) - 1, NULL, 0, fin, finlen, 1);
 }
 
+/*
+ * Given a |secret| generate a |snkey| of length |snkeylen| bytes. Returns 1 on
+ * success  0 on failure. (rfc9147 section 4.2.3)
+ */
+static int dtls13_derive_snkey(SSL_CONNECTION *s, const EVP_MD *md,
+                        const unsigned char *secret,
+                        unsigned char *snkey, size_t keylen)
+{
+    /* ASCII: "sn", in hex for EBCDIC compatibility */
+    static const unsigned char sn_str[] = "\x73\x6E";
+
+    return tls13_hkdf_expand(s, md, secret, sn_str, sizeof(sn_str) - 1,
+                             NULL, 0, snkey, keylen, 1);
+}
+
 /*
  * Given the previous secret |prevsecret| and a new input secret |insecret| of
  * length |insecretlen|, generate a new secret and store it in the location
@@ -352,13 +367,15 @@ size_t tls13_final_finish_mac(SSL_CONNECTION *s, const char *str, size_t slen,
 int tls13_setup_key_block(SSL_CONNECTION *s)
 {
     const EVP_CIPHER *c;
+    const EVP_CIPHER *snc = NULL, **p_snc = SSL_CONNECTION_IS_DTLS(s) ? &snc : NULL;
+    size_t snoffs;
     const EVP_MD *hash;
     int mac_type = NID_undef;
     size_t mac_secret_size = 0;
 
     s->session->cipher = s->s3.tmp.new_cipher;
-    if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash,
-                            &mac_type, &mac_secret_size, NULL, 0)) {
+    if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, p_snc, &snoffs, &c,
+                            &hash, &mac_type, &mac_secret_size, NULL, 0)) {
         /* Error is already recorded */
         SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
         return 0;
@@ -366,6 +383,9 @@ int tls13_setup_key_block(SSL_CONNECTION *s)
 
     ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
     s->s3.tmp.new_sym_enc = c;
+    ssl_evp_cipher_free(s->s3.tmp.new_sym_enc_sn);
+    s->s3.tmp.new_sym_enc_sn = snc;
+    s->s3.tmp.new_sym_enc_sn_offs = snoffs;
     ssl_evp_md_free(s->s3.tmp.new_hash);
     s->s3.tmp.new_hash = hash;
     s->s3.tmp.new_mac_pkey_type = mac_type;
@@ -382,6 +402,7 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md,
                                     const unsigned char *hash,
                                     const unsigned char *label,
                                     size_t labellen, unsigned char *secret,
+                                    unsigned char *snkey,
                                     unsigned char *key, size_t *keylen,
                                     unsigned char **iv, size_t *ivlen,
                                     size_t *taglen)
@@ -467,7 +488,9 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md,
     }
 
     if (!tls13_derive_key(s, md, secret, key, *keylen)
-            || !tls13_derive_iv(s, md, secret, *iv, *ivlen)) {
+            || !tls13_derive_iv(s, md, secret, *iv, *ivlen)
+            || (SSL_CONNECTION_IS_DTLS(s)
+                && !dtls13_derive_snkey(s, md, secret, snkey, *keylen))) {
         /* SSLfatal() already called */
         return 0;
     }
@@ -496,6 +519,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
     unsigned char iv_intern[EVP_MAX_IV_LENGTH];
     unsigned char *iv = iv_intern;
     unsigned char key[EVP_MAX_KEY_LENGTH];
+    unsigned char snkey[EVP_MAX_KEY_LENGTH];
+    size_t sn_input_offs = 0;
     unsigned char secret[EVP_MAX_MD_SIZE];
     unsigned char hashval[EVP_MAX_MD_SIZE];
     unsigned char *hash = hashval;
@@ -507,7 +532,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
     size_t labellen, hashlen = 0;
     int ret = 0;
     const EVP_MD *md = NULL, *mac_md = NULL;
-    const EVP_CIPHER *cipher = NULL;
+    const EVP_CIPHER *cipher = NULL, *sncipher = NULL;
     int mac_pkey_type = NID_undef;
     SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
     size_t keylen, ivlen = EVP_MAX_IV_LENGTH, taglen;
@@ -560,7 +585,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
              * This ups the ref count on cipher so we better make sure we free
              * it again
              */
-            if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)) {
+            if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)
+                || (SSL_CONNECTION_IS_DTLS(s)
+                    && !ssl_cipher_get_evp_cipher_sn(sctx, sslcipher, &sncipher,
+                                                     &sn_input_offs))) {
                 /* Error is already recorded */
                 SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
                 goto err;
@@ -668,6 +696,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
     if ((which & SSL3_CC_EARLY) == 0) {
         md = ssl_handshake_md(s);
         cipher = s->s3.tmp.new_sym_enc;
+        sncipher = s->s3.tmp.new_sym_enc_sn;
+        sn_input_offs = s->s3.tmp.new_sym_enc_sn_offs;
         mac_md = s->s3.tmp.new_hash;
         mac_pkey_type = s->s3.tmp.new_mac_pkey_type;
         if (!ssl3_digest_cached_records(s, 1)
@@ -707,8 +737,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
         goto err;
 
     if (!derive_secret_key_and_iv(s, md, cipher, mac_pkey_type, mac_md,
-                                  insecret, hash, label, labellen, secret, key,
-                                  &keylen, &iv, &ivlen, &taglen)) {
+                                  insecret, hash, label, labellen, secret,
+                                  snkey, key, &keylen, &iv, &ivlen, &taglen)) {
         /* SSLfatal() already called */
         goto err;
     }
@@ -777,10 +807,9 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
         }
     }
 
-    if (!ssl_set_new_record_layer(s, s->version,
-                                  direction,
-                                  level, secret, hashlen, key, keylen, iv,
-                                  ivlen, NULL, 0, cipher, taglen,
+    if (!ssl_set_new_record_layer(s, s->version, direction, level, secret,
+                                  hashlen, snkey, key, keylen, iv, ivlen,
+                                  NULL, 0, sncipher, sn_input_offs, cipher, taglen,
                                   mac_pkey_type, mac_md, NULL, md)) {
         /* SSLfatal already called */
         goto err;
@@ -793,8 +822,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
         if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
             ssl_evp_md_free(mac_md);
         ssl_evp_cipher_free(cipher);
+        ssl_evp_cipher_free(sncipher);
     }
     OPENSSL_cleanse(key, sizeof(key));
+    OPENSSL_cleanse(snkey, sizeof(snkey));
     OPENSSL_cleanse(secret, sizeof(secret));
     if (iv != iv_intern)
         OPENSSL_free(iv);
@@ -808,6 +839,7 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
     const EVP_MD *md = ssl_handshake_md(s);
     size_t hashlen;
     unsigned char key[EVP_MAX_KEY_LENGTH];
+    unsigned char snkey[EVP_MAX_KEY_LENGTH];
     unsigned char *insecret;
     unsigned char secret[EVP_MAX_MD_SIZE];
     char *log_label;
@@ -835,8 +867,8 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
                                   s->s3.tmp.new_mac_pkey_type, s->s3.tmp.new_hash,
                                   insecret, NULL,
                                   application_traffic,
-                                  sizeof(application_traffic) - 1, secret, key,
-                                  &keylen, &iv, &ivlen, &taglen)) {
+                                  sizeof(application_traffic) - 1, secret, snkey,
+                                  key, &keylen, &iv, &ivlen, &taglen)) {
         /* SSLfatal() already called */
         goto err;
     }
@@ -846,12 +878,13 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
     if (SSL_CONNECTION_IS_DTLS(s))
         dtls1_increment_epoch(s, which);
 
-    if (!ssl_set_new_record_layer(s, s->version,
-                            direction,
-                            OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
-                            insecret, hashlen, key, keylen, iv, ivlen, NULL, 0,
-                            s->s3.tmp.new_sym_enc, taglen, NID_undef, NULL,
-                            NULL, md)) {
+    if (!ssl_set_new_record_layer(s, s->version, direction,
+                                  OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
+                                  insecret, hashlen, snkey, key, keylen,
+                                  iv, ivlen, NULL, 0,
+                                  s->s3.tmp.new_sym_enc_sn, s->s3.tmp.new_sym_enc_sn_offs,
+                                  s->s3.tmp.new_sym_enc,
+                                  taglen, NID_undef, NULL, NULL, md)) {
         /* SSLfatal already called */
         goto err;
     }
@@ -865,6 +898,7 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
     ret = 1;
  err:
     OPENSSL_cleanse(key, sizeof(key));
+    OPENSSL_cleanse(snkey, sizeof(snkey));
     OPENSSL_cleanse(secret, sizeof(secret));
     if (iv != iv_intern)
         OPENSSL_free(iv);
index f1e6490f9f900b810bd19642d3e7e5cd2c191f48..9cc5b167b0090866b14225dfbebc7b8b8983d6ce 100644 (file)
@@ -336,7 +336,8 @@ static int test_tls13_encryption(void)
                           NULL, NULL, TLS1_3_VERSION, OSSL_RECORD_ROLE_SERVER,
                           OSSL_RECORD_DIRECTION_WRITE,
                           OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, 0, NULL, 0,
-                          key, 16, iv, ivlen, NULL, 0, EVP_aes_128_gcm(),
+                          NULL, key, 16, iv, ivlen, NULL, 0, NULL, 0,
+                          EVP_aes_128_gcm(),
                           EVP_GCM_TLS_TAG_LEN, 0, NULL, NULL, NULL, NULL, NULL,
                           NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                           &wrl)))
@@ -359,7 +360,8 @@ static int test_tls13_encryption(void)
                           NULL, NULL, TLS1_3_VERSION, OSSL_RECORD_ROLE_SERVER,
                           OSSL_RECORD_DIRECTION_READ,
                           OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, 0, NULL, 0,
-                          key, 16, iv, ivlen, NULL, 0, EVP_aes_128_gcm(),
+                          NULL, key, 16, iv, ivlen, NULL, 0, NULL, 0,
+                          EVP_aes_128_gcm(),
                           EVP_GCM_TLS_TAG_LEN, 0, NULL, NULL, NULL, NULL, NULL,
                           NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                           &rrl)))
index 79a81a9f4ac7d6be25d93e9fd10a31846fadd1ea..6cc8dae29bac241d591a31feff8bd4805255079b 100644 (file)
@@ -157,6 +157,11 @@ const EVP_MD *ssl_handshake_md(SSL_CONNECTION *s)
     return EVP_sha256();
 }
 
+int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc,
+                                 const EVP_CIPHER **enc, size_t *inputoffs) {
+    return 0;
+}
+
 int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc,
                                      const EVP_CIPHER **enc)
 {
@@ -171,7 +176,9 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc,
 }
 
 int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
-                       const EVP_CIPHER **enc, const EVP_MD **md,
+                       const EVP_CIPHER **snenc, size_t *snencoffs,
+                       const EVP_CIPHER **enc,
+                       const EVP_MD **md,
                        int *mac_pkey_type, size_t *mac_secret_size,
                        SSL_COMP **comp, int use_etm)
 
@@ -226,9 +233,11 @@ void ssl_evp_md_free(const EVP_MD *md)
 
 int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction,
                              int level, unsigned char *secret, size_t secretlen,
+                             unsigned char *snkey,
                              unsigned char *key, size_t keylen,
                              unsigned char *iv,  size_t ivlen,
                              unsigned char *mackey, size_t mackeylen,
+                             const EVP_CIPHER *snciph, size_t snoffs,
                              const EVP_CIPHER *ciph, size_t taglen,
                              int mactype, const EVP_MD *md,
                              const SSL_COMP *comp, const EVP_MD *kdfdigest)