Browse Source

[tls] Use hybrid MD5+SHA1 algorithm

TLSv1.1 and earlier use a hybrid of MD5 and SHA-1 to generate digests
over the handshake messages.  Formalise this as a separate digest
algorithm "md5+sha1".

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
a156c15746
2 changed files with 90 additions and 17 deletions
  1. 24
    4
      src/include/ipxe/tls.h
  2. 66
    13
      src/net/tls.c

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

145
 	uint8_t random[28];
145
 	uint8_t random[28];
146
 } __attribute__ (( packed ));
146
 } __attribute__ (( packed ));
147
 
147
 
148
+/** An MD5+SHA1 context */
149
+struct md5_sha1_context {
150
+	/** MD5 context */
151
+	uint8_t md5[MD5_CTX_SIZE];
152
+	/** SHA-1 context */
153
+	uint8_t sha1[SHA1_CTX_SIZE];
154
+} __attribute__ (( packed ));
155
+
156
+/** MD5+SHA1 context size */
157
+#define MD5_SHA1_CTX_SIZE sizeof ( struct md5_sha1_context )
158
+
159
+/** An MD5+SHA1 digest */
160
+struct md5_sha1_digest {
161
+	/** MD5 digest */
162
+	uint8_t md5[MD5_DIGEST_SIZE];
163
+	/** SHA-1 digest */
164
+	uint8_t sha1[SHA1_DIGEST_SIZE];
165
+} __attribute__ (( packed ));
166
+
167
+/** MD5+SHA1 digest size */
168
+#define MD5_SHA1_DIGEST_SIZE sizeof ( struct md5_sha1_digest )
169
+
148
 /** A TLS session */
170
 /** A TLS session */
149
 struct tls_session {
171
 struct tls_session {
150
 	/** Reference counter */
172
 	/** Reference counter */
175
 	uint8_t server_random[32];
197
 	uint8_t server_random[32];
176
 	/** Client random bytes */
198
 	/** Client random bytes */
177
 	struct tls_client_random client_random;
199
 	struct tls_client_random client_random;
178
-	/** MD5 context for handshake verification */
179
-	uint8_t handshake_md5_ctx[MD5_CTX_SIZE];
180
-	/** SHA1 context for handshake verification */
181
-	uint8_t handshake_sha1_ctx[SHA1_CTX_SIZE];
200
+	/** MD5+SHA1 context for handshake verification */
201
+	uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE];
182
 	/** SHA256 context for handshake verification */
202
 	/** SHA256 context for handshake verification */
183
 	uint8_t handshake_sha256_ctx[SHA256_CTX_SIZE];
203
 	uint8_t handshake_sha256_ctx[SHA256_CTX_SIZE];
184
 
204
 

+ 66
- 13
src/net/tls.c View File

79
 	return ( ( field24[0] << 16 ) + ( field24[1] << 8 ) + field24[2] );
79
 	return ( ( field24[0] << 16 ) + ( field24[1] << 8 ) + field24[2] );
80
 }
80
 }
81
 
81
 
82
+/******************************************************************************
83
+ *
84
+ * Hybrid MD5+SHA1 hash as used by TLSv1.1 and earlier
85
+ *
86
+ ******************************************************************************
87
+ */
88
+
89
+/**
90
+ * Initialise MD5+SHA1 algorithm
91
+ *
92
+ * @v ctx		MD5+SHA1 context
93
+ */
94
+static void md5_sha1_init ( void *ctx ) {
95
+	struct md5_sha1_context *context = ctx;
96
+
97
+	digest_init ( &md5_algorithm, context->md5 );
98
+	digest_init ( &sha1_algorithm, context->sha1 );
99
+}
100
+
101
+/**
102
+ * Accumulate data with MD5+SHA1 algorithm
103
+ *
104
+ * @v ctx		MD5+SHA1 context
105
+ * @v data		Data
106
+ * @v len		Length of data
107
+ */
108
+static void md5_sha1_update ( void *ctx, const void *data, size_t len ) {
109
+	struct md5_sha1_context *context = ctx;
110
+
111
+	digest_update ( &md5_algorithm, context->md5, data, len );
112
+	digest_update ( &sha1_algorithm, context->sha1, data, len );
113
+}
114
+
115
+/**
116
+ * Generate MD5+SHA1 digest
117
+ *
118
+ * @v ctx		MD5+SHA1 context
119
+ * @v out		Output buffer
120
+ */
121
+static void md5_sha1_final ( void *ctx, void *out ) {
122
+	struct md5_sha1_context *context = ctx;
123
+	struct md5_sha1_digest *digest = out;
124
+
125
+	digest_final ( &md5_algorithm, context->md5, digest->md5 );
126
+	digest_final ( &sha1_algorithm, context->sha1, digest->sha1 );
127
+}
128
+
129
+/** Hybrid MD5+SHA1 digest algorithm */
130
+static struct digest_algorithm md5_sha1_algorithm = {
131
+	.name		= "md5+sha1",
132
+	.ctxsize	= sizeof ( struct md5_sha1_context ),
133
+	.blocksize	= 0, /* Not applicable */
134
+	.digestsize	= sizeof ( struct md5_sha1_digest ),
135
+	.init		= md5_sha1_init,
136
+	.update		= md5_sha1_update,
137
+	.final		= md5_sha1_final,
138
+};
139
+
82
 /******************************************************************************
140
 /******************************************************************************
83
  *
141
  *
84
  * Cleanup functions
142
  * Cleanup functions
633
 static void tls_add_handshake ( struct tls_session *tls,
691
 static void tls_add_handshake ( struct tls_session *tls,
634
 				const void *data, size_t len ) {
692
 				const void *data, size_t len ) {
635
 
693
 
636
-	digest_update ( &md5_algorithm, tls->handshake_md5_ctx, data, len );
637
-	digest_update ( &sha1_algorithm, tls->handshake_sha1_ctx, data, len );
694
+	digest_update ( &md5_sha1_algorithm, tls->handshake_md5_sha1_ctx,
695
+			data, len );
638
 	digest_update ( &sha256_algorithm, tls->handshake_sha256_ctx,
696
 	digest_update ( &sha256_algorithm, tls->handshake_sha256_ctx,
639
 			data, len );
697
 			data, len );
640
 }
698
 }
651
 		return SHA256_DIGEST_SIZE;
709
 		return SHA256_DIGEST_SIZE;
652
 	} else {
710
 	} else {
653
 		/* Use MD5+SHA1 for TLSv1.1 and earlier */
711
 		/* Use MD5+SHA1 for TLSv1.1 and earlier */
654
-		return ( MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE );
712
+		return MD5_SHA1_DIGEST_SIZE;
655
 	}
713
 	}
656
 }
714
 }
657
 
715
 
666
  */
724
  */
667
 static void tls_verify_handshake ( struct tls_session *tls, void *out ) {
725
 static void tls_verify_handshake ( struct tls_session *tls, void *out ) {
668
 	union {
726
 	union {
669
-		uint8_t md5[MD5_CTX_SIZE];
670
-		uint8_t sha1[SHA1_CTX_SIZE];
727
+		uint8_t md5_sha1[MD5_SHA1_CTX_SIZE];
671
 		uint8_t sha256[SHA256_CTX_SIZE];
728
 		uint8_t sha256[SHA256_CTX_SIZE];
672
 	} ctx;
729
 	} ctx;
673
 
730
 
678
 		digest_final ( &sha256_algorithm, ctx.sha256, out );
735
 		digest_final ( &sha256_algorithm, ctx.sha256, out );
679
 	} else {
736
 	} else {
680
 		/* Use MD5+SHA1 for TLSv1.1 and earlier */
737
 		/* Use MD5+SHA1 for TLSv1.1 and earlier */
681
-		memcpy ( ctx.md5, tls->handshake_md5_ctx, sizeof ( ctx.md5 ) );
682
-		digest_final ( &md5_algorithm, ctx.md5, out );
683
-		memcpy ( ctx.sha1, tls->handshake_sha1_ctx,
684
-			 sizeof ( ctx.sha1 ) );
685
-		digest_final ( &sha1_algorithm, ctx.sha1,
686
-			       ( out + MD5_DIGEST_SIZE ) );
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 );
687
 	}
741
 	}
688
 }
742
 }
689
 
743
 
2043
 		      ( sizeof ( tls->pre_master_secret.random ) ) ) ) != 0 ) {
2097
 		      ( sizeof ( tls->pre_master_secret.random ) ) ) ) != 0 ) {
2044
 		goto err_random;
2098
 		goto err_random;
2045
 	}
2099
 	}
2046
-	digest_init ( &md5_algorithm, tls->handshake_md5_ctx );
2047
-	digest_init ( &sha1_algorithm, tls->handshake_sha1_ctx );
2100
+	digest_init ( &md5_sha1_algorithm, tls->handshake_md5_sha1_ctx );
2048
 	digest_init ( &sha256_algorithm, tls->handshake_sha256_ctx );
2101
 	digest_init ( &sha256_algorithm, tls->handshake_sha256_ctx );
2049
 	tls->tx_pending = TLS_TX_CLIENT_HELLO;
2102
 	tls->tx_pending = TLS_TX_CLIENT_HELLO;
2050
 	process_init ( &tls->process, &tls_process_desc, &tls->refcnt );
2103
 	process_init ( &tls->process, &tls_process_desc, &tls->refcnt );

Loading…
Cancel
Save