diff options
author | Michael Brown <mcb30@ipxe.org> | 2012-09-26 21:42:23 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2012-09-27 01:56:01 +0100 |
commit | 72db14640c2a9eac0ba53baa955b180f1f4b9c2f (patch) | |
tree | 239f9dbbdfe5c889a9fd72110efae604ec80b14c /src/include/ipxe/tls.h | |
parent | 09d45ffd7991e6b64a76d86f338a2f0973527be6 (diff) | |
download | ipxe-72db14640c2a9eac0ba53baa955b180f1f4b9c2f.tar.gz |
[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>
Diffstat (limited to 'src/include/ipxe/tls.h')
-rw-r--r-- | src/include/ipxe/tls.h | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index 2af864dfe..f8a754096 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -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 { @@ -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 ); |