Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[tls] Split received records over multiple I/O buffers
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.