Subject: [Lurk] lurk integration with openssl

From: Daniel Migault <[email-masked]>
Date: Fri, 20 Apr 2018 14:26:27 -0400

Hi Jesus Alberto,

There have been some discussions regarding the integration of lurk with
openssl during the hackathon, so feel free to share your concerns on the
mailing list.

Here are some links you might find of interest:

https://www.agwa.name/blog/post/protecting_the_openssl_private_key_in_a_separate_process
https://www.agwa.name/blog/post/titus_isolation_techniques_continued

Yours,
Daniel

---

From: Dmitry Kravkov <[email-masked]>
Date: Sun, 22 Apr 2018 10:08:42 +0000

Hi Jesus Alberto,

this is a patch for openssl used during 101 hackathon

It looks that direct calling for lurk library from statemachine will be
hard to push upstream, but adding more callbacks for master secret
calculation that nginx (or other client) registers for,  will be easier to
submit.

On Fri, Apr 20, 2018 at 9:26 PM Daniel Migault <[email-masked]>
wrote:

> mailing list..
> _______________________________________________
> Lurk mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/lurk
>
-- 

*Dmitry Kravkov*
Qwilt | Work: +972-72-2221630 | Mobile: +972-54-4839923

dmitrykATqwilt.com
diff -Naur openssl.orig/Configurations/unix-Makefile.tmpl openssl/Configurations/unix-Makefile.tmpl
--- openssl.orig/Configurations/unix-Makefile.tmpl	2018-03-18 11:10:36.243303435 +0200
+++ openssl/Configurations/unix-Makefile.tmpl	2018-03-18 11:10:36.006303654 +0200
@@ -195,7 +195,8 @@
 CXXFLAGS={- join(' ', @{$config{cxxflags}}) -}
 LDFLAGS= {- join(' ', @{$config{lflags}}) -}
 PLIB_LDFLAGS= {- join(' ', @{$config{plib_lflags}}) -}
-EX_LIBS= {- join(' ', @{$config{ex_libs}}) -}
+#EX_LIBS= {- join(' ', @{$config{ex_libs}}) -}
+EX_LIBS=-ldl -pthread -L/root/pylurk/test/ -lclurk -lpython36m
 LIB_CPPFLAGS={- join(' ',
                      (map { '-D'.$_ }
                           ('OPENSSLDIR="\"$(OPENSSLDIR)\""',
diff -Naur openssl.orig/include/openssl/ssl.h openssl/include/openssl/ssl.h
--- openssl.orig/include/openssl/ssl.h	2018-03-18 11:10:38.765301106 +0200
+++ openssl/include/openssl/ssl.h	2018-03-18 11:10:36.034303628 +0200
@@ -361,6 +361,9 @@
  */
 # define SSL_OP_TLS_ROLLBACK_BUG                         0x00800000U
 
+/* Disable Extended master secret */
+# define SSL_OP_NO_EXTENDED_MASTER_SECRET                0x01000000U
+
 # define SSL_OP_NO_SSLv3                                 0x02000000U
 # define SSL_OP_NO_TLSv1                                 0x04000000U
 # define SSL_OP_NO_TLSv1_2                               0x08000000U
diff -Naur openssl.orig/ssl/ssl_lib.c openssl/ssl/ssl_lib.c
--- openssl.orig/ssl/ssl_lib.c	2018-03-18 11:10:38.778301094 +0200
+++ openssl/ssl/ssl_lib.c	2018-03-18 11:10:35.934303721 +0200
@@ -2867,6 +2867,7 @@
     if (ret == NULL)
         goto err;
 
+    ret->mode |= (SSL_MODE_SEND_SERVERHELLO_TIME | SSL_MODE_SEND_CLIENTHELLO_TIME);
     ret->method = meth;
     ret->min_proto_version = 0;
     ret->max_proto_version = 0;
diff -Naur openssl.orig/ssl/ssl_locl.h openssl/ssl/ssl_locl.h
--- openssl.orig/ssl/ssl_locl.h	2018-03-18 11:10:38.778301094 +0200
+++ openssl/ssl/ssl_locl.h	2018-03-18 14:08:19.495455792 +0200
@@ -1087,6 +1087,8 @@
      * be 'copied' into these ones
      */
     uint32_t mac_flags;
+    unsigned char *enc_premaster_secret;
+    size_t enc_premaster_secret_len;
     /*
      * The TLS1.3 secrets. The resumption master secret is stored in the
      * session.
diff -Naur openssl.orig/ssl/statem/extensions.c openssl/ssl/statem/extensions.c
--- openssl.orig/ssl/statem/extensions.c	2018-03-18 11:10:38.780301092 +0200
+++ openssl/ssl/statem/extensions.c	2018-03-18 11:10:35.966303691 +0200
@@ -1127,8 +1127,7 @@
 
 static int init_ems(SSL *s, unsigned int context)
 {
-    if (!s->server)
-        s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
+    s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
 
     return 1;
 }
diff -Naur openssl.orig/ssl/statem/extensions_clnt.c openssl/ssl/statem/extensions_clnt.c
--- openssl.orig/ssl/statem/extensions_clnt.c	2018-03-18 11:10:38.780301092 +0200
+++ openssl/ssl/statem/extensions_clnt.c	2018-03-18 11:10:35.967303690 +0200
@@ -491,6 +491,9 @@
 EXT_RETURN tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context,
                                   X509 *x, size_t chainidx)
 {
+    //if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET)
+        return EXT_RETURN_NOT_SENT;
+
     if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
             || !WPACKET_put_bytes_u16(pkt, 0)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_EMS,
@@ -1633,6 +1636,8 @@
 int tls_parse_stoc_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                        size_t chainidx)
 {
+    //if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET)
+        return 1;
     s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
     if (!s->hit)
         s->session->flags |= SSL_SESS_FLAG_EXTMS;
diff -Naur openssl.orig/ssl/statem/extensions_srvr.c openssl/ssl/statem/extensions_srvr.c
--- openssl.orig/ssl/statem/extensions_srvr.c	2018-03-18 11:10:38.781301091 +0200
+++ openssl/ssl/statem/extensions_srvr.c	2018-03-18 11:10:35.967303690 +0200
@@ -978,6 +978,9 @@
         return 0;
     }
 
+    //if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET)
+        return 1;
+
     s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
 
     return 1;
diff -Naur openssl.orig/ssl/statem/statem_srvr.c openssl/ssl/statem/statem_srvr.c
--- openssl.orig/ssl/statem/statem_srvr.c	2018-03-18 11:10:38.783301089 +0200
+++ openssl/ssl/statem/statem_srvr.c	2018-03-18 11:10:35.957303699 +0200
@@ -2884,6 +2884,14 @@
         goto err;
     }
 
+    s->enc_premaster_secret = OPENSSL_malloc(PACKET_remaining(&enc_premaster));
+    if (s->enc_premaster_secret == NULL) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_RSA,
+                 ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    s->enc_premaster_secret_len = PACKET_remaining(&enc_premaster);
+    memcpy(s->enc_premaster_secret, PACKET_data(&enc_premaster), s->enc_premaster_secret_len);
     /*
      * Decrypt with no padding. PKCS#1 padding will be removed as part of
      * the timing-sensitive code below.
diff -Naur openssl.orig/ssl/t1_enc.c openssl/ssl/t1_enc.c
--- openssl.orig/ssl/t1_enc.c	2018-03-18 11:10:38.786301086 +0200
+++ openssl/ssl/t1_enc.c	2018-03-18 14:04:07.451231125 +0200
@@ -469,6 +469,9 @@
     return TLS1_FINISH_MAC_LENGTH;
 }
 
+extern int lurk_client(unsigned char* c, size_t cLen, unsigned char* s, size_t sLen, unsigned char* pms, size_t pmsLen, unsigned char* res, size_t space, size_t * len);
+
+
 int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
                                 size_t len, size_t *secret_size)
 {
@@ -502,6 +505,21 @@
         }
         OPENSSL_cleanse(hash, hashlen);
     } else {
+
+#ifndef HAS_LURK_SUPPORT
+#define HAS_LURK_SUPPORT 1
+#endif
+#if HAS_LURK_SUPPORT
+        size_t lurk_master_size;
+
+        lurk_client(s->s3->client_random, SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE, s->enc_premaster_secret, s->enc_premaster_secret_len, out, SSL3_MASTER_SECRET_SIZE, &lurk_master_size);
+        // TODO Check ret value
+        
+	fprintf(stderr, "Lurk Master Secret put into master\n");
+        OPENSSL_free(s->enc_premaster_secret);
+        s->enc_premaster_secret = NULL;
+        s->enc_premaster_secret_len = 0;
+#else
         if (!tls1_PRF(s,
                       TLS_MD_MASTER_SECRET_CONST,
                       TLS_MD_MASTER_SECRET_CONST_SIZE,
@@ -513,6 +531,7 @@
            /* SSLfatal() already called */
             return 0;
         }
+#endif
     }
 #ifdef SSL_DEBUG
     fprintf(stderr, "Premaster Secret:\n");

---

From: Jesús Alberto Polo <[email-masked]>
Date: Tue, 24 Apr 2018 17:10:31 +0200

Hi,

Thanks for the resources and the patch, it’s definitely easier to solve it the way you did in the hackathon.

I managed to integrate the basic functionality of LURK for ECDHE and I’m preparing some tests, I hope they’re done and the code cleaned up by the end of this week.

Regarding the TLS12ECDHERequestPayload [1], I think the Signature Algorithm field is missing (hash and signature), to indicate the chosen algorithms for the TLS connection.

Best regards,

Jesús Alberto

[1] https://tools.ietf.org/html/draft-mglt-lurk-tls12-00#section-7.1

On 22 Apr 2018, 12:08 +0200, Dmitry Kravkov <[email-masked]>, wrote:
> It looks that direct calling for lurk library from statemachine will be hard to push upstream, but adding more callbacks for master secret calculation that nginx (or other client) registers for,  will be easier to submit.
>
>
> > On Fri, Apr 20, 2018 at 9:26 PM Daniel Migault <[email-masked]> wrote:
> > > Hi Jesus Alberto,
> > >
> > > There have been some discussions regarding the integration of lurk with openssl during the hackathon, so feel free to share your concerns on the mailing list..
> > >
> Dmitry Kravkov

---

From: Daniel Migault <[email-masked]>
Date: Tue, 24 Apr 2018 15:34:15 +0000

Thanks for the feed back! Yes absolutely for ecdhe, the sig_and_hash is missing from the spec. I have also slightly changed the extended master structure by exchanging the session_hash and encrypted premaster. I expect to be able to update the draft by next week as well. On my python implementation I am using the following structures for ecdhe.

Yours,
Daniel

TLS12ECDHERequestPayload = Struct(
    Embedded(TLS12Base),
    "sig_and_hash" / SignatureAndHashAlgorithm,
    "ecdhe_params" / ServerECDHParams,
    "poo_params" / Struct(
        "poo_prf" / Default( POOPRF, "null" ),
        "rG" / IfThenElse( this.poo_prf == 'null',
             Pass,
             Switch( this.ecdhe_params.curve_param.curve,
                {
                "secp256r1" : UncompressedPointRepresentation_256,
                "secp384r1" : UncompressedPointRepresentation_384,
                "secp512r1" : UncompressedPointRepresentation_512

               }) ),
        "tG" / IfThenElse( this.poo_prf == 'null',
              Pass,
              Switch( this.ecdhe_params.curve_param.curve,
                  {
                  "secp256r1" : UncompressedPointRepresentation_256,
                  "secp384r1" : UncompressedPointRepresentation_384,
                  "secp512r1" : UncompressedPointRepresentation_512

               }) ),
    )
)

With

TLS12Base = Struct(
    "key_id" / KeyPairID ,
    "client_random" / Random,
    "server_random" / Random,
    "tls_version" /  ProtocolVersion,
    "prf" / PRFAlgorithm
)

I have also changed the structure of the extended master by interverting the session hash and the encrypted master to ease the parsing.

struct{
    KeyPairID key_id
    ProtocolVersion tls_version   // see RFC5246 section 6.2.1
    PRFAlgorithm prf              // see RFC5246 section 6.1
    opaque session_hash<2...2^16-2>
    EncryptedPreMasterSecret  pre_master
                                  // see RFC5246 section 7.4.7.1
}TLS12ExtendedMasterRSARequestPayload;
        ]]></artwork>

From: Jesús Alberto Polo [mailto:[email-masked]]
Sent: Tuesday, April 24, 2018 11:11 AM
To: Dmitry Kravkov <[email-masked]>; Daniel Migault <[email-masked]>
Cc: LURK BoF <[email-masked]>
Subject: Re: [Lurk] lurk integration with openssl

Hi,

Best regards,

Jesús Alberto

[1] https://tools.ietf.org/html/draft-mglt-lurk-tls12-00#section-7.1<https://tools.ietf.org/html/draft-mglt-lurk-tls12-00%23section-7.1>

On 22 Apr 2018, 12:08 +0200, Dmitry Kravkov <[email-masked]<mailto:[email-masked]>>, wrote:

Hi Jesus Alberto,

On Fri, Apr 20, 2018 at 9:26 PM Daniel Migault <[email-masked]<mailto:[email-masked]>> wrote:
Hi Jesus Alberto,
There have been some discussions regarding the integration of lurk with openssl during the hackathon, so feel free to share your concerns on the mailing list..
Here are some links you might find of interest:

_______________________________________________
Lurk mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/lurk
--

Dmitry Kravkov

dmitrykATqwilt.com