Elliptic curve + post-quantum key exchange

CECPQ1 is a new key exchange that concatenates the results of an X25519
key agreement and a NEWHOPE key agreement.

Change-Id: Ib919bdc2e1f30f28bf80c4c18f6558017ea386bb
Reviewed-on: https://boringssl-review.googlesource.com/7962
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 88a30e3..39aea3c 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -1142,8 +1142,7 @@
     CBS point;
     if (!CBS_get_u8(&server_key_exchange, &curve_type) ||
         curve_type != NAMED_CURVE_TYPE ||
-        !CBS_get_u16(&server_key_exchange, &curve_id) ||
-        !CBS_get_u8_length_prefixed(&server_key_exchange, &point)) {
+        !CBS_get_u16(&server_key_exchange, &curve_id)) {
       al = SSL_AD_DECODE_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
       goto f_err;
@@ -1157,13 +1156,22 @@
       goto f_err;
     }
 
-    /* Initialize ECDH and save the peer public key for later. */
-    size_t peer_key_len;
-    if (!SSL_ECDH_CTX_init(&ssl->s3->tmp.ecdh_ctx, curve_id) ||
-        !CBS_stow(&point, &ssl->s3->tmp.peer_key, &peer_key_len)) {
+    if (!SSL_ECDH_CTX_init(&ssl->s3->tmp.ecdh_ctx, curve_id)) {
       goto err;
     }
-    /* |point| has a u8 length prefix, so this fits in a |uint16_t|. */
+    if (!SSL_ECDH_CTX_get_key(&ssl->s3->tmp.ecdh_ctx, &server_key_exchange,
+                              &point)) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+      goto f_err;
+    }
+
+    /* Initialize ECDH and save the peer public key for later. */
+    size_t peer_key_len;
+    if (!CBS_stow(&point, &ssl->s3->tmp.peer_key, &peer_key_len)) {
+      goto err;
+    }
+    /* |point| has a u8 or u16 length prefix, so this fits in a |uint16_t|. */
     assert(sizeof(ssl->s3->tmp.peer_key_len) == 2 && peer_key_len <= 0xffff);
     ssl->s3->tmp.peer_key_len = (uint16_t)peer_key_len;
   } else if (!(alg_k & SSL_kPSK)) {
@@ -1616,17 +1624,9 @@
       goto err;
     }
   } else if (alg_k & (SSL_kECDHE|SSL_kDHE)) {
-    /* Generate a keypair and serialize the public half. ECDHE uses a u8 length
-     * prefix while DHE uses u16. */
+    /* Generate a keypair and serialize the public half. */
     CBB child;
-    int child_ok;
-    if (alg_k & SSL_kECDHE) {
-      child_ok = CBB_add_u8_length_prefixed(&cbb, &child);
-    } else {
-      child_ok = CBB_add_u16_length_prefixed(&cbb, &child);
-    }
-
-    if (!child_ok) {
+    if (!SSL_ECDH_CTX_add_key(&ssl->s3->tmp.ecdh_ctx, &cbb, &child)) {
       goto err;
     }