- /* Generate the early_secret */
- if (!tls13_generate_secret(s, md, NULL, sess->master_key,
- sess->master_key_length,
- (unsigned char *)&s->early_secret)) {
+ if (external
+ && s->early_data_state == SSL_EARLY_DATA_CONNECTING
+ && s->session->ext.max_early_data == 0
+ && sess->ext.max_early_data > 0)
+ usepskfored = 1;
+
+ if (external) {
+ label = external_label;
+ labelsize = sizeof(external_label) - 1;
+ } else {
+ label = resumption_label;
+ labelsize = sizeof(resumption_label) - 1;
+ }
+
+ if (sess->master_key_length != hashsize) {
+ SSLerr(SSL_F_TLS_PSK_DO_BINDER, SSL_R_BAD_PSK);
+ goto err;
+ }
+
+ if (external) {
+ psk = sess->master_key;
+ } else {
+ psk = tmppsk;
+ if (!tls13_hkdf_expand(s, md, sess->master_key,
+ (const unsigned char *)nonce_label,
+ sizeof(nonce_label) - 1, sess->ext.tick_nonce,
+ sess->ext.tick_nonce_len, psk, hashsize)) {
+ SSLerr(SSL_F_TLS_PSK_DO_BINDER, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ /*
+ * Generate the early_secret. On the server side we've selected a PSK to
+ * resume with (internal or external) so we always do this. On the client
+ * side we do this for a non-external (i.e. resumption) PSK or external PSK
+ * that will be used for early_data so that it is in place for sending early
+ * data. For client side external PSK not being used for early_data we
+ * generate it but store it away for later use.
+ */
+ if (s->server || !external || usepskfored)
+ early_secret = (unsigned char *)s->early_secret;
+ else
+ early_secret = (unsigned char *)sess->early_secret;
+ if (!tls13_generate_secret(s, md, NULL, psk, hashsize, early_secret)) {