aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-11-07 18:34:37 +0000
committerMichael Brown <mcb30@ipxe.org>2022-11-08 13:48:45 +0000
commitb6eef1485808093f9dae4fe9d6b685e01a6d65a4 (patch)
tree412bf41dea752f04f3cca2cc658aedac5bebac9a /src
parent6a360ebfde9921b9cacbee724fe25d646e4499d5 (diff)
downloadipxe-b6eef1485808093f9dae4fe9d6b685e01a6d65a4.zip
ipxe-b6eef1485808093f9dae4fe9d6b685e01a6d65a4.tar.gz
ipxe-b6eef1485808093f9dae4fe9d6b685e01a6d65a4.tar.bz2
[tls] Abstract out concept of a TLS authentication header
All TLS cipher types use a common structure for the per-record data that is authenticated in addition to the plaintext itself. This data is used as a prefix in the HMAC calculation for stream and block ciphers, or as additional authenticated data for AEAD ciphers. Define a "TLS authentication header" structure to hold this data as a contiguous block, in order to meet the alignment requirement for AEAD ciphers such as GCM. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/include/ipxe/tls.h8
-rw-r--r--src/net/tls.c40
2 files changed, 27 insertions, 21 deletions
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h
index 8bb1ccc..be192b7 100644
--- a/src/include/ipxe/tls.h
+++ b/src/include/ipxe/tls.h
@@ -122,6 +122,14 @@ struct tls_header {
/* TLS renegotiation information extension */
#define TLS_RENEGOTIATION_INFO 0xff01
+/** TLS authentication header */
+struct tls_auth_header {
+ /** Sequence number */
+ uint64_t seq;
+ /** TLS header */
+ struct tls_header header;
+} __attribute__ (( packed ));
+
/** TLS verification data */
struct tls_verify_data {
/** Client verification data */
diff --git a/src/net/tls.c b/src/net/tls.c
index d2b8d60..a613a08 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -2521,17 +2521,14 @@ static int tls_new_record ( struct tls_connection *tls, unsigned int type,
*
* @v cipherspec Cipher specification
* @v ctx Context
- * @v seq Sequence number
- * @v tlshdr TLS header
+ * @v authhdr Authentication header
*/
static void tls_hmac_init ( struct tls_cipherspec *cipherspec, void *ctx,
- uint64_t seq, struct tls_header *tlshdr ) {
+ struct tls_auth_header *authhdr ) {
struct digest_algorithm *digest = cipherspec->suite->digest;
hmac_init ( digest, ctx, cipherspec->mac_secret, digest->digestsize );
- seq = cpu_to_be64 ( seq );
- hmac_update ( digest, ctx, &seq, sizeof ( seq ) );
- hmac_update ( digest, ctx, tlshdr, sizeof ( *tlshdr ) );
+ hmac_update ( digest, ctx, authhdr, sizeof ( *authhdr ) );
}
/**
@@ -2567,19 +2564,18 @@ static void tls_hmac_final ( struct tls_cipherspec *cipherspec, void *ctx,
* Calculate HMAC
*
* @v cipherspec Cipher specification
- * @v seq Sequence number
- * @v tlshdr TLS header
+ * @v authhdr Authentication header
* @v data Data
* @v len Length of data
* @v mac HMAC to fill in
*/
static void tls_hmac ( struct tls_cipherspec *cipherspec,
- uint64_t seq, struct tls_header *tlshdr,
+ struct tls_auth_header *authhdr,
const void *data, size_t len, void *hmac ) {
struct digest_algorithm *digest = cipherspec->suite->digest;
uint8_t ctx[ hmac_ctxsize ( digest ) ];
- tls_hmac_init ( cipherspec, ctx, seq, tlshdr );
+ tls_hmac_init ( cipherspec, ctx, authhdr );
tls_hmac_update ( cipherspec, ctx, data, len );
tls_hmac_final ( cipherspec, ctx, hmac );
}
@@ -2678,10 +2674,10 @@ static void * tls_assemble_block ( struct tls_connection *tls,
*/
static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
const void *data, size_t len ) {
- struct tls_header plaintext_tlshdr;
- struct tls_header *tlshdr;
struct tls_cipherspec *cipherspec = &tls->tx_cipherspec;
struct cipher_algorithm *cipher = cipherspec->suite->cipher;
+ struct tls_auth_header authhdr;
+ struct tls_header *tlshdr;
void *plaintext = NULL;
size_t plaintext_len;
struct io_buffer *ciphertext = NULL;
@@ -2691,12 +2687,13 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
int rc;
/* Construct header */
- plaintext_tlshdr.type = type;
- plaintext_tlshdr.version = htons ( tls->version );
- plaintext_tlshdr.length = htons ( len );
+ authhdr.seq = cpu_to_be64 ( tls->tx_seq );
+ authhdr.header.type = type;
+ authhdr.header.version = htons ( tls->version );
+ authhdr.header.length = htons ( len );
/* Calculate MAC */
- tls_hmac ( cipherspec, tls->tx_seq, &plaintext_tlshdr, data, len, mac );
+ tls_hmac ( cipherspec, &authhdr, data, len, mac );
/* Allocate and assemble plaintext struct */
if ( is_stream_cipher ( cipher ) ) {
@@ -2852,10 +2849,10 @@ static int tls_split_block ( struct tls_connection *tls,
static int tls_new_ciphertext ( struct tls_connection *tls,
struct tls_header *tlshdr,
struct list_head *rx_data ) {
- struct tls_header plaintext_tlshdr;
struct tls_cipherspec *cipherspec = &tls->rx_cipherspec;
struct cipher_algorithm *cipher = cipherspec->suite->cipher;
struct digest_algorithm *digest = cipherspec->suite->digest;
+ struct tls_auth_header authhdr;
uint8_t ctx[ hmac_ctxsize ( digest ) ];
uint8_t verify_mac[digest->digestsize];
struct io_buffer *iobuf;
@@ -2886,10 +2883,11 @@ static int tls_new_ciphertext ( struct tls_connection *tls,
}
/* Verify MAC */
- plaintext_tlshdr.type = tlshdr->type;
- plaintext_tlshdr.version = tlshdr->version;
- plaintext_tlshdr.length = htons ( len );
- tls_hmac_init ( cipherspec, ctx, tls->rx_seq, &plaintext_tlshdr );
+ authhdr.seq = cpu_to_be64 ( tls->rx_seq );
+ authhdr.header.type = tlshdr->type;
+ authhdr.header.version = tlshdr->version;
+ authhdr.header.length = htons ( len );
+ tls_hmac_init ( cipherspec, ctx, &authhdr );
list_for_each_entry ( iobuf, rx_data, list ) {
tls_hmac_update ( cipherspec, ctx, iobuf->data,
iob_len ( iobuf ) );