|
@@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
33
|
33
|
#include <ipxe/hmac.h>
|
34
|
34
|
#include <ipxe/md5.h>
|
35
|
35
|
#include <ipxe/sha1.h>
|
|
36
|
+#include <ipxe/sha256.h>
|
36
|
37
|
#include <ipxe/aes.h>
|
37
|
38
|
#include <ipxe/rsa.h>
|
38
|
39
|
#include <ipxe/iobuf.h>
|
|
@@ -247,32 +248,40 @@ static void tls_prf ( struct tls_session *tls, void *secret, size_t secret_len,
|
247
|
248
|
size_t subsecret_len;
|
248
|
249
|
void *md5_secret;
|
249
|
250
|
void *sha1_secret;
|
250
|
|
- uint8_t out_md5[out_len];
|
251
|
|
- uint8_t out_sha1[out_len];
|
|
251
|
+ uint8_t buf[out_len];
|
252
|
252
|
unsigned int i;
|
253
|
253
|
|
254
|
254
|
va_start ( seeds, out_len );
|
255
|
255
|
|
256
|
|
- /* Split secret into two, with an overlap of up to one byte */
|
257
|
|
- subsecret_len = ( ( secret_len + 1 ) / 2 );
|
258
|
|
- md5_secret = secret;
|
259
|
|
- sha1_secret = ( secret + secret_len - subsecret_len );
|
|
256
|
+ if ( tls->version >= TLS_VERSION_TLS_1_2 ) {
|
|
257
|
+ /* Use P_SHA256 for TLSv1.2 and later */
|
|
258
|
+ tls_p_hash_va ( tls, &sha256_algorithm, secret, secret_len,
|
|
259
|
+ out, out_len, seeds );
|
|
260
|
+ } else {
|
|
261
|
+ /* Use combination of P_MD5 and P_SHA-1 for TLSv1.1
|
|
262
|
+ * and earlier
|
|
263
|
+ */
|
260
|
264
|
|
261
|
|
- /* Calculate MD5 portion */
|
262
|
|
- va_copy ( tmp, seeds );
|
263
|
|
- tls_p_hash_va ( tls, &md5_algorithm, md5_secret, subsecret_len,
|
264
|
|
- out_md5, out_len, seeds );
|
265
|
|
- va_end ( tmp );
|
|
265
|
+ /* Split secret into two, with an overlap of up to one byte */
|
|
266
|
+ subsecret_len = ( ( secret_len + 1 ) / 2 );
|
|
267
|
+ md5_secret = secret;
|
|
268
|
+ sha1_secret = ( secret + secret_len - subsecret_len );
|
266
|
269
|
|
267
|
|
- /* Calculate SHA1 portion */
|
268
|
|
- va_copy ( tmp, seeds );
|
269
|
|
- tls_p_hash_va ( tls, &sha1_algorithm, sha1_secret, subsecret_len,
|
270
|
|
- out_sha1, out_len, seeds );
|
271
|
|
- va_end ( tmp );
|
|
270
|
+ /* Calculate MD5 portion */
|
|
271
|
+ va_copy ( tmp, seeds );
|
|
272
|
+ tls_p_hash_va ( tls, &md5_algorithm, md5_secret,
|
|
273
|
+ subsecret_len, out, out_len, seeds );
|
|
274
|
+ va_end ( tmp );
|
|
275
|
+
|
|
276
|
+ /* Calculate SHA1 portion */
|
|
277
|
+ va_copy ( tmp, seeds );
|
|
278
|
+ tls_p_hash_va ( tls, &sha1_algorithm, sha1_secret,
|
|
279
|
+ subsecret_len, buf, out_len, seeds );
|
|
280
|
+ va_end ( tmp );
|
272
|
281
|
|
273
|
|
- /* XOR the two portions together into the final output buffer */
|
274
|
|
- for ( i = 0 ; i < out_len ; i++ ) {
|
275
|
|
- *( ( uint8_t * ) out + i ) = ( out_md5[i] ^ out_sha1[i] );
|
|
282
|
+ /* XOR the two portions together into the final output buffer */
|
|
283
|
+ for ( i = 0 ; i < out_len ; i++ )
|
|
284
|
+ *( ( uint8_t * ) out + i ) ^= buf[i];
|
276
|
285
|
}
|
277
|
286
|
|
278
|
287
|
va_end ( seeds );
|
|
@@ -569,6 +578,24 @@ static void tls_add_handshake ( struct tls_session *tls,
|
569
|
578
|
|
570
|
579
|
digest_update ( &md5_algorithm, tls->handshake_md5_ctx, data, len );
|
571
|
580
|
digest_update ( &sha1_algorithm, tls->handshake_sha1_ctx, data, len );
|
|
581
|
+ digest_update ( &sha256_algorithm, tls->handshake_sha256_ctx,
|
|
582
|
+ data, len );
|
|
583
|
+}
|
|
584
|
+
|
|
585
|
+/**
|
|
586
|
+ * Size of handshake output buffer
|
|
587
|
+ *
|
|
588
|
+ * @v tls TLS session
|
|
589
|
+ */
|
|
590
|
+static size_t tls_verify_handshake_len ( struct tls_session *tls ) {
|
|
591
|
+
|
|
592
|
+ if ( tls->version >= TLS_VERSION_TLS_1_2 ) {
|
|
593
|
+ /* Use SHA-256 for TLSv1.2 and later */
|
|
594
|
+ return SHA256_DIGEST_SIZE;
|
|
595
|
+ } else {
|
|
596
|
+ /* Use MD5+SHA1 for TLSv1.1 and earlier */
|
|
597
|
+ return ( MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE );
|
|
598
|
+ }
|
572
|
599
|
}
|
573
|
600
|
|
574
|
601
|
/**
|
|
@@ -577,21 +604,30 @@ static void tls_add_handshake ( struct tls_session *tls,
|
577
|
604
|
* @v tls TLS session
|
578
|
605
|
* @v out Output buffer
|
579
|
606
|
*
|
580
|
|
- * Calculates the MD5+SHA1 digest over all handshake messages seen so
|
581
|
|
- * far.
|
|
607
|
+ * Calculates the MD5+SHA1 or SHA256 digest over all handshake
|
|
608
|
+ * messages seen so far.
|
582
|
609
|
*/
|
583
|
610
|
static void tls_verify_handshake ( struct tls_session *tls, void *out ) {
|
584
|
|
- struct digest_algorithm *md5 = &md5_algorithm;
|
585
|
|
- struct digest_algorithm *sha1 = &sha1_algorithm;
|
586
|
|
- uint8_t md5_ctx[md5->ctxsize];
|
587
|
|
- uint8_t sha1_ctx[sha1->ctxsize];
|
588
|
|
- void *md5_digest = out;
|
589
|
|
- void *sha1_digest = ( out + md5->digestsize );
|
590
|
|
-
|
591
|
|
- memcpy ( md5_ctx, tls->handshake_md5_ctx, sizeof ( md5_ctx ) );
|
592
|
|
- memcpy ( sha1_ctx, tls->handshake_sha1_ctx, sizeof ( sha1_ctx ) );
|
593
|
|
- digest_final ( md5, md5_ctx, md5_digest );
|
594
|
|
- digest_final ( sha1, sha1_ctx, sha1_digest );
|
|
611
|
+ union {
|
|
612
|
+ uint8_t md5[MD5_CTX_SIZE];
|
|
613
|
+ uint8_t sha1[SHA1_CTX_SIZE];
|
|
614
|
+ uint8_t sha256[SHA256_CTX_SIZE];
|
|
615
|
+ } ctx;
|
|
616
|
+
|
|
617
|
+ if ( tls->version >= TLS_VERSION_TLS_1_2 ) {
|
|
618
|
+ /* Use SHA-256 for TLSv1.2 and later */
|
|
619
|
+ memcpy ( ctx.sha256, tls->handshake_sha256_ctx,
|
|
620
|
+ sizeof ( ctx.sha256 ) );
|
|
621
|
+ digest_final ( &sha256_algorithm, ctx.sha256, out );
|
|
622
|
+ } else {
|
|
623
|
+ /* Use MD5+SHA1 for TLSv1.1 and earlier */
|
|
624
|
+ memcpy ( ctx.md5, tls->handshake_md5_ctx, sizeof ( ctx.md5 ) );
|
|
625
|
+ digest_final ( &md5_algorithm, ctx.md5, out );
|
|
626
|
+ memcpy ( ctx.sha1, tls->handshake_sha1_ctx,
|
|
627
|
+ sizeof ( ctx.sha1 ) );
|
|
628
|
+ digest_final ( &sha1_algorithm, ctx.sha1,
|
|
629
|
+ ( out + MD5_DIGEST_SIZE ) );
|
|
630
|
+ }
|
595
|
631
|
}
|
596
|
632
|
|
597
|
633
|
/******************************************************************************
|
|
@@ -770,7 +806,7 @@ static int tls_send_finished ( struct tls_session *tls ) {
|
770
|
806
|
uint32_t type_length;
|
771
|
807
|
uint8_t verify_data[12];
|
772
|
808
|
} __attribute__ (( packed )) finished;
|
773
|
|
- uint8_t digest[MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE];
|
|
809
|
+ uint8_t digest[ tls_verify_handshake_len ( tls ) ];
|
774
|
810
|
|
775
|
811
|
memset ( &finished, 0, sizeof ( finished ) );
|
776
|
812
|
finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
|
|
@@ -1047,7 +1083,7 @@ static int tls_new_finished ( struct tls_session *tls,
|
1047
|
1083
|
char next[0];
|
1048
|
1084
|
} __attribute__ (( packed )) *finished = data;
|
1049
|
1085
|
void *end = finished->next;
|
1050
|
|
- uint8_t digest[MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE];
|
|
1086
|
+ uint8_t digest[ tls_verify_handshake_len ( tls ) ];
|
1051
|
1087
|
uint8_t verify_data[ sizeof ( finished->verify_data ) ];
|
1052
|
1088
|
|
1053
|
1089
|
/* Sanity check */
|
|
@@ -1869,7 +1905,7 @@ int add_tls ( struct interface *xfer, const char *name,
|
1869
|
1905
|
tls->name = name;
|
1870
|
1906
|
intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt );
|
1871
|
1907
|
intf_init ( &tls->cipherstream, &tls_cipherstream_desc, &tls->refcnt );
|
1872
|
|
- tls->version = TLS_VERSION_TLS_1_1;
|
|
1908
|
+ tls->version = TLS_VERSION_TLS_1_2;
|
1873
|
1909
|
tls_clear_cipher ( tls, &tls->tx_cipherspec );
|
1874
|
1910
|
tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );
|
1875
|
1911
|
tls_clear_cipher ( tls, &tls->rx_cipherspec );
|
|
@@ -1886,6 +1922,7 @@ int add_tls ( struct interface *xfer, const char *name,
|
1886
|
1922
|
}
|
1887
|
1923
|
digest_init ( &md5_algorithm, tls->handshake_md5_ctx );
|
1888
|
1924
|
digest_init ( &sha1_algorithm, tls->handshake_sha1_ctx );
|
|
1925
|
+ digest_init ( &sha256_algorithm, tls->handshake_sha256_ctx );
|
1889
|
1926
|
tls->tx_pending = TLS_TX_CLIENT_HELLO;
|
1890
|
1927
|
process_init ( &tls->process, &tls_process_desc, &tls->refcnt );
|
1891
|
1928
|
|