Browse Source

[tls] Treat handshake digest algorithm as a session parameter

Simplify code by recording the active handshake digest algorithm as a
session parameter.  (Note that we must still accumulate digests for
all supported algorithms, since we don't know which digest will
eventually be used until we receive the Server Hello.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
7869f71ae7
2 changed files with 28 additions and 39 deletions
  1. 4
    0
      src/include/ipxe/tls.h
  2. 24
    39
      src/net/tls.c

+ 4
- 0
src/include/ipxe/tls.h View File

@@ -201,6 +201,10 @@ struct tls_session {
201 201
 	uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE];
202 202
 	/** SHA256 context for handshake verification */
203 203
 	uint8_t handshake_sha256_ctx[SHA256_CTX_SIZE];
204
+	/** Digest algorithm used for handshake verification */
205
+	struct digest_algorithm *handshake_digest;
206
+	/** Digest algorithm context used for handshake verification */
207
+	uint8_t *handshake_ctx;
204 208
 
205 209
 	/** TX sequence number */
206 210
 	uint64_t tx_seq;

+ 24
- 39
src/net/tls.c View File

@@ -697,22 +697,6 @@ static void tls_add_handshake ( struct tls_session *tls,
697 697
 			data, len );
698 698
 }
699 699
 
700
-/**
701
- * Size of handshake output buffer
702
- *
703
- * @v tls		TLS session
704
- */
705
-static size_t tls_verify_handshake_len ( struct tls_session *tls ) {
706
-
707
-	if ( tls->version >= TLS_VERSION_TLS_1_2 ) {
708
-		/* Use SHA-256 for TLSv1.2 and later */
709
-		return SHA256_DIGEST_SIZE;
710
-	} else {
711
-		/* Use MD5+SHA1 for TLSv1.1 and earlier */
712
-		return MD5_SHA1_DIGEST_SIZE;
713
-	}
714
-}
715
-
716 700
 /**
717 701
  * Calculate handshake verification hash
718 702
  *
@@ -723,22 +707,11 @@ static size_t tls_verify_handshake_len ( struct tls_session *tls ) {
723 707
  * messages seen so far.
724 708
  */
725 709
 static void tls_verify_handshake ( struct tls_session *tls, void *out ) {
726
-	union {
727
-		uint8_t md5_sha1[MD5_SHA1_CTX_SIZE];
728
-		uint8_t sha256[SHA256_CTX_SIZE];
729
-	} ctx;
710
+	struct digest_algorithm *digest = tls->handshake_digest;
711
+	uint8_t ctx[ digest->ctxsize ];
730 712
 
731
-	if ( tls->version >= TLS_VERSION_TLS_1_2 ) {
732
-		/* Use SHA-256 for TLSv1.2 and later */
733
-		memcpy ( ctx.sha256, tls->handshake_sha256_ctx,
734
-			 sizeof ( ctx.sha256 ) );
735
-		digest_final ( &sha256_algorithm, ctx.sha256, out );
736
-	} else {
737
-		/* Use MD5+SHA1 for TLSv1.1 and earlier */
738
-		memcpy ( ctx.md5_sha1, tls->handshake_md5_sha1_ctx,
739
-			 sizeof ( ctx.md5_sha1 ) );
740
-		digest_final ( &md5_sha1_algorithm, ctx.md5_sha1, out );
741
-	}
713
+	memcpy ( ctx, tls->handshake_ctx, sizeof ( ctx ) );
714
+	digest_final ( digest, ctx, out );
742 715
 }
743 716
 
744 717
 /******************************************************************************
@@ -915,20 +888,21 @@ static int tls_send_change_cipher ( struct tls_session *tls ) {
915 888
  * @ret rc		Return status code
916 889
  */
917 890
 static int tls_send_finished ( struct tls_session *tls ) {
891
+	struct digest_algorithm *digest = tls->handshake_digest;
918 892
 	struct {
919 893
 		uint32_t type_length;
920 894
 		uint8_t verify_data[12];
921 895
 	} __attribute__ (( packed )) finished;
922
-	uint8_t digest[ tls_verify_handshake_len ( tls ) ];
896
+	uint8_t digest_out[ digest->digestsize ];
923 897
 
924 898
 	memset ( &finished, 0, sizeof ( finished ) );
925 899
 	finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
926 900
 				 htonl ( sizeof ( finished ) -
927 901
 					 sizeof ( finished.type_length ) ) );
928
-	tls_verify_handshake ( tls, digest );
902
+	tls_verify_handshake ( tls, digest_out );
929 903
 	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
930 904
 			finished.verify_data, sizeof ( finished.verify_data ),
931
-			"client finished", digest, sizeof ( digest ) );
905
+			"client finished", digest_out, sizeof ( digest_out ) );
932 906
 
933 907
 	return tls_send_handshake ( tls, &finished, sizeof ( finished ) );
934 908
 }
@@ -1052,6 +1026,14 @@ static int tls_new_server_hello ( struct tls_session *tls,
1052 1026
 	DBGC ( tls, "TLS %p using protocol version %d.%d\n",
1053 1027
 	       tls, ( version >> 8 ), ( version & 0xff ) );
1054 1028
 
1029
+	/* Use MD5+SHA1 digest algorithm for handshake verification
1030
+	 * for versions earlier than TLSv1.2.
1031
+	 */
1032
+	if ( tls->version < TLS_VERSION_TLS_1_2 ) {
1033
+		tls->handshake_digest = &md5_sha1_algorithm;
1034
+		tls->handshake_ctx = tls->handshake_md5_sha1_ctx;
1035
+	}
1036
+
1055 1037
 	/* Copy out server random bytes */
1056 1038
 	memcpy ( &tls->server_random, &hello_a->random,
1057 1039
 		 sizeof ( tls->server_random ) );
@@ -1254,12 +1236,13 @@ static int tls_new_server_hello_done ( struct tls_session *tls,
1254 1236
  */
1255 1237
 static int tls_new_finished ( struct tls_session *tls,
1256 1238
 			      const void *data, size_t len ) {
1239
+	struct digest_algorithm *digest = tls->handshake_digest;
1257 1240
 	const struct {
1258 1241
 		uint8_t verify_data[12];
1259 1242
 		char next[0];
1260 1243
 	} __attribute__ (( packed )) *finished = data;
1261 1244
 	const void *end = finished->next;
1262
-	uint8_t digest[ tls_verify_handshake_len ( tls ) ];
1245
+	uint8_t digest_out[ digest->digestsize ];
1263 1246
 	uint8_t verify_data[ sizeof ( finished->verify_data ) ];
1264 1247
 
1265 1248
 	/* Sanity check */
@@ -1270,10 +1253,10 @@ static int tls_new_finished ( struct tls_session *tls,
1270 1253
 	}
1271 1254
 
1272 1255
 	/* Verify data */
1273
-	tls_verify_handshake ( tls, digest );
1256
+	tls_verify_handshake ( tls, digest_out );
1274 1257
 	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
1275 1258
 			verify_data, sizeof ( verify_data ), "server finished",
1276
-			digest, sizeof ( digest ) );
1259
+			digest_out, sizeof ( digest_out ) );
1277 1260
 	if ( memcmp ( verify_data, finished->verify_data,
1278 1261
 		      sizeof ( verify_data ) ) != 0 ) {
1279 1262
 		DBGC ( tls, "TLS %p verification failed\n", tls );
@@ -2014,8 +1997,8 @@ static void tls_tx_step ( struct tls_session *tls ) {
2014 1997
 	} else if ( tls->tx_pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
2015 1998
 		/* Send Client Key Exchange */
2016 1999
 		if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
2017
-			DBGC ( tls, "TLS %p could send Client Key Exchange: "
2018
-			       "%s\n", tls, strerror ( rc ) );
2000
+			DBGC ( tls, "TLS %p could not send Client Key "
2001
+			       "Exchange: %s\n", tls, strerror ( rc ) );
2019 2002
 			goto err;
2020 2003
 		}
2021 2004
 		tls->tx_pending &= ~TLS_TX_CLIENT_KEY_EXCHANGE;
@@ -2099,6 +2082,8 @@ int add_tls ( struct interface *xfer, const char *name,
2099 2082
 	}
2100 2083
 	digest_init ( &md5_sha1_algorithm, tls->handshake_md5_sha1_ctx );
2101 2084
 	digest_init ( &sha256_algorithm, tls->handshake_sha256_ctx );
2085
+	tls->handshake_digest = &sha256_algorithm;
2086
+	tls->handshake_ctx = tls->handshake_sha256_ctx;
2102 2087
 	tls->tx_pending = TLS_TX_CLIENT_HELLO;
2103 2088
 	process_init ( &tls->process, &tls_process_desc, &tls->refcnt );
2104 2089
 

Loading…
Cancel
Save