Skip to content

Commit

Permalink
[tls] Split received records over multiple I/O buffers
Browse files Browse the repository at this point in the history
TLS servers are not obliged to implement the RFC3546 maximum fragment
length extension, and many common servers (including OpenSSL, as used
in Apache's mod_ssl) do not do so.  iPXE may therefore have to cope
with TLS records of up to 16kB.  Allocations for 16kB have a
non-negligible chance of failing, causing the TLS connection to abort.

Fix by maintaining the received record as a linked list of I/O
buffers, rather than a single contiguous buffer.  To reduce memory
pressure, we also decrypt in situ, and deliver the decrypted data via
xfer_deliver_iob() rather than xfer_deliver_raw().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Sep 27, 2012
1 parent 09d45ff commit 72db146
Show file tree
Hide file tree
Showing 2 changed files with 304 additions and 168 deletions.
30 changes: 26 additions & 4 deletions src/include/ipxe/tls.h
Expand Up @@ -19,6 +19,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/sha256.h>
#include <ipxe/x509.h>
#include <ipxe/pending.h>
#include <ipxe/iobuf.h>

/** A TLS header */
struct tls_header {
Expand Down Expand Up @@ -264,14 +265,35 @@ struct tls_session {
uint64_t rx_seq;
/** RX state */
enum tls_rx_state rx_state;
/** Offset within current RX state */
size_t rx_rcvd;
/** Current received record header */
struct tls_header rx_header;
/** Current received raw data buffer */
void *rx_data;
/** Current received record header (static I/O buffer) */
struct io_buffer rx_header_iobuf;
/** List of received data buffers */
struct list_head rx_data;
};

/** RX I/O buffer size
*
* The maximum fragment length extension is optional, and many common
* implementations (including OpenSSL) do not support it. We must
* therefore be prepared to receive records of up to 16kB in length.
* The chance of an allocation of this size failing is non-negligible,
* so we must split received data into smaller allocations.
*/
#define TLS_RX_BUFSIZE 4096

/** Minimum RX I/O buffer size
*
* To simplify manipulations, we ensure that no RX I/O buffer is
* smaller than this size. This allows us to assume that the MAC and
* padding are entirely contained within the final I/O buffer.
*/
#define TLS_RX_MIN_BUFSIZE 512

/** RX I/O buffer alignment */
#define TLS_RX_ALIGN 16

extern int add_tls ( struct interface *xfer, const char *name,
struct interface **next );

Expand Down

0 comments on commit 72db146

Please sign in to comment.