Prefer SHA-256 ciphersuites if using old style PSKs

If we have no certificate and we are using "old style" PSKs then we will
always default to using SHA-256 for that PSK. However we may have selected
a ciphersuite that is not based on SHA-256. Therefore if we see that there
are no certificates and we have been configured for "old style" PSKs then
we should prefer SHA-256 based ciphersuites during the selection process.

Fixes #6197

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6215)
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index f797497..c5f2235 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -4108,8 +4108,9 @@
 {
     const SSL_CIPHER *c, *ret = NULL;
     STACK_OF(SSL_CIPHER) *prio, *allow;
-    int i, ii, ok;
+    int i, ii, ok, prefer_sha256 = 0;
     unsigned long alg_k = 0, alg_a = 0, mask_k = 0, mask_a = 0;
+    const EVP_MD *mdsha256 = EVP_sha256();
 #ifndef OPENSSL_NO_CHACHA
     STACK_OF(SSL_CIPHER) *prio_chacha = NULL;
 #endif
@@ -4190,7 +4191,24 @@
         allow = srvr;
     }
 
-    if (!SSL_IS_TLS13(s)) {
+    if (SSL_IS_TLS13(s)) {
+        int j;
+
+        /*
+         * If we allow "old" style PSK callbacks, and we have no certificate (so
+         * we're not going to succeed without a PSK anyway), and we're in
+         * TLSv1.3 then the default hash for a PSK is SHA-256 (as per the
+         * TLSv1.3 spec). Therefore we should prioritise ciphersuites using
+         * that.
+         */
+        if (s->psk_server_callback != NULL) {
+            for (j = 0; j < SSL_PKEY_NUM && !ssl_has_cert(s, j); j++);
+            if (j == SSL_PKEY_NUM) {
+                /* There are no certificates */
+                prefer_sha256 = 1;
+            }
+        }
+    } else {
         tls1_set_cert_validity(s);
         ssl_set_masks(s);
     }
@@ -4262,6 +4280,17 @@
                 continue;
             }
 #endif
+            if (prefer_sha256) {
+                const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii);
+
+                if (ssl_md(tmp->algorithm2) == mdsha256) {
+                    ret = tmp;
+                    break;
+                }
+                if (ret == NULL)
+                    ret = tmp;
+                continue;
+            }
             ret = sk_SSL_CIPHER_value(allow, ii);
             break;
         }