+#ifndef OPENSSL_NO_TLS1_3
+static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id)
+{
+ unsigned char *encoded_point;
+ EVP_PKEY *key_share_key;
+ size_t encodedlen;
+
+ key_share_key = ssl_generate_pkey_curve(curve_id);
+ if (key_share_key == NULL) {
+ SSLerr(SSL_F_ADD_KEY_SHARE, ERR_R_EVP_LIB);
+ return 0;
+ }
+
+ /* Encode the public key. */
+ encodedlen = EVP_PKEY_get1_tls_encodedpoint(key_share_key,
+ &encoded_point);
+ if (encodedlen == 0) {
+ SSLerr(SSL_F_ADD_KEY_SHARE, ERR_R_EC_LIB);
+ EVP_PKEY_free(key_share_key);
+ return 0;
+ }
+
+ /* Create KeyShareEntry */
+ if (!WPACKET_put_bytes_u16(pkt, curve_id)
+ || !WPACKET_sub_memcpy_u16(pkt, encoded_point, encodedlen)) {
+ SSLerr(SSL_F_ADD_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+ EVP_PKEY_free(key_share_key);
+ OPENSSL_free(encoded_point);
+ return 0;
+ }
+
+ /*
+ * TODO(TLS1.3): When changing to send more than one key_share we're
+ * going to need to be able to save more than one EVP_PKEY. For now
+ * we reuse the existing tmp.pkey
+ */
+ s->s3->tmp.pkey = key_share_key;
+ s->s3->group_id = curve_id;
+ OPENSSL_free(encoded_point);
+
+ return 1;
+}
+#endif
+
+int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context,
+ X509 *x, size_t chainidx, int *al)