aboutsummaryrefslogtreecommitdiffstats
path: root/src/net
Commit message (Collapse)AuthorAgeFilesLines
* [eap] Add support for the MS-CHAPv2 authentication methodMichael Brown2024-02-231-0/+251
| | | | | | | | | | | | | | | | | | | Add support for EAP-MSCHAPv2 (note that this is not the same as PEAP-MSCHAPv2), controllable via the build configuration option EAP_METHOD_MSCHAPV2 in config/general.h. Our model for EAP does not encompass mutual authentication: we will starting sending plaintext packets (e.g. DHCP requests) over the link even before EAP completes, and our only use for an EAP success is to mark the link as unblocked. We therefore ignore the content of the EAP-MSCHAPv2 success request (containing the MS-CHAPv2 authenticator response) and just send back an EAP-MSCHAPv2 success response, so that the EAP authenticator will complete the process and send through the real EAP success packet (which will, in turn, cause us to unblock the link). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eap] Allow MD5-Challenge authentication method to be disabledMichael Brown2024-02-232-82/+124
| | | | | | | | | | | RFC 3748 states that implementations must support the MD5-Challenge method. However, some network environments may wish to disable it as a matter of policy. Allow support for MD5-Challenge to be controllable via the build configuration option EAP_METHOD_MD5 in config/general.h. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eap] Add progress debug messagesMichael Brown2024-02-231-1/+11
| | | | | | | Add debug messages for each EAP Request and Response, and to show the list of methods offered when sending a Nak. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Allow for multiple cross-signed certificate download attemptsMichael Brown2024-02-151-100/+227
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Certificates issued by Let's Encrypt have two options for their chain of trust: the chain can either terminate in the self-signed ISRG Root X1 root certificate, or in an intermediate ISRG Root X1 certificate that is signed in turn by the self-signed DST Root CA X3 root certificate. This is a historical artifact: when Let's Encrypt first launched as a project, the chain ending in DST Root CA X3 was used since existing clients would not have recognised the ISRG Root X1 certificate as a trusted root certificate. The DST Root CA X3 certificate expired in September 2021, and so is no longer trusted by clients (such as iPXE) that validate the expiry times of all certificates in the certificate chain. In order to maintain usability of certificates on older Android devices, the default certificate chain provided by Let's Encrypt still terminates in DST Root CA X3, even though that certificate has now expired. On newer devices which include ISRG Root X1 as a trusted root certificate, the intermediate version of ISRG Root X1 in the certificate chain is ignored and validation is performed as though the chain had terminated in the self-signed ISRG Root X1 root certificate. On older Android devices which do not include ISRG Root X1 as a trusted root certificate, the validation succeeds since Android chooses to ignore expiry times for root certificates and so continues to trust the DST Root CA X3 root certificate. This backwards compatibility hack unfortunately breaks the cross- signing mechanism used by iPXE, which assumes that the certificate chain will always terminate in a non-expired root certificate. Generalise the validator's cross-signed certificate download mechanism to walk up the certificate chain in the event of a failure, attempting to find a replacement cross-signed certificate chain starting from the next level up. This allows the validator to step over the expired (and hence invalidatable) DST Root CA X3 certificate, and instead download the cross-signed version of the ISRG Root X1 certificate. This generalisation also gives us the ability to handle servers that provide a full certificate chain including their root certificate: iPXE will step over the untrusted public root certificate and attempt to find a cross-signed version of it instead. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Add x509_is_self_signed() helper functionMichael Brown2024-02-151-1/+1
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Tidy up error handling flow in tls_send_plaintext()Michael Brown2024-01-311-10/+20
| | | | | | | | | | | | | Coverity reported that tls_send_plaintext() failed to check the return status from tls_generate_random(), which could potentially result in uninitialised random data being used as the block initialisation vector (instead of intentionally random data). Add the missing return status check, and separate out the error handling code paths (since on the successful exit code path there will be no need to free either the plaintext or the ciphertext anyway). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Add support for Ephemeral Elliptic Curve Diffie-Hellman key exchangeMichael Brown2024-01-301-0/+169
| | | | | | | Add support for the Ephemeral Elliptic Curve Diffie-Hellman (ECDHE) key exchange algorithm. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Split out Diffie-Hellman parameter signature verificationMichael Brown2024-01-301-39/+62
| | | | | | | | | | | DHE and ECDHE use essentially the same mechanism for verifying the signature over the Diffie-Hellman parameters, though the format of the parameters is different between the two methods. Split out the verification of the parameter signature so that it may be shared between the DHE and ECDHE key exchange algorithms. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Generate key material after sending ClientKeyExchangeMichael Brown2024-01-301-16/+15
| | | | | | | | | | | | | The construction of the key material for the pending cipher suites from the TLS master secret must happen regardless of which key exchange algorithm is in use, and the key material is not required to send the ClientKeyExchange handshake (which is sent before changing cipher suites). Centralise the call to tls_generate_keys() after performing key exchange via the selected algorithm. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Restructure construction of ClientHello messageMichael Brown2024-01-301-72/+99
| | | | | | | | | Define an individual local structure for each extension and a single structure for the list of extensions. This makes it viable to add extensions such as the Supported Elliptic Curves extension, which must not be present if the list of curves is empty. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [libc] Make static_assert() available via assert.hassertMichael Brown2024-01-161-1/+1
| | | | | | | Expose static_assert() via assert.h and migrate link-time assertions to build-time assertions where possible. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eap] Add support for the MD5-Challenge authentication typeMichael Brown2024-01-101-0/+80
| | | | | | | | | RFC 3748 states that support for MD5-Challenge is mandatory for EAP implementations. The MD5 and CHAP code is already included in the default build since it is required by iSCSI, and so this does not substantially increase the binary size. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eap] Add support for sending an EAP identityMichael Brown2024-01-101-20/+137
| | | | | | | | | | | | | Allow the ${netX/username} setting to be used to specify an EAP identity to be returned in response to a Request-Identity, and provide a mechanism for responding with a NAK to indicate which authentication types we support. If no identity is specified then fall back to the current behaviour of not sending any Request-Identity response, so that switches will time out and switch to MAC Authentication Bypass (MAB) if applicable. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eap] Ignore any received EAP responsesMichael Brown2024-01-101-0/+3
| | | | | | | EAP responses (including our own) may be broadcast by switches but are not of interest to us and can be safely ignored if received. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eapol] Limit number of EAPoL-Start packets transmitted per attemptMichael Brown2023-11-071-0/+8
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eapol] Delay EAPoL-Start while waiting for EAP to completeMichael Brown2023-11-072-41/+46
| | | | | | | | | | | | | | | | EAP exchanges may take a long time to reach a final status, especially when relying upon MAC Authentication Bypass (MAB). Our current behaviour of sending EAPoL-Start every few seconds until a final status is obtained can prevent these exchanges from ever completing. Fix by redefining the EAP supplicant state to allow EAPoL-Start to be suppressed: either temporarily (while waiting for a full EAP exchange to complete, in which case we need to eventually resend EAPoL-Start if the final Success or Failure packet is lost), or permanently (while waiting for the potentially very long MAC Authentication Bypass timeout period). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eapol] Send EAPoL-Start packets to trigger EAP authenticationsupplicantMichael Brown2023-09-191-0/+73
| | | | | | | | | | | | | | | | | | | | | | We have no way to force a link-layer restart in iPXE, and therefore no way to explicitly trigger a restart of EAP authentication. If an iPXE script has performed some action that requires such a restart (e.g. registering a device such that the port VLAN assignment will be changed), then the only means currently available to effect the restart is to reboot the whole system. If iPXE is taking over a physical link already used by a preceding bootloader, then even a reboot may not work. In the EAP model, the supplicant is a pure responder and never initiates transmissions. EAPoL extends this to include an EAPoL-Start packet type that may be sent by the supplicant to (re)trigger EAP. Add support for sending EAPoL-Start packets at two-second intervals on links that are open and have reached physical link-up, but for which EAP has not yet completed. This allows "ifclose ; ifopen" to be used to restart the EAP process. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [eap] Define a supplicant model for EAP and EAPoLMichael Brown2023-09-183-23/+154
| | | | | | | | Extend the EAP model to include a record of whether or not EAP authentication has completed (successfully or otherwise), and to provide a method for transmitting EAP responses. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [fcoe] Use driver-private data to hold FCoE port structureMichael Brown2023-09-141-64/+21
| | | | | | | Simplify the FCoE code by using driver-private data to hold the FCoE port for each network device, instead of using a separate allocation. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [ipv6] Use driver-private data to hold link-local IPv6 settings blockMichael Brown2023-09-131-29/+10
| | | | | | | | Simplify the IPv6 link-local settings code by using driver-private data to hold the settings block, instead of using a separate allocation. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [lldp] Use driver-private data to hold LLDP settings blockMichael Brown2023-09-131-63/+31
| | | | | | | | | | | | | | | | | | | | Simplify the LLDP code by using driver-private data to hold the LLDP settings block, instead of using a separate allocation. This avoids the need to maintain a list of LLDP settings blocks (since the LLDP settings block pointer can always be obtained using netdev_priv()) and obviates several failure paths. Any recorded LLDP data is now freed when the network device is unregistered, since there is no longer a dedicated reference counter for the LLDP settings block. To minimise surprise, we also now explicitly unregister the settings block. This is not strictly necessary (since the block will be automatically unregistered when the parent network device settings block is unregistered), but it maintains symmetry between lldp_probe() and lldp_remove(). The overall reduction in the size of the LLDP code is around 15%. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [netdevice] Allocate private data for each network upper-layer driverMichael Brown2023-09-137-23/+81
| | | | | | | | | | | | | | | | | Allow network upper-layer drivers (such as LLDP, which attaches to each network device in order to provide a corresponding LLDP settings block) to specify a size for private data, which will be allocated as part of the network device structure (as with the existing private data allocated for the underlying device driver). This will allow network upper-layer drivers to be simplified by omitting memory allocation and freeing code. If the upper-layer driver requires a reference counter (e.g. for interface initialisation), then it may use the network device's existing reference counter, since this is now the reference counter for the containing block of memory. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dhcp] Request NTP server optionntpsettingCornelius Hoffmann2023-07-191-3/+4
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [ntp] Define NTP server settingMichael Brown2023-07-191-0/+10
| | | | | | | | | | | Define the IPv4 NTP server setting to simplify the use of a DHCP-provided NTP server in scripts, using e.g. #!ipxe dhcp ntp ${ntp} Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [netdevice] Stop link block timer when device is closedMichael Brown2023-07-051-1/+4
| | | | | | | | | | | | | | | A running link block timer holds a reference to the network device and will prevent it from being freed until the timer expires. It is impossible for free_netdev() to be called while the timer is still running: the call to stop_timer() therein is therefore a no-op. Stop the link block timer when the device is closed, to allow a link-blocked device to be freed immediately upon unregistration of the device. (Since link block state is updated in response to received packets, the state is effectively undefined for a closed device: there is therefore no reason to leave the timer running.) Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Handle fragmented handshake recordsMichael Brown2023-03-301-18/+24
| | | | | Originally-implemented-by: Christopher Schenk <christopher@cschenk.net> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Pass I/O buffer to received record handlersMichael Brown2023-03-301-58/+98
| | | | | | | | Prepare for the possibility that a record handler may choose not to consume the entire record by passing the I/O buffer and requiring the handler to mark consumed data using iob_pull(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Clean up change cipher spec record handlingMichael Brown2023-03-301-4/+15
| | | | | | | Define and use data structures and constants for the (single-byte) change cipher spec records. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dhcp] Unregister ProxyDHCP and PXEBS settings on a successful DHCPACKMichael Brown2023-03-141-0/+6
| | | | | | | | | | | | | | | | | | | | | | When a DHCP transaction does not result in the registration of a new "proxydhcp" or "pxebs" settings block, any existing settings blocks are currently left unaltered. This can cause surprising behaviour. For example: when chainloading iPXE, the "proxydhcp" and "pxebs" settings blocks may be prepopulated using cached values from the previous PXE bootloader. If iPXE performs a subsequent DHCP request, then the DHCP or ProxyDHCP servers may choose to respond differently to iPXE. The response may choose to omit the ProxyDHCP or PXEBS stages, in which case no new "proxydhcp" or "pxebs" settings blocks may be registered. This will result in iPXE using a combination of both old and new DHCP responses. Fix by assuming that a successful DHCPACK effectively acquires ownership of the "proxydhcp" and "pxebs" settings blocks, and that any existing settings blocks should therefore be unregistered. Reported-by: Henry Tung <htung@palantir.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [params] Allow for arbitrary HTTP request headers to be specifiedMichael Brown2023-03-011-9/+34
| | | | | | | | | | | Extend the request parameter mechanism to allow for arbitrary HTTP headers to be specified via e.g.: params param --header Referer http://www.example.com imgfetch http://192.168.0.1/script.ipxe##params Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [http] Use POST method only if the form parameter list is non-emptyMichael Brown2023-03-011-44/+32
| | | | | | | | | | | | | An attempt to use an existent but empty form parameter list will currently result in an invalid POST request since the Content-Length header will be missing. Fix by using GET instead of POST if the form parameter list is empty. This is a non-breaking change (since the current behaviour produces an invalid request), and simplifies the imminent generalisation of the parameter list concept to handle both header and form parameters. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [iscsi] Limit maximum transfer size to MaxBurstLengthiscsicapMichael Brown2023-02-161-4/+61
| | | | | | | | | | | | | | | | | We currently specify only the iSCSI default value for MaxBurstLength and ignore any negotiated value, since our internal block device API allows only for receiving directly into caller-allocated buffers and so we have no intrinsic limit on burst length. A conscientious target may however refuse to attempt a transfer that we request for a number of blocks that would exceed the negotiated maximum burst length. Fix by recording the negotiated maximum burst length and using it to limit the maximum number of blocks per transfer as reported by the SCSI layer. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [lldp] Add support for the Link Layer Discovery ProtocollldpMichael Brown2023-02-051-0/+340
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add support for recording LLDP packets and exposing TLV values via the settings mechanism. LLDP settings are encoded as ${netX.lldp/<prefix>.<type>.<index>.<offset>.<length>} where <type> is the TLV type <offset> is the starting offset within the TLV value <length> is the length (or zero to read the from <offset> to the end) <prefix>, if it has a non-zero value, is the subtype byte string of length <offset> to match at the start of the TLV value, up to a maximum matched length of 4 bytes <index> is the index of the entry matching <type> and <prefix> to be accessed, with zero indicating the first matching entry The <prefix> is designed to accommodate both matching of the OUI within an organization-specific TLV (e.g. 0x0080c2 for IEEE 802.1 TLVs) and of a subtype byte as found within many TLVs. This encoding allows most LLDP values to be extracted easily. For example System name: ${netX.lldp/5.0.0.0:string} System description: ${netX.lldp/6.0.0.0:string} Port description: ${netX.lldp/4.0.0.0:string} Port interface name: ${netX.lldp/5.2.0.1.0:string} Chassis MAC address: ${netX.lldp/4.1.0.1.0:hex} Management IPv4 address: ${netX.lldp/5.1.8.0.2.4:ipv4} Port VLAN ID: ${netX.lldp/0x0080c2.1.127.0.4.2:int16} Port VLAN name: ${netX.lldp/0x0080c2.3.127.0.7.0:string} Maximum frame size: ${netX.lldp/0x00120f.4.127.0.4.2:uint16} Originally-implemented-by: Marin Hannache <git@mareo.fr> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dhcp] Ignore DHCPNAK unless originating from the selected DHCP serverMichael Brown2023-02-031-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | RFC 2131 leaves undefined the behaviour of the client in response to a DHCPNAK that comes from a server other than the selected DHCP server. A substantial amount of online documentation suggests using multiple independent DHCP servers with non-overlapping ranges in the same subnet in order to provide some minimal redundancy. Experimentation shows that in this setup, at least ISC dhcpd will send a DHCPNAK in response to the client's DHCPREQUEST for an address that is not within the range defined on that server. (Since the requested address does lie within the subnet defined on that server, this will happen regardless of the "authoritative" parameter.) The client will therefore receive a DHCPACK from the selected DHCP server along with one or more DHCPNAKs from each of the non-selected DHCP servers. Filter out responses from non-selected DHCP servers before checking for a DHCPNAK, so that these arguably spurious DHCPNAKs will not cause iPXE to return to the discovery state. Continue to check for DHCPNAK before filtering out responses for non-selected lease addresses, since experimentation shows that the DHCPNAK will usually have an empty yiaddr field. Reported-by: Anders Blomdell <anders.blomdell@control.lth.se> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dhcp] Simplify platform-specific client architecture definitionsMichael Brown2023-01-222-2/+2
| | | | | | | | | | | | | | | | Move the platform-specific DHCP client architecture definitions to header files of the form <ipxe/$(PLATFORM)/dhcparch.h>. This simplifies the directory structure and allows the otherwise unused arch/$(ARCH)/include/$(PLATFORM) to be removed from the include directory search path, which avoids the confusing situation in which a header file may potentially be accessed through more than one path. For Linux userspace binaries on any architecture, use the EFI values for that architecture by delegating to the EFI header file. This avoids the need to explicitly select values for Linux userspace binaries for each architecture. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [netdevice] Ensure consistent interpretation of "netX" device nameMichael Brown2023-01-171-2/+2
| | | | | | | | Ensure that the "${netX/...}" settings mechanism always uses the same interpretation of the network device corresponding to "netX" as any other mechanism that performs a name-based lookup of a network device. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [vlan] Support automatic VLAN device creationMichael Brown2023-01-151-0/+48
| | | | | | | Add the ability to automatically create a VLAN device for a specified trunk device link-layer address and VLAN tag. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [netdevice] Allow duplicate MAC addressesMichael Brown2023-01-151-33/+0
| | | | | | | | | | | | | | | | | | | | | | | | Many laptops now include the ability to specify a "system-specific MAC address" (also known as "pass-through MAC"), which is supposed to be used for both the onboard NIC and for any attached docking station or other USB NIC. This is intended to simplify interoperability with software or hardware that relies on a MAC address to recognise an individual machine: for example, a deployment server may associate the MAC address with a particular operating system image to be deployed. This therefore creates legitimate situations in which duplicate MAC addresses may exist within the same system. As described in commit 98d09a1 ("[netdevice] Avoid registering duplicate network devices"), the Xen netfront driver relies on the rejection of duplicate MAC addresses in order to inhibit registration of the emulated PCI devices that a Xen PV-HVM guest will create to shadow each of the paravirtual network devices. Move the code that rejects duplicate MAC addresses from the network device core to the Xen netfront driver, to allow for the existence of duplicate MAC addresses in non-Xen setups. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [netdevice] Separate concept of scope ID from network device name indexMichael Brown2023-01-146-25/+28
| | | | | | | | | | | | | | | | | | | | | The network device index currently serves two purposes: acting as a sequential index for network device names ("net0", "net1", etc), and acting as an opaque unique integer identifier used in socket address scope IDs. There is no particular need for these usages to be linked, and it can lead to situations in which devices are named unexpectedly. For example: if a system has two network devices "net0" and "net1", a VLAN is created as "net1-42", and then a USB NIC is connected, then the USB NIC will be named "net3" rather than the expected "net2" since the VLAN device "net1-42" will have consumed an index. Separate the usages: rename the "index" field to "scope_id" (matching its one and only use case), and assign the name without reference to the scope ID by finding the first unused name. For consistency, assign the scope ID by similarly finding the first unused scope ID. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Provide VLAN configuration protocolMichael Brown2022-12-141-2/+1
| | | | | | | | | | | | | | | | | | | | | | | UEFI implements VLAN support within the Managed Network Protocol (MNP) driver, which may create child VLAN devices automatically based on stored UEFI variables. These child devices do not themselves provide a raw-packet interface via EFI_SIMPLE_NETWORK_PROTOCOL, and may be consumed only via the EFI_MANAGED_NETWORK_PROTOCOL interface. The device paths constructed for these child devices may conflict with those for the EFI_SIMPLE_NETWORK_PROTOCOL instances that iPXE attempts to install for its own VLAN devices. The upshot is that creating an iPXE VLAN device (e.g. via the "vcreate" command) will fail if the UEFI Managed Network Protocol has already created a device for the same VLAN tag. Fix by providing our own EFI_VLAN_CONFIG_PROTOCOL instance on the same device handle as EFI_SIMPLE_NETWORK_PROTOCOL. This causes the MNP driver to treat iPXE's device as supporting hardware VLAN offload, and it will therefore not attempt to install its own instance of the protocol. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [vlan] Allow external code to identify VLAN priority as well as tagMichael Brown2022-12-142-6/+6
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Allow handshake digest algorithm to be specified by cipher suiteMichael Brown2022-11-091-63/+114
| | | | | | | | | | | | | | | | | | | All existing cipher suites use SHA-256 as the TLSv1.2 and above handshake digest algorithm (even when using SHA-1 as the MAC digest algorithm). Some GCM cipher suites use SHA-384 as the handshake digest algorithm. Allow the cipher suite to specify the handshake (and PRF) digest algorithm to be used for TLSv1.2 and above. This requires some restructuring to allow for the fact that the ClientHello message must be included within the handshake digest, even though the relevant digest algorithm is not yet known at the point that the ClientHello is sent. Fortunately, the ClientHello may be reproduced verbatim at the point of receiving the ServerHello, so we rely on reconstructing (rather than storing) this message. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Always send maximum supported version in ClientHelloMichael Brown2022-11-091-1/+1
| | | | | | | | | | | | Always send the maximum supported version in our ClientHello message, even when performing renegotiation (in which case the current version may already be lower than the maximum supported version). This is permitted by the specification, and allows the ClientHello to be reconstructed verbatim at the point of selecting the handshake digest algorithm in tls_new_server_hello(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Add support for AEAD ciphersMichael Brown2022-11-081-2/+39
| | | | | | | | Allow for AEAD cipher suites where the MAC length may be zero and the authentication is instead provided by an authenticating cipher, with the plaintext authentication tag appended to the ciphertext. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Treat invalid block padding as zero length paddingMichael Brown2022-11-081-2/+2
| | | | | | | | Harden against padding oracle attacks by treating invalid block padding as zero length padding, thereby deferring the failure until after computing the (incorrect) MAC. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Allow for arbitrary-length initialisation vectorsMichael Brown2022-11-081-186/+144
| | | | | | | | | Restructure the encryption and decryption operations to allow for the use of ciphers where the initialisation vector is constructed by concatenating the fixed IV (derived as part of key expansion) with a record IV (prepended to the ciphertext). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Add MAC length as a cipher suite parameterMichael Brown2022-11-081-16/+18
| | | | | | | | | | | | | | | TLS stream and block ciphers use a MAC with a length equal to the output length of the digest algorithm in use. For AEAD ciphers there is no MAC, with the equivalent functionality provided by the cipher algorithm's authentication tag. Allow for the existence of AEAD cipher suites by making the MAC length a parameter of the cipher suite. Assume that the MAC key length is equal to the MAC length, since this is true for all currently supported cipher suites. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Abstract out concept of a TLS authentication headerMichael Brown2022-11-081-21/+19
| | | | | | | | | | | | | All TLS cipher types use a common structure for the per-record data that is authenticated in addition to the plaintext itself. This data is used as a prefix in the HMAC calculation for stream and block ciphers, or as additional authenticated data for AEAD ciphers. Define a "TLS authentication header" structure to hold this data as a contiguous block, in order to meet the alignment requirement for AEAD ciphers such as GCM. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Ensure cipher alignment size is respectedMichael Brown2022-11-071-0/+18
| | | | | | | | Adjust the length of the first received ciphertext data buffer to ensure that all decryption operations respect the cipher's alignment size. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [tls] Formalise notions of fixed and record initialisation vectorsMichael Brown2022-11-071-3/+24
| | | | | | | | | | | | | | | | | | | | | TLS block ciphers always use CBC (as per RFC 5246 section 6.2.3.2) with a record initialisation vector length that is equal to the cipher block size, and no fixed initialisation vector. The initialisation vector for AEAD ciphers such as GCM is less straightforward, and requires both a fixed and per-record component. Extend the definition of a cipher suite to include fixed and record initialisation vector lengths, and generate the fixed portion (if any) as part of key expansion. Do not add explicit calls to cipher_setiv() in tls_assemble_block() and tls_split_block(), since the constraints imposed by RFC 5246 are specifically chosen to allow implementations to avoid doing so. (Instead, add a sanity check that the record initialisation vector length is equal to the cipher block size.) Signed-off-by: Michael Brown <mcb30@ipxe.org>