|
iPXE
|
TLS data formats. More...
Go to the source code of this file.
Data Structures | |
| struct | tls_cursor |
| A TLS variable-length data cursor. More... | |
| union | tls_ptr_len |
| A pointer/length value. More... | |
| struct | tls_certificate |
| Certificate descriptor. More... | |
| struct | tls_certificate_entry |
| CertificateEntry descriptor. More... | |
| struct | tls_digitally_signed |
| DigitallySigned descriptor. More... | |
| struct | tls_extension |
| Extension descriptor. More... | |
| struct | tls_hello_request |
| HelloRequest descriptor. More... | |
| struct | tls_key_share_entry |
| KeyShareEntry descriptor. More... | |
| struct | tls_new_session_ticket |
| NewSessionTicket descriptor. More... | |
| struct | tls_renegotiation_info |
| RenegotiationInfo descriptor. More... | |
| struct | tls_server_hello |
| ServerHello descriptor. More... | |
| struct | tls_server_hello_done |
| ServerHelloDone descriptor. More... | |
| struct | tls_server_key_exchange_dhe |
| ServerKeyExchange descriptor (for DHE). More... | |
| struct | tls_server_key_exchange_ecdhe |
| ServerKeyExchange descriptor (for ECDHE). More... | |
| struct | tls_supported_version |
| SupportedVersions descriptor (in ServerHello). More... | |
| struct | tls_supported_versions |
| SupportedVersions descriptor (in ClientHello). More... | |
Macros | |
| #define | TLS_VERSION_TLS_1_1 0x0302 |
| TLS version 1.1. | |
| #define | TLS_VERSION_TLS_1_2 0x0303 |
| TLS version 1.2. | |
| #define | TLS_VERSION_TLS_1_3 0x0304 |
| TLS version 1.3. | |
| #define | TLS_VERSION_BASE TLS_VERSION_TLS_1_1 |
| Lowest configurable supported version. | |
| #define | TLS_DESCR_COUNT(desc) |
| Number of pointer/length values in a descriptor structure. | |
| #define | TLS_DESCR_MAPPING(desc) |
| Binary encoding of a descriptor structure mapping. | |
| #define | TLS_MAPSZ(desc) |
| Describe size of a descriptor mapping. | |
| #define | TLS_INDEX(desc, field) |
| Index of descriptor field. | |
| #define | TLS_EXTNS(desc, field) |
| Number of extensions of interest within an extension descriptor. | |
| #define | TLS_FIXED(desc, version, field) |
| Describe a fixed-length field. | |
| #define | TLS_VARIABLE(desc, version, field, bits, extns) |
| Describe a variable-length field. | |
| #define | TLS_EXTRA(desc, version, field) |
| Describe a variable-length field that captures all remaining data. | |
| #define | TLS_VAR08(desc, version, field) |
| Describe a variable-length field with an 8-bit length. | |
| #define | TLS_VAR16(desc, version, field) |
| Describe a variable-length field with a 16-bit length. | |
| #define | TLS_VAR24(desc, version, field) |
| Describe a variable-length field with a 24-bit length. | |
| #define | TLS_EXT16(desc, version, field) |
| Describe a variable-length field containing extensions. | |
| #define | TLS_EXTND(desc, extension, field) |
| Describe a variable-length field containing an extension of interest. | |
| #define | TLS_MAP_MIN(byte) |
| Interpret minimum version from an llllllvv byte. | |
| #define | TLS_MAP_FIXED(byte) |
| Interpret fixed length from an llllllvv byte. | |
| #define | TLS_MAP_LEN_LEN(byte) |
| Interpret number of length bytes from an xxxxxxnn byte. | |
| #define | TLS_MAP_LEN_LEN_MAX 3 |
| Maximum number of length bytes. | |
| #define | TLS_MAP_EXTENSIONS(byte) |
| Interpret number of extensions from an xxxxxxnn byte. | |
| #define | tls_parse(type, version, cursor, desc) |
| Parse TLS data structure. | |
| #define | tls_parse_opt(type, version, cursor, desc) |
| Parse optional TLS data structure. | |
| #define | tls_build(type, version, desc, cursor) |
| Build TLS data structure. | |
| #define | tls_size(type, version, desc, cursor) |
| Calculate length of TLS data structure. | |
TLS data formats.
TLS uses an ad hoc mixture of fixed-length and variable-length fields. Variable-length fields are preceded by a length field that may be one, two, or three bytes depending on the maximum length defined by the structure.
To avoid open-coding a very large number of bounds checks, we define an abstraction for decomposing the component parts of a TLS data structure into a sequence of field data pointers and lengths (for variable-length fields), along with an efficient binary encoding that can describe the mapping between the decomposition and the raw data structure.
A fixed-length field is described using a simple pointer to the appropriate fixed-length data type. A variable-length field is described using a cursor structure that comprises a void pointer followed by a length. TLS extensions are always variable-length and so are represented in the same way as variable-length fields.
For example, the start of a ServerHello could be described using:
struct tls_server_hello {
uint16_t *version;
struct tls_random *random;
struct tls_cursor session_id;
uint16_t *suite;
uint8_t *compression;
struct {
struct tls_cursor all;
struct tls_cursor renegotiation;
struct tls_cursor extended_master_secret;
} ext;
};
Note that the fixed-length fields are all typed pointers, whereas the variable-length session ID uses a TLS cursor (i.e. a void pointer and a length). Since pointer values and length values are necessarily the same size, we can meaningfully treat this descriptor structure as an array ptrlen[] of pointer/length values.
We create a binary encoding to allow us to define the mapping between this descriptor structure and the raw TLS data structure using a static byte array constructed at build time. The same binary encoding may be used both for parsing and for building a TLS data structure.
Starting at index N=1 within the byte array map[]:
Any parsing failure (e.g. insufficient remaining space to contain the fixed-length or variable-length structure) will be treated as a fatal error. Missing extensions of interest will not be treated as errors, and the corresponding ptrlen entries will be zeroed to indicate that the extension was not found. Duplicate extensions of interest will be treated as a fatal error. (Any extensions that are not of interest will be ignored, even if duplicated.)
The encoding allows for fixed-length fields of up to 62 bytes. Longer fixed-length fields must be expressed as a sequence of smaller fixed-length fields.
All fields must be represented using data structures that are packed and that allow for arbitrary byte alignment.
A variable-length field that covers all remaining data (i.e. with N==0) may be used for incremental parsing, as required for the variable number of entries in structures such as a TLS extension list. If no such variable-length field exists, then any leftover data will be treated as a fatal parsing error.
Up to four consecutive versions of TLS may be supported by the encoding. Experience shows that at most three versions of TLS will be supported by the codebase at any one time, and so this is likely to be sufficient in practice.
The encoding is designed to allow for efficient population of the byte array using preprocessor macros (with compile-time checks to ensure that the byte array matches the descriptor structure). A missing populator macro will leave an erroneous zero byte within the byte array, and the encoding has been designed so that stray zero bytes will fail safe: map[0]==0 is treated as a fatal error, L==0 or T==0 are treated as fatal errors, and N==0 would capture all remaining data (and so cause parsing to fail on the subsequent byte).
Definition in file tlsfmt.h.
| #define TLS_VERSION_TLS_1_1 0x0302 |
TLS version 1.1.
Definition at line 174 of file tlsfmt.h.
Referenced by tls_new_server_hello(), and tlsfmt_test_exec().
| #define TLS_VERSION_TLS_1_2 0x0303 |
TLS version 1.2.
Definition at line 177 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING(), tls_select_cipher(), tls_send_certificate_verify(), tls_set_digest(), tls_verify_signature(), and tlsfmt_test_exec().
| #define TLS_VERSION_TLS_1_3 0x0304 |
TLS version 1.3.
Definition at line 180 of file tlsfmt.h.
Referenced by tls_build_map(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), tls_has_inner(), tls_keysize_is_variable(), tls_new_change_cipher(), tls_new_ciphertext(), tls_new_finished(), tls_new_server_hello(), tls_new_session_ticket(), tls_parse_map(), tls_send_finished(), tls_send_record(), tls_set_digest(), tls_validator_done(), and tlsfmt_test_exec().
| #define TLS_VERSION_BASE TLS_VERSION_TLS_1_1 |
Lowest configurable supported version.
Definition at line 183 of file tlsfmt.h.
Referenced by tls_build_extensions(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and tls_parse_extensions().
| #define TLS_DESCR_COUNT | ( | desc | ) |
Number of pointer/length values in a descriptor structure.
| desc | Descriptor structure name |
| count | Number of pointer/length values |
Definition at line 207 of file tlsfmt.h.
| #define TLS_DESCR_MAPPING | ( | desc | ) |
Binary encoding of a descriptor structure mapping.
| desc | Descriptor structure name |
| map | Binary encoding of the descriptor structure mapping |
Definition at line 220 of file tlsfmt.h.
| #define TLS_MAPSZ | ( | desc | ) |
Describe size of a descriptor mapping.
| desc | Descriptor stucture name |
Definition at line 229 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().
| #define TLS_INDEX | ( | desc, | |
| field ) |
Index of descriptor field.
| desc | Descriptor structure name |
| field | Field name within descriptor structure |
| index | Index within byte array or ptr/len array |
Definition at line 239 of file tlsfmt.h.
| #define TLS_EXTNS | ( | desc, | |
| field ) |
Number of extensions of interest within an extension descriptor.
| desc | Descriptor structure name |
| field | Field name within descriptor structure |
| extns | Number of extensions of interest within this field |
Definition at line 256 of file tlsfmt.h.
Describe a fixed-length field.
| desc | Descriptor structure name |
| version | Minimum TLS version that includes this field |
| field | Field name within descriptor structure |
Definition at line 268 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().
Describe a variable-length field.
| desc | Descriptor structure name |
| version | Minimum TLS version that includes this field |
| field | Field name within descriptor structure |
| bits | Number of bits used to encode field length |
| extns | Number of extensions of interest plus one (if any) |
Definition at line 284 of file tlsfmt.h.
Describe a variable-length field that captures all remaining data.
| desc | Descriptor structure name |
| version | Minimum TLS version that includes this field |
| field | Field name within descriptor structure |
Definition at line 299 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().
Describe a variable-length field with an 8-bit length.
| desc | Descriptor structure name |
| version | Minimum TLS version that includes this field |
| field | Field name within descriptor structure |
Definition at line 309 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().
Describe a variable-length field with a 16-bit length.
| desc | Descriptor structure name |
| version | Minimum TLS version that includes this field |
| field | Field name within descriptor structure |
Definition at line 319 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().
Describe a variable-length field with a 24-bit length.
| desc | Descriptor structure name |
| version | Minimum TLS version that includes this field |
| field | Field name within descriptor structure |
Definition at line 329 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().
Describe a variable-length field containing extensions.
| desc | Descriptor structure name |
| version | Minimum TLS version that includes this field |
| field | Field name within descriptor structure |
Definition at line 339 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().
| #define TLS_EXTND | ( | desc, | |
| extension, | |||
| field ) |
Describe a variable-length field containing an extension of interest.
| desc | Descriptor structure name |
| extension | Extension type |
| field | Field name within descriptor structure |
Definition at line 350 of file tlsfmt.h.
Referenced by TLS_DESCR_MAPPING().
| #define TLS_MAP_MIN | ( | byte | ) |
Interpret minimum version from an llllllvv byte.
| byte | Mapping byte |
| min | Minimum TLS version that includes this field |
Definition at line 362 of file tlsfmt.h.
Referenced by tls_build_map(), and tls_parse_map().
| #define TLS_MAP_FIXED | ( | byte | ) |
Interpret fixed length from an llllllvv byte.
| byte | Mapping byte |
| fixed | Fixed length |
Definition at line 370 of file tlsfmt.h.
Referenced by tls_build_map(), and tls_parse_map().
| #define TLS_MAP_LEN_LEN | ( | byte | ) |
Interpret number of length bytes from an xxxxxxnn byte.
| byte | Mapping byte |
| len_len | Number of length bytes |
Definition at line 378 of file tlsfmt.h.
Referenced by tls_build_map(), and tls_parse_map().
| #define TLS_MAP_LEN_LEN_MAX 3 |
Maximum number of length bytes.
Definition at line 381 of file tlsfmt.h.
Referenced by tls_build_map().
| #define TLS_MAP_EXTENSIONS | ( | byte | ) |
Interpret number of extensions from an xxxxxxnn byte.
| byte | Mapping byte |
| extensions | Number of extensions |
Definition at line 389 of file tlsfmt.h.
Referenced by tls_build_map(), and tls_parse_map().
Parse TLS data structure.
| type | Descriptor structure name |
| version | Protocol version |
| cursor | Cursor containing TLS data structure |
| desc | Data structure descriptor to fill in |
| rc | Return status code |
Definition at line 597 of file tlsfmt.h.
Referenced by tls_new_certificate(), tls_new_hello_request(), tls_new_server_hello(), tls_new_server_hello_done(), tls_new_session_ticket(), tls_parse_dhe(), tls_parse_ecdhe(), tls_parse_extensions(), tls_verify_signature(), and tlsfmt_test_exec().
Parse optional TLS data structure.
| type | Descriptor structure name |
| version | Protocol version |
| cursor | Cursor containing TLS data structure |
| desc | Data structure descriptor to fill in |
| rc | Return status code |
Definition at line 612 of file tlsfmt.h.
Referenced by tls_new_server_hello().
Build TLS data structure.
| type | Descriptor structure name |
| version | Protocol version |
| desc | Data structure descriptor to fill in |
| cursor | Cursor to contain TLS data structure |
| rc | Return status code |
Definition at line 627 of file tlsfmt.h.
Referenced by tls_build_extensions(), and tlsfmt_test_exec().
Calculate length of TLS data structure.
| type | Descriptor structure name |
| version | Protocol version |
| desc | Data structure descriptor to fill in |
| cursor | Cursor to contain TLS data structure |
| rc | Return status code |
Definition at line 642 of file tlsfmt.h.
Referenced by tlsfmt_test_exec().
| FILE_LICENCE | ( | GPL2_OR_LATER_OR_UBDL | ) |
| FILE_SECBOOT | ( | PERMITTED | ) |
|
inlinestatic |
Get ASN.1 cursor from TLS cursor.
| cursor | TLS cursor |
| asn1 | ASN.1 object cursor |
Definition at line 548 of file tlsfmt.h.
References build_assert, container_of, typeof(), and u.
Referenced by tls_key_verify(), and tlsfmt_test_exec().
|
extern |
Parse TLS data structure.
| map | Data structure descriptor mapping |
| version | Protocol version |
| cursor | Cursor containing TLS data structure |
| desc | Data structure descriptor to fill in |
| rc | Return status code |
Definition at line 148 of file tlsfmt.c.
References assert, container_of, count, data, tls_cursor::data, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, desc, EINVAL, EPROTO, fixed, index, len, tls_cursor::len, map, memset(), next, rc, TLS_MAP_EXTENSIONS, TLS_MAP_FIXED, TLS_MAP_LEN_LEN, TLS_MAP_MIN, tls_map_name(), tls_parse_extensions(), TLS_VERSION_TLS_1_3, and version.
Referenced by tls_parse_opt_map().
|
extern |
Parse optional TLS data structure.
| map | Data structure descriptor mapping |
| version | Protocol version |
| cursor | Cursor containing TLS data structure |
| desc | Data structure descriptor to fill in |
| rc | Return status code |
Definition at line 319 of file tlsfmt.c.
References count, tls_cursor::data, DBGC, desc, EINVAL, map, memset(), rc, tls_map_name(), tls_parse_map(), and version.
|
extern |
Build TLS data structure.
| map | Data structure descriptor mapping |
| version | Protocol version |
| desc | Data structure descriptor |
| cursor | Cursor to contain TLS data structure |
| rc | Return status code |
Build a TLS data structure at the cursor. The cursor's original length will be ignored and will be set to the overall length of the built data structure. The caller must ensure that sufficient space already exists (e.g. by calling tls_size() first to determine the required length).
The overall length will be calculated based on the variable lengths within the descriptor. The output content will be be copied from any non-NULL pointers within the descriptor (with any missing content initialised to zero).
Pointers within the descriptor will be updated to point to the appropriate location within the built data structure.
The caller must therefore fill in any variable lengths within the descriptor beforehand, but may freely choose to either fill in pointers within the descriptor beforehand or to write through the updated pointers afterwards.
A cursor with a NULL data pointer may be used to calculate the required length without copying in any data or updating any pointers within the descriptor.
Definition at line 444 of file tlsfmt.c.
References assert, container_of, count, data, tls_cursor::data, DBGC, DBGC2, DBGC2_HDA, desc, EINVAL, ERANGE, fixed, index, len, tls_cursor::len, map, max, memcpy(), memset(), next, NULL, rc, tls_build_extensions(), TLS_MAP_EXTENSIONS, TLS_MAP_FIXED, TLS_MAP_LEN_LEN, TLS_MAP_LEN_LEN_MAX, TLS_MAP_MIN, tls_map_name(), TLS_VERSION_TLS_1_3, and version.
Referenced by tls_size_map().
|
inlinestatic |
Calculate length of TLS data structure.
| type | Descriptor structure name |
| version | Protocol version |
| desc | Data structure descriptor to fill in |
| cursor | Cursor to contain TLS data structure |
| rc | Return status code |
Definition at line 581 of file tlsfmt.h.
References tls_cursor::data, desc, map, NULL, tls_build_map(), and version.
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |