[tls] Guard against a premature server Finished A malicious server that immediately sends a Finished record (without ever having sent a ServerHello) will currently cause tls_prf() to get stuck in an infinite loop attempting to generate pseudorandom data using the null digest algorithm. Fix by checking that the key schedule digest size is non-zero (i.e. that the digest is not the null digest) before attempting to process the Finished record. Signed-off-by: Michael Brown <mcb30@ipxe.org>
diff --git a/src/net/tls.c b/src/net/tls.c index a53f8c8..c5cf92f 100644 --- a/src/net/tls.c +++ b/src/net/tls.c
@@ -2888,10 +2888,15 @@ } __attribute__ (( packed )) *finished = data; uint8_t digest_out[ digest->digestsize ]; - /* Sanity check */ + /* Sanity checks */ + if ( ! digest->digestsize ) { + DBGC ( tls, "TLS %p received premature Finished\n", tls ); + DBGC_HDA ( tls, 0, data, len ); + return -EINVAL_FINISHED; + } if ( sizeof ( *finished ) != len ) { DBGC ( tls, "TLS %p received overlength Finished\n", tls ); - DBGC_HD ( tls, data, len ); + DBGC_HDA ( tls, 0, data, len ); return -EINVAL_FINISHED; }