summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/ipxe/dhe.h19
-rw-r--r--src/include/ipxe/ecam.h57
-rw-r--r--src/include/ipxe/ecam_io.h139
-rw-r--r--src/include/ipxe/efi/efi_pci_api.h13
-rw-r--r--src/include/ipxe/errfile.h5
-rw-r--r--src/include/ipxe/hmac.h40
-rw-r--r--src/include/ipxe/linux/linux_pci.h16
-rw-r--r--src/include/ipxe/md4.h3
-rw-r--r--src/include/ipxe/md5.h3
-rw-r--r--src/include/ipxe/pci.h21
-rw-r--r--src/include/ipxe/pci_io.h55
-rw-r--r--src/include/ipxe/pcibridge.h43
-rw-r--r--src/include/ipxe/sha1.h3
-rw-r--r--src/include/ipxe/sha256.h3
-rw-r--r--src/include/ipxe/sha512.h3
-rw-r--r--src/include/ipxe/tls.h37
16 files changed, 423 insertions, 37 deletions
diff --git a/src/include/ipxe/dhe.h b/src/include/ipxe/dhe.h
new file mode 100644
index 000000000..3cd24a880
--- /dev/null
+++ b/src/include/ipxe/dhe.h
@@ -0,0 +1,19 @@
+#ifndef _IPXE_DHE_H
+#define _IPXE_DHE_H
+
+/** @file
+ *
+ * Ephemeral Diffie-Hellman key exchange
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+
+extern int dhe_key ( const void *modulus, size_t len, const void *generator,
+ size_t generator_len, const void *partner,
+ size_t partner_len, const void *private,
+ size_t private_len, void *public, void *shared );
+
+#endif /* _IPXE_DHE_H */
diff --git a/src/include/ipxe/ecam.h b/src/include/ipxe/ecam.h
new file mode 100644
index 000000000..683d613a0
--- /dev/null
+++ b/src/include/ipxe/ecam.h
@@ -0,0 +1,57 @@
+#ifndef _IPXE_ECAM_H
+#define _IPXE_ECAM_H
+
+/** @file
+ *
+ * PCI I/O API for Enhanced Configuration Access Mechanism (ECAM)
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/acpi.h>
+#include <ipxe/pci.h>
+
+/** Enhanced Configuration Access Mechanism per-device size */
+#define ECAM_SIZE 4096
+
+/** Enhanced Configuration Access Mechanism table signature */
+#define ECAM_SIGNATURE ACPI_SIGNATURE ( 'M', 'C', 'F', 'G' )
+
+/** An Enhanced Configuration Access Mechanism allocation */
+struct ecam_allocation {
+ /** Base address */
+ uint64_t base;
+ /** PCI segment number */
+ uint16_t segment;
+ /** Start PCI bus number */
+ uint8_t start;
+ /** End PCI bus number */
+ uint8_t end;
+ /** Reserved */
+ uint8_t reserved[4];
+} __attribute__ (( packed ));
+
+/** An Enhanced Configuration Access Mechanism table */
+struct ecam_table {
+ /** ACPI header */
+ struct acpi_header acpi;
+ /** Reserved */
+ uint8_t reserved[8];
+ /** Allocation structures */
+ struct ecam_allocation alloc[0];
+} __attribute__ (( packed ));
+
+/** A mapped Enhanced Configuration Access Mechanism allocation */
+struct ecam_mapping {
+ /** Allocation */
+ struct ecam_allocation alloc;
+ /** PCI bus:dev.fn address range */
+ struct pci_range range;
+ /** MMIO base address */
+ void *regs;
+};
+
+extern struct pci_api ecam_api;
+
+#endif /* _IPXE_ECAM_H */
diff --git a/src/include/ipxe/ecam_io.h b/src/include/ipxe/ecam_io.h
new file mode 100644
index 000000000..4fb24db33
--- /dev/null
+++ b/src/include/ipxe/ecam_io.h
@@ -0,0 +1,139 @@
+#ifndef _IPXE_ECAM_IO_H
+#define _IPXE_ECAM_IO_H
+
+/** @file
+ *
+ * PCI I/O API for Enhanced Configuration Access Mechanism (ECAM)
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+
+#ifdef PCIAPI_ECAM
+#define PCIAPI_PREFIX_ecam
+#else
+#define PCIAPI_PREFIX_ecam __ecam_
+#endif
+
+struct pci_device;
+
+/** Construct ECAM location */
+#define ECAM_LOC( where, len ) ( ( (len) << 16 ) | where )
+
+/** Extract offset from ECAM location */
+#define ECAM_WHERE( location ) ( (location) & 0xffff )
+
+/** Extract length from ECAM location */
+#define ECAM_LEN( location ) ( (location) >> 16 )
+
+extern int ecam_read ( struct pci_device *pci, unsigned int location,
+ void *value );
+extern int ecam_write ( struct pci_device *pci, unsigned int location,
+ unsigned long value );
+
+/**
+ * Read byte from PCI configuration space via ECAM
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( ecam, pci_read_config_byte ) ( struct pci_device *pci,
+ unsigned int where,
+ uint8_t *value ) {
+ return ecam_read ( pci, ECAM_LOC ( where, sizeof ( *value ) ), value );
+}
+
+/**
+ * Read word from PCI configuration space via ECAM
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( ecam, pci_read_config_word ) ( struct pci_device *pci,
+ unsigned int where,
+ uint16_t *value ) {
+ return ecam_read ( pci, ECAM_LOC ( where, sizeof ( *value ) ), value );
+}
+
+/**
+ * Read dword from PCI configuration space via ECAM
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( ecam, pci_read_config_dword ) ( struct pci_device *pci,
+ unsigned int where,
+ uint32_t *value ) {
+ return ecam_read ( pci, ECAM_LOC ( where, sizeof ( *value ) ), value );
+}
+
+/**
+ * Write byte to PCI configuration space via ECAM
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( ecam, pci_write_config_byte ) ( struct pci_device *pci,
+ unsigned int where,
+ uint8_t value ) {
+ return ecam_write ( pci, ECAM_LOC ( where, sizeof ( value ) ), value );
+}
+
+/**
+ * Write word to PCI configuration space via ECAM
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( ecam, pci_write_config_word ) ( struct pci_device *pci,
+ unsigned int where,
+ uint16_t value ) {
+ return ecam_write ( pci, ECAM_LOC ( where, sizeof ( value ) ), value );
+}
+
+/**
+ * Write dword to PCI configuration space via ECAM
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( ecam, pci_write_config_dword ) ( struct pci_device *pci,
+ unsigned int where,
+ uint32_t value ) {
+ return ecam_write ( pci, ECAM_LOC ( where, sizeof ( value ) ), value );
+}
+
+/**
+ * Map PCI bus address as an I/O address
+ *
+ * @v bus_addr PCI bus address
+ * @v len Length of region
+ * @ret io_addr I/O address, or NULL on error
+ */
+static inline __always_inline void *
+PCIAPI_INLINE ( ecam, pci_ioremap ) ( struct pci_device *pci __unused,
+ unsigned long bus_addr, size_t len ) {
+ return ioremap ( bus_addr, len );
+}
+
+#endif /* _IPXE_ECAM_IO_H */
diff --git a/src/include/ipxe/efi/efi_pci_api.h b/src/include/ipxe/efi/efi_pci_api.h
index 887d5ee14..cf5e1d020 100644
--- a/src/include/ipxe/efi/efi_pci_api.h
+++ b/src/include/ipxe/efi/efi_pci_api.h
@@ -33,14 +33,17 @@ extern int efipci_write ( struct pci_device *pci, unsigned long location,
unsigned long value );
/**
- * Determine number of PCI buses within system
+ * Find next PCI bus:dev.fn address range in system
*
- * @ret num_bus Number of buses
+ * @v busdevfn Starting PCI bus:dev.fn address
+ * @v range PCI bus:dev.fn address range to fill in
*/
-static inline __always_inline int
-PCIAPI_INLINE ( efi, pci_num_bus ) ( void ) {
+static inline __always_inline void
+PCIAPI_INLINE ( efi, pci_discover ) ( uint32_t busdevfn __unused,
+ struct pci_range *range ) {
+
/* EFI does not want us to scan the PCI bus ourselves */
- return 0;
+ range->count = 0;
}
/**
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index 81f555725..c3541e8a0 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -215,6 +215,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_iphone ( ERRFILE_DRIVER | 0x00cf0000 )
#define ERRFILE_slirp ( ERRFILE_DRIVER | 0x00d00000 )
#define ERRFILE_rdc ( ERRFILE_DRIVER | 0x00d10000 )
+#define ERRFILE_ice ( ERRFILE_DRIVER | 0x00d20000 )
+#define ERRFILE_ecam ( ERRFILE_DRIVER | 0x00d30000 )
+#define ERRFILE_pcibridge ( ERRFILE_DRIVER | 0x00d40000 )
#define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 )
#define ERRFILE_arp ( ERRFILE_NET | 0x00010000 )
@@ -396,6 +399,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_linux_sysfs ( ERRFILE_OTHER | 0x00560000 )
#define ERRFILE_linux_acpi ( ERRFILE_OTHER | 0x00570000 )
#define ERRFILE_dynkeymap ( ERRFILE_OTHER | 0x00580000 )
+#define ERRFILE_pci_cmd ( ERRFILE_OTHER | 0x00590000 )
+#define ERRFILE_dhe ( ERRFILE_OTHER | 0x005a0000 )
/** @} */
diff --git a/src/include/ipxe/hmac.h b/src/include/ipxe/hmac.h
index 09d3e273d..cf9d08677 100644
--- a/src/include/ipxe/hmac.h
+++ b/src/include/ipxe/hmac.h
@@ -10,23 +10,45 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/crypto.h>
+/** HMAC context type */
+#define hmac_context_t( digest ) struct { \
+ /** Digest context */ \
+ uint8_t ctx[ digest->ctxsize ]; \
+ /** HMAC input/output padding */ \
+ uint8_t pad[ digest->blocksize ]; \
+ } __attribute__ (( packed ))
+
+/**
+ * Calculate HMAC context size
+ *
+ * @v digest Digest algorithm to use
+ * @ret len HMAC context size
+ */
+static inline __attribute__ (( always_inline )) size_t
+hmac_ctxsize ( struct digest_algorithm *digest ) {
+ hmac_context_t ( digest ) *hctx;
+
+ return sizeof ( *hctx );
+}
+
/**
* Update HMAC
*
* @v digest Digest algorithm to use
- * @v digest_ctx Digest context
+ * @v ctx HMAC context
* @v data Data
* @v len Length of data
*/
-static inline void hmac_update ( struct digest_algorithm *digest,
- void *digest_ctx, const void *data,
- size_t len ) {
- digest_update ( digest, digest_ctx, data, len );
+static inline void hmac_update ( struct digest_algorithm *digest, void *ctx,
+ const void *data, size_t len ) {
+ hmac_context_t ( digest ) *hctx = ctx;
+
+ digest_update ( digest, hctx->ctx, data, len );
}
-extern void hmac_init ( struct digest_algorithm *digest, void *digest_ctx,
- void *key, size_t *key_len );
-extern void hmac_final ( struct digest_algorithm *digest, void *digest_ctx,
- void *key, size_t *key_len, void *hmac );
+extern void hmac_init ( struct digest_algorithm *digest, void *ctx,
+ const void *key, size_t key_len );
+extern void hmac_final ( struct digest_algorithm *digest, void *ctx,
+ void *hmac );
#endif /* _IPXE_HMAC_H */
diff --git a/src/include/ipxe/linux/linux_pci.h b/src/include/ipxe/linux/linux_pci.h
index de42f766b..ec6ff8b1c 100644
--- a/src/include/ipxe/linux/linux_pci.h
+++ b/src/include/ipxe/linux/linux_pci.h
@@ -23,14 +23,18 @@ extern int linux_pci_write ( struct pci_device *pci, unsigned long where,
unsigned long value, size_t len );
/**
- * Determine number of PCI buses within system
+ * Find next PCI bus:dev.fn address range in system
*
- * @ret num_bus Number of buses
+ * @v busdevfn Starting PCI bus:dev.fn address
+ * @v range PCI bus:dev.fn address range to fill in
*/
-static inline __always_inline int
-PCIAPI_INLINE ( linux, pci_num_bus ) ( void ) {
- /* Assume all buses may exist */
- return 0x100;
+static inline __always_inline void
+PCIAPI_INLINE ( linux, pci_discover ) ( uint32_t busdevfn __unused,
+ struct pci_range *range ) {
+
+ /* Assume all buses in segment 0 may exist */
+ range->start = PCI_BUSDEVFN ( 0, 0, 0, 0 );
+ range->count = PCI_BUSDEVFN ( 1, 0, 0, 0 );
}
/**
diff --git a/src/include/ipxe/md4.h b/src/include/ipxe/md4.h
index 8f172e626..9f6cb8a5f 100644
--- a/src/include/ipxe/md4.h
+++ b/src/include/ipxe/md4.h
@@ -65,6 +65,9 @@ struct md4_context {
/** MD4 context size */
#define MD4_CTX_SIZE sizeof ( struct md4_context )
+/** MD4 block size */
+#define MD4_BLOCK_SIZE sizeof ( union md4_block )
+
/** MD4 digest size */
#define MD4_DIGEST_SIZE sizeof ( struct md4_digest )
diff --git a/src/include/ipxe/md5.h b/src/include/ipxe/md5.h
index 05c3974c8..527ad3658 100644
--- a/src/include/ipxe/md5.h
+++ b/src/include/ipxe/md5.h
@@ -65,6 +65,9 @@ struct md5_context {
/** MD5 context size */
#define MD5_CTX_SIZE sizeof ( struct md5_context )
+/** MD5 block size */
+#define MD5_BLOCK_SIZE sizeof ( union md5_block )
+
/** MD5 digest size */
#define MD5_DIGEST_SIZE sizeof ( struct md5_digest )
diff --git a/src/include/ipxe/pci.h b/src/include/ipxe/pci.h
index 933f48530..637b20d60 100644
--- a/src/include/ipxe/pci.h
+++ b/src/include/ipxe/pci.h
@@ -127,6 +127,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Network controller */
#define PCI_CLASS_NETWORK 0x02
+/** Bridge device */
+#define PCI_CLASS_BRIDGE 0x06
+#define PCI_CLASS_BRIDGE_PCI 0x04 /**< PCI-to-PCI bridge */
+
/** Serial bus controller */
#define PCI_CLASS_SERIAL 0x0c
#define PCI_CLASS_SERIAL_USB 0x03 /**< USB controller */
@@ -135,9 +139,20 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define PCI_CLASS_SERIAL_USB_EHCI 0x20 /**< ECHI USB controller */
#define PCI_CLASS_SERIAL_USB_XHCI 0x30 /**< xHCI USB controller */
+/** Primary bus number */
+#define PCI_PRIMARY 0x18
+
+/** Secondary bus number */
+#define PCI_SECONDARY 0x19
+
/** Subordinate bus number */
#define PCI_SUBORDINATE 0x1a
+/** Memory base and limit */
+#define PCI_MEM_BASE 0x20
+#define PCI_MEM_LIMIT 0x22
+#define PCI_MEM_MASK 0x000f
+
/** Construct PCI class
*
* @v base Base class (or PCI_ANY_ID)
@@ -262,9 +277,6 @@ struct pci_driver {
#define PCI_BUS( busdevfn ) ( ( (busdevfn) >> 8 ) & 0xff )
#define PCI_SLOT( busdevfn ) ( ( (busdevfn) >> 3 ) & 0x1f )
#define PCI_FUNC( busdevfn ) ( ( (busdevfn) >> 0 ) & 0x07 )
-#define PCI_BUSDEVFN( segment, bus, slot, func ) \
- ( ( (segment) << 16 ) | ( (bus) << 8 ) | \
- ( (slot) << 3 ) | ( (func) << 0 ) )
#define PCI_FIRST_FUNC( busdevfn ) ( (busdevfn) & ~0x07 )
#define PCI_LAST_FUNC( busdevfn ) ( (busdevfn) | 0x07 )
@@ -301,7 +313,7 @@ extern void adjust_pci_device ( struct pci_device *pci );
extern unsigned long pci_bar_start ( struct pci_device *pci,
unsigned int reg );
extern int pci_read_config ( struct pci_device *pci );
-extern int pci_find_next ( struct pci_device *pci, unsigned int busdevfn );
+extern int pci_find_next ( struct pci_device *pci, uint32_t *busdevfn );
extern int pci_find_driver ( struct pci_device *pci );
extern int pci_probe ( struct pci_device *pci );
extern void pci_remove ( struct pci_device *pci );
@@ -309,6 +321,7 @@ extern int pci_find_capability ( struct pci_device *pci, int capability );
extern int pci_find_next_capability ( struct pci_device *pci,
int pos, int capability );
extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg );
+extern void pci_reset ( struct pci_device *pci, unsigned int exp );
/**
* Initialise PCI device
diff --git a/src/include/ipxe/pci_io.h b/src/include/ipxe/pci_io.h
index 2dcdd9b28..4c035b18b 100644
--- a/src/include/ipxe/pci_io.h
+++ b/src/include/ipxe/pci_io.h
@@ -14,6 +14,21 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/iomap.h>
#include <config/ioapi.h>
+struct pci_device;
+struct pci_api;
+
+/** A PCI bus:dev.fn address range */
+struct pci_range {
+ /** Starting bus:dev.fn address */
+ uint32_t start;
+ /** Number of bus:dev.fn addresses within this range */
+ unsigned int count;
+};
+
+#define PCI_BUSDEVFN( segment, bus, slot, func ) \
+ ( ( (segment) << 16 ) | ( (bus) << 8 ) | \
+ ( (slot) << 3 ) | ( (func) << 0 ) )
+
/**
* Calculate static inline PCI I/O API function name
*
@@ -44,6 +59,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
PROVIDE_SINGLE_API_INLINE ( PCIAPI_PREFIX_ ## _subsys, _api_func )
/* Include all architecture-independent I/O API headers */
+#include <ipxe/ecam_io.h>
#include <ipxe/efi/efi_pci_api.h>
#include <ipxe/linux/linux_pci.h>
@@ -51,11 +67,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <bits/pci_io.h>
/**
- * Determine number of PCI buses within system
+ * Find next PCI bus:dev.fn address range in system
*
- * @ret num_bus Number of buses
+ * @v busdevfn Starting PCI bus:dev.fn address
+ * @v range PCI bus:dev.fn address range to fill in
*/
-int pci_num_bus ( void );
+void pci_discover ( uint32_t busdevfn, struct pci_range *range );
/**
* Read byte from PCI configuration space
@@ -133,4 +150,36 @@ int pci_write_config_dword ( struct pci_device *pci, unsigned int where,
void * pci_ioremap ( struct pci_device *pci, unsigned long bus_addr,
size_t len );
+/** A runtime selectable PCI I/O API */
+struct pci_api {
+ const char *name;
+ typeof ( pci_discover ) ( * pci_discover );
+ typeof ( pci_read_config_byte ) ( * pci_read_config_byte );
+ typeof ( pci_read_config_word ) ( * pci_read_config_word );
+ typeof ( pci_read_config_dword ) ( * pci_read_config_dword );
+ typeof ( pci_write_config_byte ) ( * pci_write_config_byte );
+ typeof ( pci_write_config_word ) ( * pci_write_config_word );
+ typeof ( pci_write_config_dword ) ( * pci_write_config_dword );
+ typeof ( pci_ioremap ) ( * pci_ioremap );
+};
+
+/** Provide a runtime selectable PCI I/O API */
+#define PCIAPI_RUNTIME( _subsys ) { \
+ .name = #_subsys, \
+ .pci_discover = PCIAPI_INLINE ( _subsys, pci_discover ), \
+ .pci_read_config_byte = \
+ PCIAPI_INLINE ( _subsys, pci_read_config_byte ), \
+ .pci_read_config_word = \
+ PCIAPI_INLINE ( _subsys, pci_read_config_word ), \
+ .pci_read_config_dword = \
+ PCIAPI_INLINE ( _subsys, pci_read_config_dword ), \
+ .pci_write_config_byte = \
+ PCIAPI_INLINE ( _subsys, pci_write_config_byte ), \
+ .pci_write_config_word = \
+ PCIAPI_INLINE ( _subsys, pci_write_config_word ), \
+ .pci_write_config_dword = \
+ PCIAPI_INLINE ( _subsys, pci_write_config_dword ), \
+ .pci_ioremap = PCIAPI_INLINE ( _subsys, pci_ioremap ), \
+ }
+
#endif /* _IPXE_PCI_IO_H */
diff --git a/src/include/ipxe/pcibridge.h b/src/include/ipxe/pcibridge.h
new file mode 100644
index 000000000..c57a81067
--- /dev/null
+++ b/src/include/ipxe/pcibridge.h
@@ -0,0 +1,43 @@
+#ifndef _IPXE_PCIBRIDGE_H
+#define _IPXE_PCIBRIDGE_H
+
+/** @file
+ *
+ * PCI-to-PCI bridge
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/list.h>
+#include <ipxe/pci.h>
+
+/** A PCI-to-PCI bridge */
+struct pci_bridge {
+ /** PCI device */
+ struct pci_device *pci;
+ /** Bridge numbers */
+ union {
+ /** Raw dword */
+ uint32_t buses;
+ struct {
+ /** Primary bus */
+ uint8_t primary;
+ /** Secondary bus */
+ uint8_t secondary;
+ /** Subordinate bus */
+ uint8_t subordinate;
+ } __attribute__ (( packed ));
+ };
+ /** Memory base */
+ uint32_t membase;
+ /** Memory limit */
+ uint32_t memlimit;
+ /** List of bridges */
+ struct list_head list;
+};
+
+extern struct pci_bridge * pcibridge_find ( struct pci_device *pci );
+
+#endif /* _IPXE_PCIBRIDGE_H */
diff --git a/src/include/ipxe/sha1.h b/src/include/ipxe/sha1.h
index a97035ec7..9cbbebdee 100644
--- a/src/include/ipxe/sha1.h
+++ b/src/include/ipxe/sha1.h
@@ -65,6 +65,9 @@ struct sha1_context {
/** SHA-1 context size */
#define SHA1_CTX_SIZE sizeof ( struct sha1_context )
+/** SHA-1 block size */
+#define SHA1_BLOCK_SIZE sizeof ( union sha1_block )
+
/** SHA-1 digest size */
#define SHA1_DIGEST_SIZE sizeof ( struct sha1_digest )
diff --git a/src/include/ipxe/sha256.h b/src/include/ipxe/sha256.h
index e234cce33..f226ad07b 100644
--- a/src/include/ipxe/sha256.h
+++ b/src/include/ipxe/sha256.h
@@ -70,6 +70,9 @@ struct sha256_context {
/** SHA-256 context size */
#define SHA256_CTX_SIZE sizeof ( struct sha256_context )
+/** SHA-256 block size */
+#define SHA256_BLOCK_SIZE sizeof ( union sha256_block )
+
/** SHA-256 digest size */
#define SHA256_DIGEST_SIZE sizeof ( struct sha256_digest )
diff --git a/src/include/ipxe/sha512.h b/src/include/ipxe/sha512.h
index 8e22d8357..82a9e4e69 100644
--- a/src/include/ipxe/sha512.h
+++ b/src/include/ipxe/sha512.h
@@ -72,6 +72,9 @@ struct sha512_context {
/** SHA-512 context size */
#define SHA512_CTX_SIZE sizeof ( struct sha512_context )
+/** SHA-512 block size */
+#define SHA512_BLOCK_SIZE sizeof ( union sha512_block )
+
/** SHA-512 digest size */
#define SHA512_DIGEST_SIZE sizeof ( struct sha512_digest )
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h
index 8b03579cc..6d6c82de0 100644
--- a/src/include/ipxe/tls.h
+++ b/src/include/ipxe/tls.h
@@ -23,6 +23,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/iobuf.h>
#include <ipxe/tables.h>
+struct tls_connection;
+
/** A TLS header */
struct tls_header {
/** Content type
@@ -48,6 +50,9 @@ struct tls_header {
/** TLS version 1.2 */
#define TLS_VERSION_TLS_1_2 0x0303
+/** Maximum supported TLS version */
+#define TLS_VERSION_MAX TLS_VERSION_TLS_1_2
+
/** Change cipher content type */
#define TLS_TYPE_CHANGE_CIPHER 20
@@ -140,8 +145,23 @@ enum tls_tx_pending {
TLS_TX_FINISHED = 0x0020,
};
+/** A TLS key exchange algorithm */
+struct tls_key_exchange_algorithm {
+ /** Algorithm name */
+ const char *name;
+ /**
+ * Transmit Client Key Exchange record
+ *
+ * @v tls TLS connection
+ * @ret rc Return status code
+ */
+ int ( * exchange ) ( struct tls_connection *tls );
+};
+
/** A TLS cipher suite */
struct tls_cipher_suite {
+ /** Key exchange algorithm */
+ struct tls_key_exchange_algorithm *exchange;
/** Public-key encryption algorithm */
struct pubkey_algorithm *pubkey;
/** Bulk encryption cipher algorithm */
@@ -209,14 +229,6 @@ struct tls_signature_hash_algorithm {
#define __tls_sig_hash_algorithm \
__table_entry ( TLS_SIG_HASH_ALGORITHMS, 01 )
-/** TLS pre-master secret */
-struct tls_pre_master_secret {
- /** TLS version */
- uint16_t version;
- /** Random data */
- uint8_t random[46];
-} __attribute__ (( packed ));
-
/** TLS client random data */
struct tls_client_random {
/** GMT Unix time */
@@ -309,14 +321,16 @@ struct tls_connection {
struct tls_cipherspec rx_cipherspec;
/** Next RX cipher specification */
struct tls_cipherspec rx_cipherspec_pending;
- /** Premaster secret */
- struct tls_pre_master_secret pre_master_secret;
/** Master secret */
uint8_t master_secret[48];
/** Server random bytes */
uint8_t server_random[32];
/** Client random bytes */
struct tls_client_random client_random;
+ /** Server Key Exchange record (if any) */
+ void *server_key;
+ /** Server Key Exchange record length */
+ size_t server_key_len;
/** MD5+SHA1 context for handshake verification */
uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE];
/** SHA256 context for handshake verification */
@@ -388,6 +402,9 @@ struct tls_connection {
/** RX I/O buffer alignment */
#define TLS_RX_ALIGN 16
+extern struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm;
+extern struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm;
+
extern int add_tls ( struct interface *xfer, const char *name,
struct x509_root *root, struct private_key *key );