diff options
Diffstat (limited to 'src/include/ipxe')
40 files changed, 1149 insertions, 132 deletions
diff --git a/src/include/ipxe/asn1.h b/src/include/ipxe/asn1.h index 77429f3a..ac7ea560 100644 --- a/src/include/ipxe/asn1.h +++ b/src/include/ipxe/asn1.h @@ -187,6 +187,11 @@ struct asn1_builder_header { ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 2 ), \ ASN1_OID_SINGLE ( 26 ) +/** ASN.1 OID for id-x25519 (1.3.101.110) */ +#define ASN1_OID_X25519 \ + ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 101 ), \ + ASN1_OID_SINGLE ( 110 ) + /** ASN.1 OID for id-sha256 (2.16.840.1.101.3.4.2.1) */ #define ASN1_OID_SHA256 \ ASN1_OID_INITIAL ( 2, 16 ), ASN1_OID_DOUBLE ( 840 ), \ @@ -312,6 +317,8 @@ struct asn1_algorithm { struct pubkey_algorithm *pubkey; /** Digest algorithm (if applicable) */ struct digest_algorithm *digest; + /** Elliptic curve (if applicable) */ + struct elliptic_curve *curve; }; /** ASN.1 OID-identified algorithms */ @@ -390,10 +397,9 @@ asn1_built ( struct asn1_builder *builder ) { } *u = container_of ( builder, typeof ( *u ), builder ); /* Sanity check */ - linker_assert ( ( ( const void * ) &u->builder.data ) == - &u->cursor.data, asn1_builder_cursor_data_mismatch ); - linker_assert ( &u->builder.len == &u->cursor.len, - asn1_builder_cursor_len_mismatch ); + build_assert ( ( ( const void * ) &u->builder.data ) == + &u->cursor.data ); + build_assert ( &u->builder.len == &u->cursor.len ); return &u->cursor; } diff --git a/src/include/ipxe/base16.h b/src/include/ipxe/base16.h index 8c44da17..c9e430e7 100644 --- a/src/include/ipxe/base16.h +++ b/src/include/ipxe/base16.h @@ -12,6 +12,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <string.h> +/** Treat separator as optional while decoding */ +#define HEX_DECODE_OPTIONAL 0x80 + /** * Calculate length of base16-encoded data * diff --git a/src/include/ipxe/bigint.h b/src/include/ipxe/bigint.h index 2f99f844..3dc344df 100644 --- a/src/include/ipxe/bigint.h +++ b/src/include/ipxe/bigint.h @@ -8,6 +8,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +#include <assert.h> + /** * Define a big-integer type * @@ -177,6 +179,30 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); } while ( 0 ) /** + * Copy big integer + * + * @v source Source big integer + * @v dest Destination big integer + */ +#define bigint_copy( source, dest ) do { \ + build_assert ( sizeof ( *(source) ) == sizeof ( *(dest) ) ); \ + bigint_shrink ( (source), (dest) ); \ + } while ( 0 ) + +/** + * Conditionally swap big integers (in constant time) + * + * @v first Big integer to be conditionally swapped + * @v second Big integer to be conditionally swapped + * @v swap Swap first and second big integers + */ +#define bigint_swap( first, second, swap ) do { \ + unsigned int size = bigint_size (first); \ + bigint_swap_raw ( (first)->element, (second)->element, size, \ + (swap) ); \ + } while ( 0 ) + +/** * Multiply big integers * * @v multiplicand Big integer to be multiplied @@ -184,10 +210,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @v result Big integer to hold result */ #define bigint_multiply( multiplicand, multiplier, result ) do { \ - unsigned int size = bigint_size (multiplicand); \ + unsigned int multiplicand_size = bigint_size (multiplicand); \ + unsigned int multiplier_size = bigint_size (multiplier); \ bigint_multiply_raw ( (multiplicand)->element, \ - (multiplier)->element, (result)->element, \ - size ); \ + multiplicand_size, (multiplier)->element, \ + multiplier_size, (result)->element ); \ } while ( 0 ) /** @@ -282,10 +309,13 @@ void bigint_grow_raw ( const bigint_element_t *source0, void bigint_shrink_raw ( const bigint_element_t *source0, unsigned int source_size, bigint_element_t *dest0, unsigned int dest_size ); +void bigint_swap_raw ( bigint_element_t *first0, bigint_element_t *second0, + unsigned int size, int swap ); void bigint_multiply_raw ( const bigint_element_t *multiplicand0, + unsigned int multiplicand_size, const bigint_element_t *multiplier0, - bigint_element_t *result0, - unsigned int size ); + unsigned int multiplier_size, + bigint_element_t *result0 ); void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0, const bigint_element_t *multiplier0, const bigint_element_t *modulus0, diff --git a/src/include/ipxe/cbc.h b/src/include/ipxe/cbc.h index 382fc903..f02e5193 100644 --- a/src/include/ipxe/cbc.h +++ b/src/include/ipxe/cbc.h @@ -77,19 +77,19 @@ static void _cbc_name ## _setiv ( void *ctx, const void *iv, \ size_t ivlen ) { \ struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \ cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv, ivlen, \ - &_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \ + &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx ); \ } \ static void _cbc_name ## _encrypt ( void *ctx, const void *src, \ void *dst, size_t len ) { \ struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \ cbc_encrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len, \ - &_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \ + &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx ); \ } \ static void _cbc_name ## _decrypt ( void *ctx, const void *src, \ void *dst, size_t len ) { \ struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \ cbc_decrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len, \ - &_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \ + &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx ); \ } \ struct cipher_algorithm _cbc_cipher = { \ .name = #_cbc_name, \ diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h index a15d5eba..a6f43765 100644 --- a/src/include/ipxe/crypto.h +++ b/src/include/ipxe/crypto.h @@ -195,34 +195,54 @@ struct pubkey_algorithm { const void *public_key, size_t public_key_len ); }; -static inline void digest_init ( struct digest_algorithm *digest, - void *ctx ) { +/** An elliptic curve */ +struct elliptic_curve { + /** Curve name */ + const char *name; + /** Key size */ + size_t keysize; + /** Multiply scalar by curve point + * + * @v base Base point (or NULL to use generator) + * @v scalar Scalar multiple + * @v result Result point to fill in + * @ret rc Return status code + */ + int ( * multiply ) ( const void *base, const void *scalar, + void *result ); +}; + +static inline __attribute__ (( always_inline )) void +digest_init ( struct digest_algorithm *digest, void *ctx ) { digest->init ( ctx ); } -static inline void digest_update ( struct digest_algorithm *digest, - void *ctx, const void *data, size_t len ) { +static inline __attribute__ (( always_inline )) void +digest_update ( struct digest_algorithm *digest, void *ctx, + const void *data, size_t len ) { digest->update ( ctx, data, len ); } -static inline void digest_final ( struct digest_algorithm *digest, - void *ctx, void *out ) { +static inline __attribute__ (( always_inline )) void +digest_final ( struct digest_algorithm *digest, void *ctx, void *out ) { digest->final ( ctx, out ); } -static inline int cipher_setkey ( struct cipher_algorithm *cipher, - void *ctx, const void *key, size_t keylen ) { +static inline __attribute__ (( always_inline )) int +cipher_setkey ( struct cipher_algorithm *cipher, void *ctx, + const void *key, size_t keylen ) { return cipher->setkey ( ctx, key, keylen ); } -static inline void cipher_setiv ( struct cipher_algorithm *cipher, - void *ctx, const void *iv, size_t ivlen ) { +static inline __attribute__ (( always_inline )) void +cipher_setiv ( struct cipher_algorithm *cipher, void *ctx, + const void *iv, size_t ivlen ) { cipher->setiv ( ctx, iv, ivlen ); } -static inline void cipher_encrypt ( struct cipher_algorithm *cipher, - void *ctx, const void *src, void *dst, - size_t len ) { +static inline __attribute__ (( always_inline )) void +cipher_encrypt ( struct cipher_algorithm *cipher, void *ctx, + const void *src, void *dst, size_t len ) { cipher->encrypt ( ctx, src, dst, len ); } #define cipher_encrypt( cipher, ctx, src, dst, len ) do { \ @@ -230,9 +250,9 @@ static inline void cipher_encrypt ( struct cipher_algorithm *cipher, cipher_encrypt ( (cipher), (ctx), (src), (dst), (len) ); \ } while ( 0 ) -static inline void cipher_decrypt ( struct cipher_algorithm *cipher, - void *ctx, const void *src, void *dst, - size_t len ) { +static inline __attribute__ (( always_inline )) void +cipher_decrypt ( struct cipher_algorithm *cipher, void *ctx, + const void *src, void *dst, size_t len ) { cipher->decrypt ( ctx, src, dst, len ); } #define cipher_decrypt( cipher, ctx, src, dst, len ) do { \ @@ -240,68 +260,82 @@ static inline void cipher_decrypt ( struct cipher_algorithm *cipher, cipher_decrypt ( (cipher), (ctx), (src), (dst), (len) ); \ } while ( 0 ) -static inline void cipher_auth ( struct cipher_algorithm *cipher, void *ctx, - void *auth ) { +static inline __attribute__ (( always_inline )) void +cipher_auth ( struct cipher_algorithm *cipher, void *ctx, void *auth ) { cipher->auth ( ctx, auth ); } -static inline int is_stream_cipher ( struct cipher_algorithm *cipher ) { +static inline __attribute__ (( always_inline )) int +is_stream_cipher ( struct cipher_algorithm *cipher ) { return ( cipher->blocksize == 1 ); } -static inline int is_block_cipher ( struct cipher_algorithm *cipher ) { +static inline __attribute__ (( always_inline )) int +is_block_cipher ( struct cipher_algorithm *cipher ) { return ( cipher->blocksize > 1 ); } -static inline int is_auth_cipher ( struct cipher_algorithm *cipher ) { +static inline __attribute__ (( always_inline )) int +is_auth_cipher ( struct cipher_algorithm *cipher ) { return cipher->authsize; } -static inline int pubkey_init ( struct pubkey_algorithm *pubkey, void *ctx, - const void *key, size_t key_len ) { +static inline __attribute__ (( always_inline )) int +pubkey_init ( struct pubkey_algorithm *pubkey, void *ctx, + const void *key, size_t key_len ) { return pubkey->init ( ctx, key, key_len ); } -static inline size_t pubkey_max_len ( struct pubkey_algorithm *pubkey, - void *ctx ) { +static inline __attribute__ (( always_inline )) size_t +pubkey_max_len ( struct pubkey_algorithm *pubkey, void *ctx ) { return pubkey->max_len ( ctx ); } -static inline int pubkey_encrypt ( struct pubkey_algorithm *pubkey, void *ctx, - const void *data, size_t len, void *out ) { +static inline __attribute__ (( always_inline )) int +pubkey_encrypt ( struct pubkey_algorithm *pubkey, void *ctx, + const void *data, size_t len, void *out ) { return pubkey->encrypt ( ctx, data, len, out ); } -static inline int pubkey_decrypt ( struct pubkey_algorithm *pubkey, void *ctx, - const void *data, size_t len, void *out ) { +static inline __attribute__ (( always_inline )) int +pubkey_decrypt ( struct pubkey_algorithm *pubkey, void *ctx, + const void *data, size_t len, void *out ) { return pubkey->decrypt ( ctx, data, len, out ); } -static inline int pubkey_sign ( struct pubkey_algorithm *pubkey, void *ctx, - struct digest_algorithm *digest, - const void *value, void *signature ) { +static inline __attribute__ (( always_inline )) int +pubkey_sign ( struct pubkey_algorithm *pubkey, void *ctx, + struct digest_algorithm *digest, const void *value, + void *signature ) { return pubkey->sign ( ctx, digest, value, signature ); } -static inline int pubkey_verify ( struct pubkey_algorithm *pubkey, void *ctx, - struct digest_algorithm *digest, - const void *value, const void *signature, - size_t signature_len ) { +static inline __attribute__ (( always_inline )) int +pubkey_verify ( struct pubkey_algorithm *pubkey, void *ctx, + struct digest_algorithm *digest, const void *value, + const void *signature, size_t signature_len ) { return pubkey->verify ( ctx, digest, value, signature, signature_len ); } -static inline void pubkey_final ( struct pubkey_algorithm *pubkey, void *ctx ) { +static inline __attribute__ (( always_inline )) void +pubkey_final ( struct pubkey_algorithm *pubkey, void *ctx ) { pubkey->final ( ctx ); } -static inline int pubkey_match ( struct pubkey_algorithm *pubkey, - const void *private_key, - size_t private_key_len, const void *public_key, - size_t public_key_len ) { +static inline __attribute__ (( always_inline )) int +pubkey_match ( struct pubkey_algorithm *pubkey, + const void *private_key, size_t private_key_len, + const void *public_key, size_t public_key_len ) { return pubkey->match ( private_key, private_key_len, public_key, public_key_len ); } +static inline __attribute__ (( always_inline )) int +elliptic_multiply ( struct elliptic_curve *curve, + const void *base, const void *scalar, void *result ) { + return curve->multiply ( base, scalar, result ); +} + extern void digest_null_init ( void *ctx ); extern void digest_null_update ( void *ctx, const void *src, size_t len ); extern void digest_null_final ( void *ctx, void *out ); diff --git a/src/include/ipxe/des.h b/src/include/ipxe/des.h new file mode 100644 index 00000000..755a90ea --- /dev/null +++ b/src/include/ipxe/des.h @@ -0,0 +1,91 @@ +#ifndef _IPXE_DES_H +#define _IPXE_DES_H + +/** @file + * + * DES algorithm + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <ipxe/crypto.h> + +/** A DES 32-bit dword value + * + * DES views data as 64-bit big-endian values, typically handled as a + * most-significant "left" half and a least-significant "right" half. + */ +union des_dword { + /** Raw bytes */ + uint8_t byte[4]; + /** 32-bit big-endian dword */ + uint32_t dword; +}; + +/** A DES 64-bit block */ +union des_block { + /** Raw bytes */ + uint8_t byte[8]; + /** 32-bit big-endian dwords */ + uint32_t dword[2]; + /** Named left and right halves */ + struct { + /** Left (most significant) half */ + union des_dword left; + /** Right (least significant) half */ + union des_dword right; + }; + /** Named "C" and "D" halves */ + struct { + /** "C" (most significant) half */ + union des_dword c; + /** "D" (least significant) half */ + union des_dword d; + }; +}; + +/** DES blocksize */ +#define DES_BLOCKSIZE sizeof ( union des_block ) + +/** A DES round key + * + * A DES round key is a 48-bit value, consumed as 8 groups of 6 bits. + * We store these as 8 separate bytes, for simplicity of consumption. + */ +union des_round_key { + /** Raw bytes */ + uint8_t byte[8]; + /** 32-bit big-endian dwords */ + uint32_t dword[2]; + /** 6-bit step key byte + * + * There are 8 steps within a DES round (one step per S-box). + * Each step requires six bits of the round key. + * + * As an optimisation, we store the least significant of the 6 + * bits in the sign bit of a signed 8-bit value, and the + * remaining 5 bits in the least significant 5 bits of the + * 8-bit value. See the comments in des_sbox() for further + * details. + */ + int8_t step[8]; +}; + +/** Number of DES rounds */ +#define DES_ROUNDS 16 + +/** DES context */ +struct des_context { + /** Round keys */ + union des_round_key rkey[DES_ROUNDS]; +}; + +/** DES context size */ +#define DES_CTX_SIZE sizeof ( struct des_context ) + +extern struct cipher_algorithm des_algorithm; +extern struct cipher_algorithm des_ecb_algorithm; +extern struct cipher_algorithm des_cbc_algorithm; + +#endif /* _IPXE_DES_H */ diff --git a/src/include/ipxe/eap.h b/src/include/ipxe/eap.h index e5f60655..a44f01e0 100644 --- a/src/include/ipxe/eap.h +++ b/src/include/ipxe/eap.h @@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <ipxe/netdevice.h> #include <ipxe/timer.h> +#include <ipxe/tables.h> /** EAP header */ struct eap_header { @@ -26,17 +27,68 @@ struct eap_header { /** EAP request */ #define EAP_CODE_REQUEST 1 -/** EAP request */ -struct eap_request { +/** EAP response */ +#define EAP_CODE_RESPONSE 2 + +/** EAP request/response message */ +struct eap_message { /** Header */ struct eap_header hdr; /** Type */ uint8_t type; + /** Type data */ + uint8_t data[0]; } __attribute__ (( packed )); +/** EAP "no available types" marker */ +#define EAP_TYPE_NONE 0 + /** EAP identity */ #define EAP_TYPE_IDENTITY 1 +/** EAP NAK */ +#define EAP_TYPE_NAK 3 + +/** EAP MD5 challenge request/response */ +#define EAP_TYPE_MD5 4 + +/** EAP MD5 challenge request/response type data */ +struct eap_md5 { + /** Value length */ + uint8_t len; + /** Value */ + uint8_t value[0]; +} __attribute__ (( packed )); + +/** EAP MS-CHAPv2 request/response */ +#define EAP_TYPE_MSCHAPV2 26 + +/** EAP MS-CHAPv2 request/response type data */ +struct eap_mschapv2 { + /** Code + * + * This is in the same namespace as the EAP header's code + * field, but is used to extend the handshake by allowing for + * "success request" and "success response" packets. + */ + uint8_t code; + /** Identifier + * + * This field serves no purposes: it always has the same value + * as the EAP header's identifier field (located 5 bytes + * earlier in the same packet). + */ + uint8_t id; + /** Length + * + * This field serves no purpose: it always has the same value + * as the EAP header's length field (located 5 bytes earlier + * in the same packet), minus the 5 byte length of the EAP + * header. + */ + uint16_t len; +} __attribute__ (( packed )); + /** EAP success */ #define EAP_CODE_SUCCESS 3 @@ -47,11 +99,11 @@ struct eap_request { union eap_packet { /** Header */ struct eap_header hdr; - /** Request */ - struct eap_request req; + /** Request/response message */ + struct eap_message msg; }; -/** Link block timeout +/** EAP link block timeout * * We mark the link as blocked upon receiving a Request-Identity, on * the basis that this most likely indicates that the switch will not @@ -64,12 +116,34 @@ union eap_packet { */ #define EAP_BLOCK_TIMEOUT ( 45 * TICKS_PER_SEC ) +/** EAP protocol wait timeout + * + * In the EAP model, the supplicant is a pure responder. The model + * also defines no acknowledgement response for the final Success or + * Failure "requests". This leaves open the possibility that the + * final Success or Failure packet is lost, with the supplicant having + * no way to determine the final authentication status. + * + * Sideband mechanisms such as EAPoL-Start may be used to restart the + * entire EAP process, as a (crude) workaround for this protocol flaw. + * When expecting to receive a further EAP request (e.g. an + * authentication challenge), we may wait for some length of time + * before triggering this restart. Choose a duration that is shorter + * than the link block timeout, so that there is no period during + * which we erroneously leave the link marked as not blocked. + */ +#define EAP_WAIT_TIMEOUT ( EAP_BLOCK_TIMEOUT * 7 / 8 ) + /** An EAP supplicant */ struct eap_supplicant { /** Network device */ struct net_device *netdev; - /** Authentication outcome is final */ - int done; + /** Flags */ + uint16_t flags; + /** ID for current request/response */ + uint8_t id; + /** Type for current request/response */ + uint8_t type; /** * Transmit EAP response * @@ -82,6 +156,47 @@ struct eap_supplicant { const void *data, size_t len ); }; +/** EAP authentication is in progress + * + * This indicates that we have received an EAP Request-Identity, but + * have not yet received a final EAP Success or EAP Failure. + */ +#define EAP_FL_ONGOING 0x0001 + +/** EAP supplicant is passive + * + * This indicates that the supplicant should not transmit any futher + * unsolicited packets (e.g. EAPoL-Start for a supplicant running over + * EAPoL). This could be because authentication has already + * completed, or because we are relying upon MAC Authentication Bypass + * (MAB) which may have a very long timeout. + */ +#define EAP_FL_PASSIVE 0x0002 + +/** An EAP method */ +struct eap_method { + /** Type */ + uint8_t type; + /** + * Handle EAP request + * + * @v supplicant EAP supplicant + * @v req Request type data + * @v req_len Length of request type data + * @ret rc Return status code + */ + int ( * rx ) ( struct eap_supplicant *supplicant, + const void *req, size_t req_len ); +}; + +/** EAP method table */ +#define EAP_METHODS __table ( struct eap_method, "eap_methods" ) + +/** Declare an EAP method */ +#define __eap_method __table_entry ( EAP_METHODS, 01 ) + +extern int eap_tx_response ( struct eap_supplicant *supplicant, + const void *rsp, size_t rsp_len ); extern int eap_rx ( struct eap_supplicant *supplicant, const void *data, size_t len ); diff --git a/src/include/ipxe/eapol.h b/src/include/ipxe/eapol.h index d4ea3920..dcf39294 100644 --- a/src/include/ipxe/eapol.h +++ b/src/include/ipxe/eapol.h @@ -42,11 +42,16 @@ struct eapol_supplicant { struct eap_supplicant eap; /** EAPoL-Start retransmission timer */ struct retry_timer timer; + /** EAPoL-Start transmission count */ + unsigned int count; }; /** Delay between EAPoL-Start packets */ #define EAPOL_START_INTERVAL ( 2 * TICKS_PER_SEC ) +/** Maximum number of EAPoL-Start packets to transmit */ +#define EAPOL_START_COUNT 3 + /** An EAPoL handler */ struct eapol_handler { /** Type */ diff --git a/src/include/ipxe/ecam.h b/src/include/ipxe/ecam.h index 683d613a..ff08aee5 100644 --- a/src/include/ipxe/ecam.h +++ b/src/include/ipxe/ecam.h @@ -50,6 +50,8 @@ struct ecam_mapping { struct pci_range range; /** MMIO base address */ void *regs; + /** Mapping result */ + int rc; }; extern struct pci_api ecam_api; diff --git a/src/include/ipxe/efi/Base.h b/src/include/ipxe/efi/Base.h index e76013c1..46c31a3b 100644 --- a/src/include/ipxe/efi/Base.h +++ b/src/include/ipxe/efi/Base.h @@ -1232,6 +1232,11 @@ typedef UINTN RETURN_STATUS; #define RETURN_COMPROMISED_DATA ENCODE_ERROR (33) /// +/// There is an address conflict address allocation. +/// +#define RETURN_IP_ADDRESS_CONFLICT ENCODE_ERROR (34) + +/// /// A HTTP error occurred during the network operation. /// #define RETURN_HTTP_ERROR ENCODE_ERROR (35) @@ -1270,6 +1275,11 @@ typedef UINTN RETURN_STATUS; /// #define RETURN_WARN_FILE_SYSTEM ENCODE_WARNING (6) +/// +/// The operation will be processed across a system reset. +/// +#define RETURN_WARN_RESET_REQUIRED ENCODE_WARNING (7) + /** Returns a 16-bit signature built from 2 ASCII characters. diff --git a/src/include/ipxe/efi/Guid/FileInfo.h b/src/include/ipxe/efi/Guid/FileInfo.h index 4fc9e860..62c5f4c0 100644 --- a/src/include/ipxe/efi/Guid/FileInfo.h +++ b/src/include/ipxe/efi/Guid/FileInfo.h @@ -49,6 +49,7 @@ typedef struct { UINT64 Attribute; /// /// The Null-terminated name of the file. + /// For a root directory, the name is an empty string. /// CHAR16 FileName[1]; } EFI_FILE_INFO; diff --git a/src/include/ipxe/efi/IndustryStandard/Acpi30.h b/src/include/ipxe/efi/IndustryStandard/Acpi30.h index c7dfd5c7..ff82bf20 100644 --- a/src/include/ipxe/efi/IndustryStandard/Acpi30.h +++ b/src/include/ipxe/efi/IndustryStandard/Acpi30.h @@ -19,6 +19,20 @@ FILE_LICENCE ( BSD2_PATENT ); #define ACPI_EXTENDED_ADDRESS_SPACE_DESCRIPTOR 0x8B +/// +/// C-state Coordination Types +/// See s8.4.2.2 _CSD (C-State Dependency) +/// +#define ACPI_AML_COORD_TYPE_SW_ALL 0xFC +#define ACPI_AML_COORD_TYPE_SW_ANY 0xFD +#define ACPI_AML_COORD_TYPE_HW_ALL 0xFE + +/// +/// _PSD Revision for ACPI 3.0 +// See s8.4.4.5 _PSD (P-State Dependency) +/// +#define EFI_ACPI_3_0_AML_PSD_REVISION 0 + // // Ensure proper structure formats // diff --git a/src/include/ipxe/efi/IndustryStandard/Acpi40.h b/src/include/ipxe/efi/IndustryStandard/Acpi40.h index f6c70d74..97b81703 100644 --- a/src/include/ipxe/efi/IndustryStandard/Acpi40.h +++ b/src/include/ipxe/efi/IndustryStandard/Acpi40.h @@ -12,6 +12,11 @@ FILE_LICENCE ( BSD2_PATENT ); #include <ipxe/efi/IndustryStandard/Acpi30.h> +/// +/// _PSD Revision for ACPI 4.0 +/// +#define EFI_ACPI_4_0_AML_PSD_REVISION 0 + // // Ensure proper structure formats // diff --git a/src/include/ipxe/efi/IndustryStandard/Acpi50.h b/src/include/ipxe/efi/IndustryStandard/Acpi50.h index 7d57b9ff..2addcb00 100644 --- a/src/include/ipxe/efi/IndustryStandard/Acpi50.h +++ b/src/include/ipxe/efi/IndustryStandard/Acpi50.h @@ -25,6 +25,16 @@ FILE_LICENCE ( BSD2_PATENT ); #define ACPI_GPIO_CONNECTION_DESCRIPTOR 0x8C #define ACPI_GENERIC_SERIAL_BUS_CONNECTION_DESCRIPTOR 0x8E +/// +/// _PSD Revision for ACPI 5.0 +/// +#define EFI_ACPI_5_0_AML_PSD_REVISION 0 + +/// +/// _CPC Revision for ACPI 5.0 +/// +#define EFI_ACPI_5_0_AML_CPC_REVISION 1 + #pragma pack(1) /// diff --git a/src/include/ipxe/efi/IndustryStandard/Acpi51.h b/src/include/ipxe/efi/IndustryStandard/Acpi51.h index 49bb972e..a2079ecc 100644 --- a/src/include/ipxe/efi/IndustryStandard/Acpi51.h +++ b/src/include/ipxe/efi/IndustryStandard/Acpi51.h @@ -15,6 +15,16 @@ FILE_LICENCE ( BSD2_PATENT ); #include <ipxe/efi/IndustryStandard/Acpi50.h> +/// +/// _PSD Revision for ACPI 5.1 +/// +#define EFI_ACPI_5_1_AML_PSD_REVISION 0 + +/// +/// _CPC Revision for ACPI 5.1 +/// +#define EFI_ACPI_5_1_AML_CPC_REVISION 2 + // // Ensure proper structure formats // diff --git a/src/include/ipxe/efi/IndustryStandard/Acpi60.h b/src/include/ipxe/efi/IndustryStandard/Acpi60.h index 9bd821c7..c8d99214 100644 --- a/src/include/ipxe/efi/IndustryStandard/Acpi60.h +++ b/src/include/ipxe/efi/IndustryStandard/Acpi60.h @@ -14,6 +14,16 @@ FILE_LICENCE ( BSD2_PATENT ); #include <ipxe/efi/IndustryStandard/Acpi51.h> +/// +/// _PSD Revision for ACPI 6.0 +/// +#define EFI_ACPI_6_0_AML_PSD_REVISION 0 + +/// +/// _CPC Revision for ACPI 6.0 +/// +#define EFI_ACPI_6_0_AML_CPC_REVISION 2 + // // Ensure proper structure formats // diff --git a/src/include/ipxe/efi/IndustryStandard/PeImage.h b/src/include/ipxe/efi/IndustryStandard/PeImage.h index 401e961c..c1f1a09c 100644 --- a/src/include/ipxe/efi/IndustryStandard/PeImage.h +++ b/src/include/ipxe/efi/IndustryStandard/PeImage.h @@ -4,7 +4,7 @@ EFI_IMAGE_NT_HEADERS64 is for PE32+. This file is coded to the Visual Studio, Microsoft Portable Executable and - Common Object File Format Specification, Revision 8.3 - February 6, 2013. + Common Object File Format Specification, Revision 9.3 - December 29, 2015. This file also includes some definitions in PI Specification, Revision 1.0. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> @@ -271,6 +271,21 @@ typedef struct { #define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5 #define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7 +// +// DLL Characteristics +// +#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020 +#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 +#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080 +#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 +#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 +#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 +#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 +#define IMAGE_DLLCHARACTERISTICS_APPCONTAINER 0x1000 +#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 +#define IMAGE_DLLCHARACTERISTICS_GUARD_CF 0x4000 +#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 + /// /// Length of ShortName. /// @@ -680,9 +695,6 @@ typedef struct { // } EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY; -// avoid conflict with windows header files -#ifndef RUNTIME_FUNCTION_INDIRECT - // // .pdata entries for X64 // @@ -692,8 +704,6 @@ typedef struct { UINT32 UnwindInfoAddress; } RUNTIME_FUNCTION; -#endif - typedef struct { UINT8 Version : 3; UINT8 Flags : 5; diff --git a/src/include/ipxe/efi/Library/BaseLib.h b/src/include/ipxe/efi/Library/BaseLib.h index e17f3da2..16ea35cd 100644 --- a/src/include/ipxe/efi/Library/BaseLib.h +++ b/src/include/ipxe/efi/Library/BaseLib.h @@ -184,11 +184,21 @@ RiscVSetSupervisorAddressTranslationRegister ( ); UINT64 +RiscVGetSupervisorAddressTranslationRegister ( + VOID + ); + +UINT64 RiscVReadTimer ( VOID ); VOID +RiscVSetSupervisorTimeCompareRegister ( + IN UINT64 + ); + +VOID RiscVEnableTimerInterrupt ( VOID ); @@ -203,6 +213,59 @@ RiscVClearPendingTimerInterrupt ( VOID ); +/** + RISC-V invalidate instruction cache. + +**/ +VOID +EFIAPI +RiscVInvalidateInstCacheFenceAsm ( + VOID + ); + +/** + RISC-V invalidate data cache. + +**/ +VOID +EFIAPI +RiscVInvalidateDataCacheFenceAsm ( + VOID + ); + +/** + RISC-V flush cache block. Atomically perform a clean operation + followed by an invalidate operation + +**/ +VOID +EFIAPI +RiscVCpuCacheFlushCmoAsm ( + IN UINTN + ); + +/** +Perform a write transfer to another cache or to memory if the +data in the copy of the cache block have been modified by a store +operation + +**/ +VOID +EFIAPI +RiscVCpuCacheCleanCmoAsm ( + IN UINTN + ); + +/** +Deallocate the copy of the cache block + +**/ +VOID +EFIAPI +RiscVCpuCacheInvalCmoAsm ( + IN UINTN + ); + #endif // defined (MDE_CPU_RISCV64) #if defined (MDE_CPU_LOONGARCH64) @@ -226,6 +289,227 @@ typedef struct { #define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8 +/* + * Set the exception base address for LoongArch. + * + * @param ExceptionBaseAddress The exception base address, must be aligned greater than or qeual to 4K . + */ +VOID +SetExceptionBaseAddress ( + IN UINT64 + ); + +/* + * Set the TlbRebase address for LoongArch. + * + * @param TlbRebaseAddress The TlbRebase address, must be aligned greater than or qeual to 4K . + */ +VOID +SetTlbRebaseAddress ( + IN UINT64 + ); + +/** + Enables local CPU interrupts. + + @param Needs to enable local interrupt bit. +**/ +VOID +EnableLocalInterrupts ( + IN UINT16 + ); + +/** + Disables local CPU interrupts. + + @param Needs to disable local interrupt bit. +**/ +VOID +DisableLocalInterrupts ( + IN UINT16 + ); + +/** + Read CPUCFG register. + + @param Index Specifies the register number of the CPUCFG to read the data. + @param Data A pointer to the variable used to store the CPUCFG register value. +**/ +VOID +AsmCpucfg ( + IN UINT32 Index, + OUT UINT32 *Data + ); + +/** + Gets the timer count value. + + @param[] VOID + @retval timer count value. + +**/ +UINTN +AsmReadStableCounter ( + VOID + ); + +/** + CSR read operation. + + @param[in] Select CSR read instruction select values. + + @return The return value of csrrd instruction, return -1 means no CSR instruction + is found. +**/ +UINTN +CsrRead ( + IN UINT16 Select + ); + +/** + CSR write operation. + + @param[in] Select CSR write instruction select values. + @param[in] Value The csrwr will write the value. + + @return The return value of csrwr instruction, that is, store the old value of + the register, return -1 means no CSR instruction is found. +**/ +UINTN +CsrWrite ( + IN UINT16 Select, + IN UINTN Value + ); + +/** + CSR exchange operation. + + @param[in] Select CSR exchange instruction select values. + @param[in] Value The csrxchg will write the value. + @param[in] Mask The csrxchg mask value. + + @return The return value of csrxchg instruction, that is, store the old value of + the register, return -1 means no CSR instruction is found. +**/ +UINTN +CsrXChg ( + IN UINT16 Select, + IN UINTN Value, + IN UINTN Mask + ); + +/** + IO CSR read byte operation. + + @param[in] Select IO CSR read instruction select values. + + @return The return value of iocsrrd.b instruction. + +**/ +UINT8 +IoCsrRead8 ( + IN UINTN Select + ); + +/** + IO CSR read half word operation. + + @param[in] Select IO CSR read instruction select values. + + @return The return value of iocsrrd.h instruction. + +**/ +UINT16 +IoCsrRead16 ( + IN UINTN Select + ); + +/** + IO CSR read word operation. + + @param[in] Select IO CSR read instruction select values. + + @return The return value of iocsrrd.w instruction. + +**/ +UINT32 +IoCsrRead32 ( + IN UINTN Select + ); + +/** + IO CSR read double word operation. Only for LoongArch64. + + @param[in] Select IO CSR read instruction select values. + + @return The return value of iocsrrd.d instruction. + +**/ +UINT64 +IoCsrRead64 ( + IN UINTN Select + ); + +/** + IO CSR write byte operation. + + @param[in] Select IO CSR write instruction select values. + @param[in] Value The iocsrwr.b will write the value. + + @return VOID. + +**/ +VOID +IoCsrWrite8 ( + IN UINTN Select, + IN UINT8 Value + ); + +/** + IO CSR write half word operation. + + @param[in] Select IO CSR write instruction select values. + @param[in] Value The iocsrwr.h will write the value. + + @return VOID. + +**/ +VOID +IoCsrWrite16 ( + IN UINTN Select, + IN UINT16 Value + ); + +/** + IO CSR write word operation. + + @param[in] Select IO CSR write instruction select values. + @param[in] Value The iocsrwr.w will write the value. + + @return VOID. + +**/ +VOID +IoCsrWrite32 ( + IN UINTN Select, + IN UINT32 Value + ); + +/** + IO CSR write double word operation. Only for LoongArch64. + + @param[in] Select IO CSR write instruction select values. + @param[in] Value The iocsrwr.d will write the value. + + @return VOID. + +**/ +VOID +IoCsrWrite64 ( + IN UINTN Select, + IN UINT64 Value + ); + #endif // defined (MDE_CPU_LOONGARCH64) // @@ -4596,6 +4880,11 @@ CalculateCrc16Ansi ( IN UINT16 InitialValue ); +// +// Initial value for the CRC16-ANSI algorithm, when no prior checksum has been calculated. +// +#define CRC16ANSI_INIT 0xffff + /** Calculates the CRC32c checksum of the given buffer. diff --git a/src/include/ipxe/efi/Pi/PiStatusCode.h b/src/include/ipxe/efi/Pi/PiStatusCode.h index 4375f704..427e5061 100644 --- a/src/include/ipxe/efi/Pi/PiStatusCode.h +++ b/src/include/ipxe/efi/Pi/PiStatusCode.h @@ -365,6 +365,7 @@ typedef struct { #define EFI_PERIPHERAL_LCD_DEVICE (EFI_PERIPHERAL | 0x000B0000) #define EFI_PERIPHERAL_NETWORK (EFI_PERIPHERAL | 0x000C0000) #define EFI_PERIPHERAL_DOCKING (EFI_PERIPHERAL | 0x000D0000) +#define EFI_PERIPHERAL_TPM (EFI_PERIPHERAL | 0x000E0000) ///@} /// @@ -967,26 +968,27 @@ typedef struct { /// These are shared by all subclasses. /// ///@{ -#define EFI_SW_EC_NON_SPECIFIC 0x00000000 -#define EFI_SW_EC_LOAD_ERROR 0x00000001 -#define EFI_SW_EC_INVALID_PARAMETER 0x00000002 -#define EFI_SW_EC_UNSUPPORTED 0x00000003 -#define EFI_SW_EC_INVALID_BUFFER 0x00000004 -#define EFI_SW_EC_OUT_OF_RESOURCES 0x00000005 -#define EFI_SW_EC_ABORTED 0x00000006 -#define EFI_SW_EC_ILLEGAL_SOFTWARE_STATE 0x00000007 -#define EFI_SW_EC_ILLEGAL_HARDWARE_STATE 0x00000008 -#define EFI_SW_EC_START_ERROR 0x00000009 -#define EFI_SW_EC_BAD_DATE_TIME 0x0000000A -#define EFI_SW_EC_CFG_INVALID 0x0000000B -#define EFI_SW_EC_CFG_CLR_REQUEST 0x0000000C -#define EFI_SW_EC_CFG_DEFAULT 0x0000000D -#define EFI_SW_EC_PWD_INVALID 0x0000000E -#define EFI_SW_EC_PWD_CLR_REQUEST 0x0000000F -#define EFI_SW_EC_PWD_CLEARED 0x00000010 -#define EFI_SW_EC_EVENT_LOG_FULL 0x00000011 -#define EFI_SW_EC_WRITE_PROTECTED 0x00000012 -#define EFI_SW_EC_FV_CORRUPTED 0x00000013 +#define EFI_SW_EC_NON_SPECIFIC 0x00000000 +#define EFI_SW_EC_LOAD_ERROR 0x00000001 +#define EFI_SW_EC_INVALID_PARAMETER 0x00000002 +#define EFI_SW_EC_UNSUPPORTED 0x00000003 +#define EFI_SW_EC_INVALID_BUFFER 0x00000004 +#define EFI_SW_EC_OUT_OF_RESOURCES 0x00000005 +#define EFI_SW_EC_ABORTED 0x00000006 +#define EFI_SW_EC_ILLEGAL_SOFTWARE_STATE 0x00000007 +#define EFI_SW_EC_ILLEGAL_HARDWARE_STATE 0x00000008 +#define EFI_SW_EC_START_ERROR 0x00000009 +#define EFI_SW_EC_BAD_DATE_TIME 0x0000000A +#define EFI_SW_EC_CFG_INVALID 0x0000000B +#define EFI_SW_EC_CFG_CLR_REQUEST 0x0000000C +#define EFI_SW_EC_CFG_DEFAULT 0x0000000D +#define EFI_SW_EC_PWD_INVALID 0x0000000E +#define EFI_SW_EC_PWD_CLR_REQUEST 0x0000000F +#define EFI_SW_EC_PWD_CLEARED 0x00000010 +#define EFI_SW_EC_EVENT_LOG_FULL 0x00000011 +#define EFI_SW_EC_WRITE_PROTECTED 0x00000012 +#define EFI_SW_EC_FV_CORRUPTED 0x00000013 +#define EFI_SW_EC_INCONSISTENT_MEMORY_MAP 0x00000014 ///@} // diff --git a/src/include/ipxe/efi/Protocol/DebugSupport.h b/src/include/ipxe/efi/Protocol/DebugSupport.h index 453ea975..8f930e33 100644 --- a/src/include/ipxe/efi/Protocol/DebugSupport.h +++ b/src/include/ipxe/efi/Protocol/DebugSupport.h @@ -685,6 +685,20 @@ typedef struct { // // LoongArch processor exception types. // +// The exception types is located in the CSR ESTAT +// register offset 16 bits, width 6 bits. +// +// If you want to register an exception hook, you can +// shfit the number left by 16 bits, and the exception +// handler will know the types. +// +// For example: +// mCpu->CpuRegisterInterruptHandler ( +// mCpu, +// (EXCEPT_LOONGARCH_PPI << CSR_ESTAT_EXC_SHIFT), +// PpiExceptionHandler +// ); +// #define EXCEPT_LOONGARCH_INT 0 #define EXCEPT_LOONGARCH_PIL 1 #define EXCEPT_LOONGARCH_PIS 2 diff --git a/src/include/ipxe/efi/Protocol/FormBrowser2.h b/src/include/ipxe/efi/Protocol/FormBrowser2.h index b1c0d200..5e6f940b 100644 --- a/src/include/ipxe/efi/Protocol/FormBrowser2.h +++ b/src/include/ipxe/efi/Protocol/FormBrowser2.h @@ -57,6 +57,7 @@ typedef UINTN EFI_BROWSER_ACTION_REQUEST; #define EFI_BROWSER_ACTION_REQUEST_FORM_APPLY 6 #define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD 7 #define EFI_BROWSER_ACTION_REQUEST_RECONNECT 8 +#define EFI_BROWSER_ACTION_REQUEST_QUESTION_APPLY 9 /** Initialize the browser to display the specified configuration forms. @@ -140,10 +141,13 @@ EFI_STATUS @retval EFI_SUCCESS The results have been distributed or are awaiting distribution. - @retval EFI_OUT_OF_RESOURCES The ResultsDataSize specified + @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to contain the results data. + @retval EFI_UNSUPPORTED Uncommitted browser state is not available + at the current stage of execution. + **/ typedef EFI_STATUS diff --git a/src/include/ipxe/efi/Protocol/HiiConfigAccess.h b/src/include/ipxe/efi/Protocol/HiiConfigAccess.h index beae0820..aaa51a31 100644 --- a/src/include/ipxe/efi/Protocol/HiiConfigAccess.h +++ b/src/include/ipxe/efi/Protocol/HiiConfigAccess.h @@ -104,9 +104,16 @@ typedef UINTN EFI_BROWSER_ACTION; string. @retval EFI_INVALID_PARAMETER Unknown name. Progress points - to the & before the name in + to the "&" before the name in question. + @retval EFI_INVALID_PARAMETER If Results or Progress is NULL. + + @retval EFI_ACCESS_DENIED The action violated a system policy. + + @retval EFI_DEVICE_ERROR Failed to extract the current configuration + for one or more named elements. + **/ typedef EFI_STATUS diff --git a/src/include/ipxe/efi/Protocol/Rng.h b/src/include/ipxe/efi/Protocol/Rng.h index 87c5c0ed..92d648be 100644 --- a/src/include/ipxe/efi/Protocol/Rng.h +++ b/src/include/ipxe/efi/Protocol/Rng.h @@ -69,6 +69,15 @@ typedef EFI_GUID EFI_RNG_ALGORITHM; { \ 0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 } \ } +/// +/// The Arm Architecture states the RNDR that the DRBG algorithm should be compliant +/// with NIST SP800-90A, while not mandating a particular algorithm, so as to be +/// inclusive of different geographies. +/// +#define EFI_RNG_ALGORITHM_ARM_RNDR \ + { \ + 0x43d2fde3, 0x9d4e, 0x4d79, {0x02, 0x96, 0xa8, 0x9b, 0xca, 0x78, 0x08, 0x41} \ + } /** Returns information about the random number generation implementation. @@ -148,5 +157,6 @@ extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid; extern EFI_GUID gEfiRngAlgorithmX9313DesGuid; extern EFI_GUID gEfiRngAlgorithmX931AesGuid; extern EFI_GUID gEfiRngAlgorithmRaw; +extern EFI_GUID gEfiRngAlgorithmArmRndr; #endif diff --git a/src/include/ipxe/efi/Protocol/Tcp6.h b/src/include/ipxe/efi/Protocol/Tcp6.h index eed2f7cc..ddceaaf9 100644 --- a/src/include/ipxe/efi/Protocol/Tcp6.h +++ b/src/include/ipxe/efi/Protocol/Tcp6.h @@ -194,12 +194,12 @@ typedef struct { BOOLEAN EnableNagle; /// /// Set it to TRUE to enable TCP timestamps option as defined in - /// RFC1323. Set to FALSE to disable it. + /// RFC7323. Set to FALSE to disable it. /// BOOLEAN EnableTimeStamp; /// /// Set it to TRUE to enable TCP window scale option as defined in - /// RFC1323. Set it to FALSE to disable it. + /// RFC7323. Set it to FALSE to disable it. /// BOOLEAN EnableWindowScaling; /// diff --git a/src/include/ipxe/efi/Uefi/UefiBaseType.h b/src/include/ipxe/efi/Uefi/UefiBaseType.h index 04927599..bf3aa9bb 100644 --- a/src/include/ipxe/efi/Uefi/UefiBaseType.h +++ b/src/include/ipxe/efi/Uefi/UefiBaseType.h @@ -143,6 +143,7 @@ typedef union { #define EFI_END_OF_FILE RETURN_END_OF_FILE #define EFI_INVALID_LANGUAGE RETURN_INVALID_LANGUAGE #define EFI_COMPROMISED_DATA RETURN_COMPROMISED_DATA +#define EFI_IP_ADDRESS_CONFLICT RETURN_IP_ADDRESS_CONFLICT #define EFI_HTTP_ERROR RETURN_HTTP_ERROR #define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH @@ -151,6 +152,7 @@ typedef union { #define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL #define EFI_WARN_STALE_DATA RETURN_WARN_STALE_DATA #define EFI_WARN_FILE_SYSTEM RETURN_WARN_FILE_SYSTEM +#define EFI_WARN_RESET_REQUIRED RETURN_WARN_RESET_REQUIRED ///@} /// diff --git a/src/include/ipxe/efi/Uefi/UefiSpec.h b/src/include/ipxe/efi/Uefi/UefiSpec.h index e5a32d88..cc166fc3 100644 --- a/src/include/ipxe/efi/Uefi/UefiSpec.h +++ b/src/include/ipxe/efi/Uefi/UefiSpec.h @@ -113,6 +113,21 @@ typedef enum { #define EFI_MEMORY_RUNTIME 0x8000000000000000ULL // +// If this flag is set, the memory region is +// described with additional ISA-specific memory attributes +// as specified in EFI_MEMORY_ISA_MASK. +// +#define EFI_MEMORY_ISA_VALID 0x4000000000000000ULL + +// +// Defines the bits reserved for describing optional ISA-specific cacheability +// attributes that are not covered by the standard UEFI Memory Attributes cacheability +// bits (EFI_MEMORY_UC, EFI_MEMORY_WC, EFI_MEMORY_WT, EFI_MEMORY_WB and EFI_MEMORY_UCE). +// See Calling Conventions for further ISA-specific enumeration of these bits. +// +#define EFI_MEMORY_ISA_MASK 0x0FFFF00000000000ULL + +// // Attributes bitmasks, grouped by type // #define EFI_CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP) @@ -307,6 +322,9 @@ EFI_STATUS map that requires a mapping. @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found in the memory map. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -397,11 +415,14 @@ EFI_STATUS for the new virtual address mappings being applied. @retval EFI_SUCCESS The pointer pointed to by Address was modified. - @retval EFI_INVALID_PARAMETER 1) Address is NULL. - 2) *Address is NULL and DebugDisposition does - not have the EFI_OPTIONAL_PTR bit set. @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part of the current memory map. This is normally fatal. + @retval EFI_INVALID_PARAMETER Address is NULL. + @retval EFI_INVALID_PARAMETER *Address is NULL and DebugDisposition does + not have the EFI_OPTIONAL_PTR bit set. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -666,6 +687,10 @@ VOID @retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL. @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure. + @retval EFI_UNSUPPORTED After ExitBootServices() has been called, this return code may be returned + if no variable storage is supported. The platform should describe this + runtime service as unsupported at runtime via an EFI_RT_PROPERTIES_TABLE + configuration table. **/ typedef @@ -702,6 +727,10 @@ EFI_STATUS @retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of the input VariableName buffer. @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_UNSUPPORTED After ExitBootServices() has been called, this return code may be returned + if no variable storage is supported. The platform should describe this + runtime service as unsupported at runtime via an EFI_RT_PROPERTIES_TABLE + configuration table. **/ typedef @@ -744,6 +773,9 @@ EFI_STATUS but the AuthInfo does NOT pass the validation check carried out by the firmware. @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -796,6 +828,9 @@ typedef struct { @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER Time is NULL. @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -813,6 +848,9 @@ EFI_STATUS @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER A time field is out of range. @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -833,7 +871,9 @@ EFI_STATUS @retval EFI_INVALID_PARAMETER Pending is NULL. @retval EFI_INVALID_PARAMETER Time is NULL. @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. - @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -855,7 +895,9 @@ EFI_STATUS Enable is FALSE, then the wakeup alarm was disabled. @retval EFI_INVALID_PARAMETER A time field is out of range. @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. - @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -900,7 +942,7 @@ EFI_STATUS (EFIAPI *EFI_IMAGE_LOAD)( IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN VOID *SourceBuffer OPTIONAL, IN UINTN SourceSize, OUT EFI_HANDLE *ImageHandle @@ -1077,6 +1119,9 @@ EFI_STATUS @retval EFI_SUCCESS The next high monotonic count was returned. @retval EFI_INVALID_PARAMETER HighCount is NULL. @retval EFI_DEVICE_ERROR The device is not functioning properly. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -1650,7 +1695,7 @@ typedef struct { /// UINT32 Flags; /// - /// Size in bytes of the capsule. + /// Size in bytes of the capsule (including capsule header). /// UINT32 CapsuleImageSize; } EFI_CAPSULE_HEADER; @@ -1703,6 +1748,9 @@ typedef struct { in runtime. The caller may resubmit the capsule prior to ExitBootServices(). @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates the capsule is compatible with this platform but there are insufficient resources to process. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef @@ -1734,6 +1782,9 @@ EFI_STATUS in runtime. The caller may resubmit the capsule prior to ExitBootServices(). @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates the capsule is compatible with this platform but there are insufficient resources to process. + @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made. + The platform should describe this runtime service as unsupported at runtime + via an EFI_RT_PROPERTIES_TABLE configuration table. **/ typedef diff --git a/src/include/ipxe/efi/efi_path.h b/src/include/ipxe/efi/efi_path.h index e75ae42c..20ff43f6 100644 --- a/src/include/ipxe/efi/efi_path.h +++ b/src/include/ipxe/efi/efi_path.h @@ -20,6 +20,7 @@ struct aoe_device; struct fcp_description; struct ib_srp_device; struct usb_function; +union uuid; /** * Terminate device path @@ -43,6 +44,7 @@ extern EFI_DEVICE_PATH_PROTOCOL * efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path ); extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path ); extern unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path ); +extern int efi_path_guid ( EFI_DEVICE_PATH_PROTOCOL *path, union uuid *uuid ); extern EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first, ... ); extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev ); diff --git a/src/include/ipxe/efi/import.pl b/src/include/ipxe/efi/import.pl index 34aed9a2..0a7669f4 100755 --- a/src/include/ipxe/efi/import.pl +++ b/src/include/ipxe/efi/import.pl @@ -68,7 +68,7 @@ sub try_import_file { chomp; # Update include lines, and record included files if ( s/^(\s*\#include\s+)[<\"](\S+)[>\"]/$1<ipxe\/efi\/$2>/ ) { - push @dependencies, $1; + push @dependencies, $2; } # Check for BSD licence statement if ( /^\s*SPDX-License-Identifier: BSD-2-Clause-Patent$/ ) { diff --git a/src/include/ipxe/entropy.h b/src/include/ipxe/entropy.h index 240feace..82bb1182 100644 --- a/src/include/ipxe/entropy.h +++ b/src/include/ipxe/entropy.h @@ -237,8 +237,7 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len, int rc; /* Sanity check */ - linker_assert ( ( min_entropy_bits <= ( 8 * max_len ) ), - entropy_buffer_too_small ); + build_assert ( min_entropy_bits <= ( 8 * max_len ) ); /* Round up minimum entropy to an integral number of bytes */ min_entropy_bits = ( ( min_entropy_bits + 7 ) & ~7 ); @@ -247,11 +246,11 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len, * meet or exceed the security strength indicated by the * min_entropy parameter. */ - linker_assert ( ( ( 8 * ENTROPY_HASH_DF_OUTLEN_BYTES ) >= - min_entropy_bits ), hash_df_algorithm_too_weak ); + build_assert ( ( 8 * ENTROPY_HASH_DF_OUTLEN_BYTES ) >= + min_entropy_bits ); /* 1. If ( min_length > max_length ), then return ( FAILURE, Null ) */ - linker_assert ( ( min_len <= max_len ), min_len_greater_than_max_len ); + build_assert ( min_len <= max_len ); /* 2. n = 2 * min_entropy */ n = ( 2 * min_entropy_bits ); @@ -269,9 +268,8 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len, * (The implementation of these steps is inside the function * get_entropy_input_tmp().) */ - linker_assert ( __builtin_constant_p ( tmp_len ), - tmp_len_not_constant ); - linker_assert ( ( n == ( 8 * tmp_len ) ), tmp_len_mismatch ); + build_assert ( __builtin_constant_p ( tmp_len ) ); + build_assert ( n == ( 8 * tmp_len ) ); if ( ( rc = get_entropy_input_tmp ( MIN_ENTROPY ( min_entropy_bits ), tmp, tmp_len ) ) != 0 ) { return rc; @@ -283,17 +281,17 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len, */ if ( tmp_len < min_len ) { /* (Data is already in-place.) */ - linker_assert ( ( data == tmp ), data_not_inplace ); + build_assert ( data == tmp ); memset ( ( data + tmp_len ), 0, ( min_len - tmp_len ) ); return min_len; } else if ( tmp_len > max_len ) { - linker_assert ( ( tmp == tmp_buf ), data_inplace ); + build_assert ( tmp == tmp_buf ); hash_df ( &entropy_hash_df_algorithm, tmp, tmp_len, data, max_len ); return max_len; } else { /* (Data is already in-place.) */ - linker_assert ( ( data == tmp ), data_not_inplace ); + build_assert ( data == tmp ); return tmp_len; } } @@ -328,15 +326,14 @@ entropy_repetition_count_cutoff ( min_entropy_t min_entropy_per_sample ) { cutoff = max_repetitions; if ( cutoff < max_repetitions ) cutoff++; - linker_assert ( ( cutoff >= max_repetitions ), rounding_error ); + build_assert ( cutoff >= max_repetitions ); /* Floating-point operations are not allowed in iPXE since we * never set up a suitable environment. Abort the build * unless the calculated number of repetitions is a * compile-time constant. */ - linker_assert ( __builtin_constant_p ( cutoff ), - repetition_count_cutoff_not_constant ); + build_assert ( __builtin_constant_p ( cutoff ) ); return cutoff; } @@ -443,12 +440,10 @@ entropy_adaptive_proportion_cutoff ( min_entropy_t min_entropy_per_sample ) { cutoff = entropy_adaptive_proportion_cutoff_lookup ( n, h ); /* Fail unless cutoff value is a compile-time constant */ - linker_assert ( __builtin_constant_p ( cutoff ), - adaptive_proportion_cutoff_not_constant ); + build_assert ( __builtin_constant_p ( cutoff ) ); /* Fail if cutoff value is N/A */ - linker_assert ( ( cutoff != APC_NA ), - adaptive_proportion_cutoff_not_applicable ); + build_assert ( cutoff != APC_NA ); return cutoff; } @@ -475,8 +470,7 @@ entropy_startup_test_count ( unsigned int repetition_count_cutoff, num_samples = repetition_count_cutoff; if ( num_samples < adaptive_proportion_cutoff ) num_samples = adaptive_proportion_cutoff; - linker_assert ( __builtin_constant_p ( num_samples ), - startup_test_count_not_constant ); + build_assert ( __builtin_constant_p ( num_samples ) ); return num_samples; } @@ -499,11 +493,9 @@ entropy_init ( struct entropy_source *source, unsigned int startup_test_count; /* Sanity check */ - linker_assert ( min_entropy_per_sample > MIN_ENTROPY ( 0 ), - min_entropy_per_sample_is_zero ); - linker_assert ( ( min_entropy_per_sample <= - MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ), - min_entropy_per_sample_is_impossibly_high ); + build_assert ( min_entropy_per_sample > MIN_ENTROPY ( 0 ) ); + build_assert ( min_entropy_per_sample <= + MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ); /* Calculate test cutoff values */ repetition_count_cutoff = diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 320835a3..21c3d338 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -79,6 +79,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ERRFILE_cachedhcp ( ERRFILE_CORE | 0x00270000 ) #define ERRFILE_acpimac ( ERRFILE_CORE | 0x00280000 ) #define ERRFILE_efi_strings ( ERRFILE_CORE | 0x00290000 ) +#define ERRFILE_uuid ( ERRFILE_CORE | 0x002a0000 ) +#define ERRFILE_efi_path ( ERRFILE_CORE | 0x002b0000 ) #define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 ) #define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 ) @@ -219,6 +221,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ERRFILE_ice ( ERRFILE_DRIVER | 0x00d20000 ) #define ERRFILE_ecam ( ERRFILE_DRIVER | 0x00d30000 ) #define ERRFILE_pcibridge ( ERRFILE_DRIVER | 0x00d40000 ) +#define ERRFILE_aqc1xx ( ERRFILE_DRIVER | 0x00d50000 ) +#define ERRFILE_atl_hw ( ERRFILE_DRIVER | 0x00d60000 ) +#define ERRFILE_atl2_hw ( ERRFILE_DRIVER | 0x00d70000 ) + #define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 ) #define ERRFILE_arp ( ERRFILE_NET | 0x00010000 ) @@ -297,6 +303,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ERRFILE_httpntlm ( ERRFILE_NET | 0x004a0000 ) #define ERRFILE_eap ( ERRFILE_NET | 0x004b0000 ) #define ERRFILE_lldp ( ERRFILE_NET | 0x004c0000 ) +#define ERRFILE_eap_md5 ( ERRFILE_NET | 0x004d0000 ) +#define ERRFILE_eap_mschapv2 ( ERRFILE_NET | 0x004e0000 ) #define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) #define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) @@ -407,6 +415,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ERRFILE_efi_rng ( ERRFILE_OTHER | 0x005c0000 ) #define ERRFILE_efi_shim ( ERRFILE_OTHER | 0x005d0000 ) #define ERRFILE_efi_settings ( ERRFILE_OTHER | 0x005e0000 ) +#define ERRFILE_x25519 ( ERRFILE_OTHER | 0x005f0000 ) +#define ERRFILE_des ( ERRFILE_OTHER | 0x00600000 ) /** @} */ diff --git a/src/include/ipxe/gcm.h b/src/include/ipxe/gcm.h index 90ef0b52..4864445d 100644 --- a/src/include/ipxe/gcm.h +++ b/src/include/ipxe/gcm.h @@ -88,13 +88,11 @@ struct _gcm_name ## _context { \ static int _gcm_name ## _setkey ( void *ctx, const void *key, \ size_t keylen ) { \ struct _gcm_name ## _context *context = ctx; \ - linker_assert ( _blocksize == sizeof ( context->gcm.key ), \ - _gcm_name ## _unsupported_blocksize ); \ - linker_assert ( ( ( void * ) &context->gcm ) == ctx, \ - _gcm_name ## _context_layout_error ); \ - linker_assert ( ( ( void * ) &context->raw ) == \ - ( ( void * ) context->gcm.raw_ctx ), \ - _gcm_name ## _context_layout_error ); \ + build_assert ( _blocksize == sizeof ( context->gcm.key ) ); \ + build_assert ( ( ( void * ) &context->gcm ) == \ + ( ( void * ) context ) ); \ + build_assert ( ( ( void * ) &context->raw ) == \ + ( ( void * ) context->gcm.raw_ctx ) ); \ return gcm_setkey ( &context->gcm, key, keylen, &_raw_cipher ); \ } \ static void _gcm_name ## _setiv ( void *ctx, const void *iv, \ diff --git a/src/include/ipxe/list.h b/src/include/ipxe/list.h index 8de25498..2f02e71f 100644 --- a/src/include/ipxe/list.h +++ b/src/include/ipxe/list.h @@ -399,6 +399,17 @@ extern void extern_list_splice_tail_init ( struct list_head *list, ( (head)->prev == &(entry)->member ) /** + * Test if entry is the list head + * + * @v entry List entry + * @v head List head + * @v member Name of list field within iterator's type + * @ret is_head Entry is the list head + */ +#define list_is_head_entry( entry, head, member ) \ + ( (head) == &(entry)->member ) + +/** * Iterate over a list * * @v pos Iterator @@ -479,6 +490,22 @@ extern void extern_list_splice_tail_init ( struct list_head *list, pos = list_entry ( pos->member.prev, typeof ( *pos ), member ) ) /** + * Iterate over subsequent entries in a list, safe against deletion + * + * @v pos Iterator + * @v tmp Temporary value (of same type as iterator) + * @v head List head + * @v member Name of list field within iterator's type + */ +#define list_for_each_entry_safe_continue( pos, tmp, head, member ) \ + for ( list_check ( (head) ), \ + pos = list_entry ( pos->member.next, typeof ( *pos ), member ), \ + tmp = list_entry ( pos->member.next, typeof ( *tmp ), member ); \ + &pos->member != (head); \ + pos = tmp, \ + tmp = list_entry ( tmp->member.next, typeof ( *tmp ), member ) ) + +/** * Test if list contains a specified entry * * @v entry Entry diff --git a/src/include/ipxe/mschapv2.h b/src/include/ipxe/mschapv2.h new file mode 100644 index 00000000..59cf37ee --- /dev/null +++ b/src/include/ipxe/mschapv2.h @@ -0,0 +1,59 @@ +#ifndef _IPXE_MSCHAPV2_H +#define _IPXE_MSCHAPV2_H + +/** @file + * + * MS-CHAPv2 authentication + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stdint.h> + +/** An MS-CHAPv2 challenge */ +struct mschapv2_challenge { + /** Raw bytes */ + uint8_t byte[16]; +} __attribute__ (( packed )); + +/** An MS-CHAPv2 NT response */ +struct mschapv2_nt_response { + /** DES-encrypted blocks */ + uint8_t block[3][8]; +} __attribute__ (( packed )); + +/** An MS-CHAPv2 challenge response */ +struct mschapv2_response { + /** Peer challenge */ + struct mschapv2_challenge peer; + /** Reserved, must be zero */ + uint8_t reserved[8]; + /** NT response */ + struct mschapv2_nt_response nt; + /** Flags, must be zero */ + uint8_t flags; +} __attribute__ (( packed )); + +/** An MS-CHAPv2 authenticator response */ +struct mschapv2_auth { + /** Authenticator response string + * + * This is an unterminated 42-byte string of the form + * "S=<auth_string>" where <auth_string> is the upper-cased + * hexadecimal encoding of the actual authenticator response + * value. Joy. + */ + char wtf[42]; +} __attribute__ (( packed )); + +extern void mschapv2_response ( const char *username, const char *password, + const struct mschapv2_challenge *challenge, + const struct mschapv2_challenge *peer, + struct mschapv2_response *response ); +extern void mschapv2_auth ( const char *username, const char *password, + const struct mschapv2_challenge *challenge, + const struct mschapv2_response *response, + struct mschapv2_auth *auth ); + +#endif /* _IPXE_MSCHAPV2_H */ diff --git a/src/include/ipxe/parseopt.h b/src/include/ipxe/parseopt.h index 829b3431..61010f22 100644 --- a/src/include/ipxe/parseopt.h +++ b/src/include/ipxe/parseopt.h @@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <stddef.h> +#include <ipxe/uuid.h> #include <ipxe/settings.h> struct net_device; @@ -125,9 +126,18 @@ struct named_setting { struct setting setting; }; +/** A UUID command-line option */ +struct uuid_option { + /** UUID */ + union uuid *value; + /** Storage buffer */ + union uuid buf; +}; + extern int parse_string ( char *text, char **value ); extern int parse_integer ( char *text, unsigned int *value ); extern int parse_timeout ( char *text, unsigned long *value ); +extern int parse_uuid ( char *text, struct uuid_option *uuid ); extern int parse_netdev ( char *text, struct net_device **netdev ); extern int parse_netdev_configurator ( char *text, diff --git a/src/include/ipxe/sanboot.h b/src/include/ipxe/sanboot.h index b163a94b..e44367cd 100644 --- a/src/include/ipxe/sanboot.h +++ b/src/include/ipxe/sanboot.h @@ -19,8 +19,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/process.h> #include <ipxe/blockdev.h> #include <ipxe/acpi.h> +#include <ipxe/uuid.h> #include <config/sanboot.h> +/** + * Default SAN drive number + * + * The drive number is an externally defined concept only in a BIOS + * environment, where it represents the INT13 drive number (0x80 for + * the first hard disk). We retain it in other environments to allow + * for a simple way for iPXE commands to refer to SAN drives. + */ +#define SAN_DEFAULT_DRIVE 0x80 + /** A SAN path */ struct san_path { /** Containing SAN device */ @@ -95,6 +106,18 @@ enum san_device_flags { SAN_NO_DESCRIBE = 0x0001, }; +/** SAN boot configuration parameters */ +struct san_boot_config { + /** Boot filename (or NULL to use default) */ + const char *filename; + /** Required extra filename (or NULL to ignore) */ + const char *extra; + /** Filesystem label (or NULL to ignore volume label) */ + const char *label; + /** UUID (or NULL to ignore UUID) */ + union uuid *uuid; +}; + /** * Calculate static inline sanboot API function name * @@ -155,10 +178,10 @@ void san_unhook ( unsigned int drive ); * Attempt to boot from a SAN device * * @v drive Drive number - * @v filename Filename (or NULL to use default) + * @v config Boot configuration parameters * @ret rc Return status code */ -int san_boot ( unsigned int drive, const char *filename ); +int san_boot ( unsigned int drive, struct san_boot_config *config ); /** * Describe SAN devices for SAN-booted operating system @@ -234,6 +257,7 @@ static inline int sandev_needs_reopen ( struct san_device *sandev ) { } extern struct san_device * sandev_find ( unsigned int drive ); +extern struct san_device * sandev_next ( unsigned int drive ); extern int sandev_reopen ( struct san_device *sandev ); extern int sandev_reset ( struct san_device *sandev ); extern int sandev_read ( struct san_device *sandev, uint64_t lba, diff --git a/src/include/ipxe/smbios.h b/src/include/ipxe/smbios.h index 42278fb2..077a67a8 100644 --- a/src/include/ipxe/smbios.h +++ b/src/include/ipxe/smbios.h @@ -227,6 +227,8 @@ struct smbios { extern int find_smbios ( struct smbios *smbios ); extern int find_smbios_entry ( userptr_t start, size_t len, struct smbios_entry *entry ); +extern int find_smbios3_entry ( userptr_t start, size_t len, + struct smbios3_entry *entry ); extern int find_smbios_structure ( unsigned int type, unsigned int instance, struct smbios_structure *structure ); extern int read_smbios_structure ( struct smbios_structure *structure, diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index 30bb1c48..cf327782 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -96,6 +96,12 @@ struct tls_header { #define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009d #define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009e #define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009f +#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xc013 +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xc014 +#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xc027 +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xc028 +#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xc02f +#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xc030 /* TLS hash algorithm identifiers */ #define TLS_MD5_ALGORITHM 1 @@ -119,6 +125,10 @@ struct tls_header { #define TLS_MAX_FRAGMENT_LENGTH_2048 3 #define TLS_MAX_FRAGMENT_LENGTH_4096 4 +/* TLS named curve extension */ +#define TLS_NAMED_CURVE 10 +#define TLS_NAMED_CURVE_X25519 29 + /* TLS signature algorithms extension */ #define TLS_SIGNATURE_ALGORITHMS 13 @@ -205,6 +215,25 @@ struct tls_cipher_suite { #define __tls_cipher_suite( pref ) \ __table_entry ( TLS_CIPHER_SUITES, pref ) +/** TLS named curved type */ +#define TLS_NAMED_CURVE_TYPE 3 + +/** A TLS named curve */ +struct tls_named_curve { + /** Elliptic curve */ + struct elliptic_curve *curve; + /** Numeric code (in network-endian order) */ + uint16_t code; +}; + +/** TLS named curve table */ +#define TLS_NAMED_CURVES \ + __table ( struct tls_named_curve, "tls_named_curves" ) + +/** Declare a TLS named curve */ +#define __tls_named_curve( pref ) \ + __table_entry ( TLS_NAMED_CURVES, pref ) + /** A TLS cipher specification */ struct tls_cipherspec { /** Cipher suite */ @@ -425,6 +454,7 @@ struct tls_connection { extern struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm; extern struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm; +extern struct tls_key_exchange_algorithm tls_ecdhe_exchange_algorithm; extern int add_tls ( struct interface *xfer, const char *name, struct x509_root *root, struct private_key *key ); diff --git a/src/include/ipxe/uuid.h b/src/include/ipxe/uuid.h index 24c46aca..4874b738 100644 --- a/src/include/ipxe/uuid.h +++ b/src/include/ipxe/uuid.h @@ -48,5 +48,6 @@ static inline void uuid_mangle ( union uuid *uuid ) { } extern const char * uuid_ntoa ( const union uuid *uuid ); +extern int uuid_aton ( const char *string, union uuid *uuid ); #endif /* _IPXE_UUID_H */ diff --git a/src/include/ipxe/x25519.h b/src/include/ipxe/x25519.h new file mode 100644 index 00000000..fd7caeee --- /dev/null +++ b/src/include/ipxe/x25519.h @@ -0,0 +1,94 @@ +#ifndef _IPXE_X25519_H +#define _IPXE_X25519_H + +/** @file + * + * X25519 key exchange + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stdint.h> +#include <ipxe/bigint.h> +#include <ipxe/crypto.h> + +/** X25519 unsigned big integer size + * + * X25519 uses the finite field of integers modulo the prime + * p=2^255-19. The canonical representations of integers in this + * field therefore require only 255 bits. + * + * For internal calculations we use big integers containing up to 267 + * bits, since this ends up allowing us to avoid some unnecessary (and + * expensive) intermediate reductions modulo p. + */ +#define X25519_SIZE bigint_required_size ( ( 267 /* bits */ + 7 ) / 8 ) + +/** An X25519 unsigned big integer used in internal calculations */ +typedef bigint_t ( X25519_SIZE ) x25519_t; + +/** An X25519 unsigned 258-bit integer + * + * This is an unsigned integer N in the finite field of integers + * modulo the prime p=2^255-19. + * + * In this representation, N is encoded as any big integer that is in + * the same congruence class as N (i.e that has the same value as N + * modulo p) and that lies within the 258-bit range [0,8p-1]. + * + * This type can be used as an input for multiplication (but not for + * addition or subtraction). + * + * Addition or subtraction will produce an output of this type. + */ +union x25519_oct258 { + /** Big integer value */ + x25519_t value; +}; + +/** An X25519 unsigned 257-bit integer + * + * This is an unsigned integer N in the finite field of integers + * modulo the prime p=2^255-19. + * + * In this representation, N is encoded as any big integer that is in + * the same congruence class as N (i.e that has the same value as N + * modulo p) and that lies within the 257-bit range [0,4p-1]. + * + * This type can be used as an input for addition, subtraction, or + * multiplication. + * + * Multiplication will produce an output of this type. + */ +union x25519_quad257 { + /** Big integer value */ + x25519_t value; + /** X25519 unsigned 258-bit integer + * + * Any value in the range [0,4p-1] is automatically also + * within the range [0,8p-1] and so may be consumed as an + * unsigned 258-bit integer. + */ + const union x25519_oct258 oct258; +}; + +/** An X25519 32-byte value */ +struct x25519_value { + /** Raw value */ + uint8_t raw[32]; +}; + +extern void x25519_multiply ( const union x25519_oct258 *multiplicand, + const union x25519_oct258 *multiplier, + union x25519_quad257 *result ); +extern void x25519_invert ( const union x25519_oct258 *invertend, + union x25519_quad257 *result ); +extern void x25519_reduce ( union x25519_quad257 *value ); +extern int x25519_key ( const struct x25519_value *base, + const struct x25519_value *scalar, + struct x25519_value *result ); + +extern struct elliptic_curve x25519_curve; + +#endif /* _IPXE_X25519_H */ diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h index c703c8f1..87323cec 100644 --- a/src/include/ipxe/x509.h +++ b/src/include/ipxe/x509.h @@ -171,6 +171,28 @@ struct x509_link { struct list_head list; /** Certificate */ struct x509_certificate *cert; + /** Flags */ + unsigned int flags; +}; + +/** X.509 certficate chain link flags */ +enum x509_link_flags { + /** Cross-signed certificate download has been attempted + * + * This indicates that a cross-signature download attempt has + * been made to find a cross-signed issuer for this link's + * certificate. + */ + X509_LINK_FL_CROSSED = 0x0001, + /** OCSP has been attempted + * + * This indicates that an OCSP attempt has been made using + * this link's certificate as an issuer. (We record the flag + * on the issuer rather than on the issued certificate, since + * we want to retry OCSP if an issuer is replaced with a + * downloaded cross-signed certificate.) + */ + X509_LINK_FL_OCSPED = 0x0002, }; /** An X.509 certificate chain */ @@ -374,6 +396,16 @@ x509_root_put ( struct x509_root *root ) { ref_put ( &root->refcnt ); } +/** + * Check if X.509 certificate is self-signed + * + * @v cert X.509 certificate + * @ret is_self_signed X.509 certificate is self-signed + */ +static inline int x509_is_self_signed ( struct x509_certificate *cert ) { + return ( asn1_compare ( &cert->issuer.raw, &cert->subject.raw ) == 0 ); +} + extern const char * x509_name ( struct x509_certificate *cert ); extern int x509_parse ( struct x509_certificate *cert, const struct asn1_cursor *raw ); @@ -391,6 +423,7 @@ extern int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ); extern int x509_append_raw ( struct x509_chain *chain, const void *data, size_t len ); +extern void x509_truncate ( struct x509_chain *chain, struct x509_link *link ); extern int x509_auto_append ( struct x509_chain *chain, struct x509_chain *certs ); extern int x509_validate_chain ( struct x509_chain *chain, time_t time, |