summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/tls.h
diff options
context:
space:
mode:
authorMichael Brown2012-09-26 22:42:23 +0200
committerMichael Brown2012-09-27 02:56:01 +0200
commit72db14640c2a9eac0ba53baa955b180f1f4b9c2f (patch)
tree239f9dbbdfe5c889a9fd72110efae604ec80b14c /src/include/ipxe/tls.h
parent[crypto] Allow in-place CBC decryption (diff)
downloadipxe-72db14640c2a9eac0ba53baa955b180f1f4b9c2f.tar.gz
ipxe-72db14640c2a9eac0ba53baa955b180f1f4b9c2f.tar.xz
ipxe-72db14640c2a9eac0ba53baa955b180f1f4b9c2f.zip
[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.h30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h
index 2af864df..f8a75409 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 );