+
+/*
+ * Saves the current handshake digest for Post-Handshake Auth,
+ * Done after ClientFinished is processed, done exactly once
+ */
+int tls13_save_handshake_digest_for_pha(SSL *s)
+{
+ if (s->pha_dgst == NULL) {
+ if (!ssl3_digest_cached_records(s, 1))
+ /* SSLfatal() already called */
+ return 0;
+
+ s->pha_dgst = EVP_MD_CTX_new();
+ if (s->pha_dgst == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ if (!EVP_MD_CTX_copy_ex(s->pha_dgst,
+ s->s3->handshake_dgst)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Restores the Post-Handshake Auth handshake digest
+ * Done just before sending/processing the Cert Request
+ */
+int tls13_restore_handshake_digest_for_pha(SSL *s)
+{
+ if (s->pha_dgst == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ if (!EVP_MD_CTX_copy_ex(s->s3->handshake_dgst,
+ s->pha_dgst)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ return 1;
+}