]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
TLS: Do not enforce in-place processing in tlsv1_record_send()
authorJouni Malinen <j@w1.fi>
Sun, 25 Sep 2011 14:11:52 +0000 (17:11 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 25 Sep 2011 14:11:52 +0000 (17:11 +0300)
In preparation for record layer format changes, modify
tlsv1_record_send() to use separate buffers for payload
and the output message.

src/tls/tlsv1_client.c
src/tls/tlsv1_client_write.c
src/tls/tlsv1_record.c
src/tls/tlsv1_record.h
src/tls/tlsv1_server.c
src/tls/tlsv1_server_write.c

index 8b7e26f2afd1e995107d8e1d56c3e289aaeee1d1..d87ea4f81432abb62fd96b7540a150fee95ce212 100644 (file)
@@ -227,10 +227,8 @@ int tlsv1_client_encrypt(struct tlsv1_client *conn,
        wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
                        in_data, in_len);
 
-       os_memcpy(out_data + TLS_RECORD_HEADER_LEN, in_data, in_len);
-
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
-                             out_data, out_len, in_len, &rlen) < 0) {
+                             out_data, out_len, in_data, in_len, &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
                tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
                          TLS_ALERT_INTERNAL_ERROR);
index 0898df9a02b454bb21b991196510fadd56c49b17..91ac5af4a948f3961155f1e96b2b21668882041f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * TLSv1 client - write handshake message
- * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -116,7 +116,8 @@ u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len)
        tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, out_len) < 0) {
+                             rhdr, end - rhdr, hs_start, pos - hs_start,
+                             out_len) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
                tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
                          TLS_ALERT_INTERNAL_ERROR);
@@ -192,7 +193,8 @@ static int tls_write_client_certificate(struct tlsv1_client *conn,
        WPA_PUT_BE24(hs_length, pos - hs_length - 3);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             rhdr, end - rhdr, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
                tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
                          TLS_ALERT_INTERNAL_ERROR);
@@ -413,7 +415,8 @@ static int tls_write_client_key_exchange(struct tlsv1_client *conn,
        WPA_PUT_BE24(hs_length, pos - hs_length - 3);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             rhdr, end - rhdr, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
                tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
                          TLS_ALERT_INTERNAL_ERROR);
@@ -534,7 +537,8 @@ static int tls_write_client_certificate_verify(struct tlsv1_client *conn,
        WPA_PUT_BE24(hs_length, pos - hs_length - 3);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             rhdr, end - rhdr, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
                tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
                          TLS_ALERT_INTERNAL_ERROR);
@@ -553,17 +557,16 @@ static int tls_write_client_certificate_verify(struct tlsv1_client *conn,
 static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
                                               u8 **msgpos, u8 *end)
 {
-       u8 *pos, *rhdr;
        size_t rlen;
-
-       pos = *msgpos;
+       u8 payload[1];
 
        wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
-       rhdr = pos;
-       pos += TLS_RECORD_HEADER_LEN;
-       *pos = TLS_CHANGE_CIPHER_SPEC;
+
+       payload[0] = TLS_CHANGE_CIPHER_SPEC;
+
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
-                             rhdr, end - rhdr, 1, &rlen) < 0) {
+                             *msgpos, end - *msgpos, payload, sizeof(payload),
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
                tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
                          TLS_ALERT_INTERNAL_ERROR);
@@ -578,7 +581,7 @@ static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
                return -1;
        }
 
-       *msgpos = rhdr + rlen;
+       *msgpos += rlen;
 
        return 0;
 }
@@ -587,13 +590,11 @@ static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
 static int tls_write_client_finished(struct tlsv1_client *conn,
                                     u8 **msgpos, u8 *end)
 {
-       u8 *pos, *rhdr, *hs_start, *hs_length;
+       u8 *pos, *hs_start;
        size_t rlen, hlen;
-       u8 verify_data[TLS_VERIFY_DATA_LEN];
+       u8 verify_data[1 + 3 + TLS_VERIFY_DATA_LEN];
        u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
 
-       pos = *msgpos;
-
        wpa_printf(MSG_DEBUG, "TLSv1: Send Finished");
 
        /* Encrypted Handshake Message: Finished */
@@ -622,40 +623,35 @@ static int tls_write_client_finished(struct tlsv1_client *conn,
 
        if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
                    "client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
-                   verify_data, TLS_VERIFY_DATA_LEN)) {
+                   verify_data + 1 + 3, TLS_VERIFY_DATA_LEN)) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
                tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
                          TLS_ALERT_INTERNAL_ERROR);
                return -1;
        }
        wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
-                       verify_data, TLS_VERIFY_DATA_LEN);
+                       verify_data + 1 + 3, TLS_VERIFY_DATA_LEN);
 
-       rhdr = pos;
-       pos += TLS_RECORD_HEADER_LEN;
        /* Handshake */
-       hs_start = pos;
+       pos = hs_start = verify_data;
        /* HandshakeType msg_type */
        *pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
-       /* uint24 length (to be filled) */
-       hs_length = pos;
+       /* uint24 length */
+       WPA_PUT_BE24(pos, TLS_VERIFY_DATA_LEN);
        pos += 3;
-       os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN);
-       pos += TLS_VERIFY_DATA_LEN;
-       WPA_PUT_BE24(hs_length, pos - hs_length - 3);
+       pos += TLS_VERIFY_DATA_LEN; /* verify_data already in place */
        tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             *msgpos, end - *msgpos, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
                tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
                          TLS_ALERT_INTERNAL_ERROR);
                return -1;
        }
 
-       pos = rhdr + rlen;
-
-       *msgpos = pos;
+       *msgpos += rlen;
 
        return 0;
 }
index c729264c281671f827a618640e95b3a31fbb4462..8efdae67d7ab38e6f5cf588119bdccd2c7723a43 100644 (file)
@@ -138,10 +138,10 @@ int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl)
  * tlsv1_record_send - TLS record layer: Send a message
  * @rl: Pointer to TLS record layer data
  * @content_type: Content type (TLS_CONTENT_TYPE_*)
- * @buf: Buffer to send (with TLS_RECORD_HEADER_LEN octets reserved in the
- * beginning for record layer to fill in; payload filled in after this and
- * extra space in the end for HMAC).
+ * @buf: Buffer for the generated TLS message (needs to have extra space for
+ * header and HMAC)
  * @buf_size: Maximum buf size
+ * @payload: Payload to be sent
  * @payload_len: Length of the payload
  * @out_len: Buffer for returning the used buf length
  * Returns: 0 on success, -1 on failure
@@ -150,13 +150,17 @@ int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl)
  * the data using the current write cipher.
  */
 int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
-                     size_t buf_size, size_t payload_len, size_t *out_len)
+                     size_t buf_size, const u8 *payload, size_t payload_len,
+                     size_t *out_len)
 {
-       u8 *pos, *ct_start, *length, *payload;
+       u8 *pos, *ct_start, *length, *cpayload;
        struct crypto_hash *hmac;
        size_t clen;
 
        pos = buf;
+       if (pos + TLS_RECORD_HEADER_LEN > buf + buf_size)
+               return -1;
+
        /* ContentType type */
        ct_start = pos;
        *pos++ = content_type;
@@ -168,11 +172,23 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
        WPA_PUT_BE16(length, payload_len);
        pos += 2;
 
-       /* opaque fragment[TLSPlaintext.length] */
-       payload = pos;
+       cpayload = pos;
+
+       /*
+        * opaque fragment[TLSPlaintext.length]
+        * (opaque content[TLSCompressed.length] in GenericBlockCipher)
+        */
+       if (pos + payload_len > buf + buf_size)
+               return -1;
+       os_memmove(pos, payload, payload_len);
        pos += payload_len;
 
        if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
+               /*
+                * MAC calculated over seq_num + TLSCompressed.type +
+                * TLSCompressed.version + TLSCompressed.length +
+                * TLSCompressed.fragment
+                */
                hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret,
                                        rl->hash_size);
                if (hmac == NULL) {
@@ -182,7 +198,8 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
                }
                crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN);
                /* type + version + length + fragment */
-               crypto_hash_update(hmac, ct_start, pos - ct_start);
+               crypto_hash_update(hmac, ct_start, TLS_RECORD_HEADER_LEN);
+               crypto_hash_update(hmac, payload, payload_len);
                clen = buf + buf_size - pos;
                if (clen < rl->hash_size) {
                        wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not "
@@ -200,7 +217,7 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
                            pos, clen);
                pos += clen;
                if (rl->iv_size) {
-                       size_t len = pos - payload;
+                       size_t len = pos - cpayload;
                        size_t pad;
                        pad = (len + 1) % rl->iv_size;
                        if (pad)
@@ -214,8 +231,8 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
                        pos += pad + 1;
                }
 
-               if (crypto_cipher_encrypt(rl->write_cbc, payload,
-                                         payload, pos - payload) < 0)
+               if (crypto_cipher_encrypt(rl->write_cbc, cpayload,
+                                         cpayload, pos - cpayload) < 0)
                        return -1;
        }
 
index 9c7c0a4e644e2167795687df0e25dc74607c2c00..acbdccaee97b640d4b91e15f162bc9b3dd11ade8 100644 (file)
@@ -66,7 +66,8 @@ int tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl,
 int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl);
 int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl);
 int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
-                     size_t buf_size, size_t payload_len, size_t *out_len);
+                     size_t buf_size, const u8 *payload, size_t payload_len,
+                     size_t *out_len);
 int tlsv1_record_receive(struct tlsv1_record_layer *rl,
                         const u8 *in_data, size_t in_len,
                         u8 *out_data, size_t *out_len, u8 *alert);
index 6a6123564553cf8de4699e99e55bb35ce4d1b2cf..06eab61ca86a9c84c82e42c2488d8e4f0486a1d2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * TLSv1 server (RFC 2246)
- * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -201,10 +201,8 @@ int tlsv1_server_encrypt(struct tlsv1_server *conn,
        wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
                        in_data, in_len);
 
-       os_memcpy(out_data + TLS_RECORD_HEADER_LEN, in_data, in_len);
-
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
-                             out_data, out_len, in_len, &rlen) < 0) {
+                             out_data, out_len, in_data, in_len, &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
index e89e52ec000368ebbc0be9ff4490c7a3dfb09821..a3d32b0ab653dc685262aa61942d1165342c002d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * TLSv1 server - write handshake message
- * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -143,7 +143,8 @@ static int tls_write_server_hello(struct tlsv1_server *conn,
        tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             rhdr, end - rhdr, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
@@ -227,7 +228,8 @@ static int tls_write_server_certificate(struct tlsv1_server *conn,
        WPA_PUT_BE24(hs_length, pos - hs_length - 3);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             rhdr, end - rhdr, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
@@ -418,7 +420,8 @@ static int tls_write_server_key_exchange(struct tlsv1_server *conn,
        WPA_PUT_BE24(hs_length, pos - hs_length - 3);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             rhdr, end - rhdr, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
@@ -483,7 +486,8 @@ static int tls_write_server_certificate_request(struct tlsv1_server *conn,
        WPA_PUT_BE24(hs_length, pos - hs_length - 3);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             rhdr, end - rhdr, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
@@ -502,40 +506,35 @@ static int tls_write_server_certificate_request(struct tlsv1_server *conn,
 static int tls_write_server_hello_done(struct tlsv1_server *conn,
                                       u8 **msgpos, u8 *end)
 {
-       u8 *pos, *rhdr, *hs_start, *hs_length;
+       u8 *pos;
        size_t rlen;
-
-       pos = *msgpos;
+       u8 payload[4];
 
        wpa_printf(MSG_DEBUG, "TLSv1: Send ServerHelloDone");
-       rhdr = pos;
-       pos += TLS_RECORD_HEADER_LEN;
 
        /* opaque fragment[TLSPlaintext.length] */
 
        /* Handshake */
-       hs_start = pos;
+       pos = payload;
        /* HandshakeType msg_type */
        *pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE;
-       /* uint24 length (to be filled) */
-       hs_length = pos;
+       /* uint24 length */
+       WPA_PUT_BE24(pos, 0);
        pos += 3;
        /* body - ServerHelloDone (empty) */
 
-       WPA_PUT_BE24(hs_length, pos - hs_length - 3);
-
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             *msgpos, end - *msgpos, payload, pos - payload,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
                return -1;
        }
-       pos = rhdr + rlen;
 
-       tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
+       tls_verify_hash_add(&conn->verify, payload, pos - payload);
 
-       *msgpos = pos;
+       *msgpos += rlen;
 
        return 0;
 }
@@ -544,17 +543,16 @@ static int tls_write_server_hello_done(struct tlsv1_server *conn,
 static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
                                               u8 **msgpos, u8 *end)
 {
-       u8 *pos, *rhdr;
        size_t rlen;
-
-       pos = *msgpos;
+       u8 payload[1];
 
        wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
-       rhdr = pos;
-       pos += TLS_RECORD_HEADER_LEN;
-       *pos = TLS_CHANGE_CIPHER_SPEC;
+
+       payload[0] = TLS_CHANGE_CIPHER_SPEC;
+
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
-                             rhdr, end - rhdr, 1, &rlen) < 0) {
+                             *msgpos, end - *msgpos, payload, sizeof(payload),
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
@@ -569,7 +567,7 @@ static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
                return -1;
        }
 
-       *msgpos = rhdr + rlen;
+       *msgpos += rlen;
 
        return 0;
 }
@@ -578,9 +576,9 @@ static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
 static int tls_write_server_finished(struct tlsv1_server *conn,
                                     u8 **msgpos, u8 *end)
 {
-       u8 *pos, *rhdr, *hs_start, *hs_length;
+       u8 *pos, *hs_start;
        size_t rlen, hlen;
-       u8 verify_data[TLS_VERIFY_DATA_LEN];
+       u8 verify_data[1 + 3 + TLS_VERIFY_DATA_LEN];
        u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
 
        pos = *msgpos;
@@ -613,40 +611,35 @@ static int tls_write_server_finished(struct tlsv1_server *conn,
 
        if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
                    "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
-                   verify_data, TLS_VERIFY_DATA_LEN)) {
+                   verify_data + 1 + 3, TLS_VERIFY_DATA_LEN)) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
                return -1;
        }
        wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
-                       verify_data, TLS_VERIFY_DATA_LEN);
+                       verify_data + 1 + 3, TLS_VERIFY_DATA_LEN);
 
-       rhdr = pos;
-       pos += TLS_RECORD_HEADER_LEN;
        /* Handshake */
-       hs_start = pos;
+       pos = hs_start = verify_data;
        /* HandshakeType msg_type */
        *pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
-       /* uint24 length (to be filled) */
-       hs_length = pos;
+       /* uint24 length */
+       WPA_PUT_BE24(pos, TLS_VERIFY_DATA_LEN);
        pos += 3;
-       os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN);
        pos += TLS_VERIFY_DATA_LEN;
-       WPA_PUT_BE24(hs_length, pos - hs_length - 3);
        tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
 
        if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
-                             rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
+                             *msgpos, end - *msgpos, hs_start, pos - hs_start,
+                             &rlen) < 0) {
                wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
                tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
                                   TLS_ALERT_INTERNAL_ERROR);
                return -1;
        }
 
-       pos = rhdr + rlen;
-
-       *msgpos = pos;
+       *msgpos += rlen;
 
        return 0;
 }