iPXE
tlsfmt.h File Reference

TLS data formats. More...

#include <stdint.h>
#include <stddef.h>
#include <ipxe/asn1.h>

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_client_hello
 ClientHello descriptor. More...
struct  tls_client_key_exchange_dhe
 ClientKeyExchange descriptor (for DHE). More...
struct  tls_client_key_exchange_ecdhe
 ClientKeyExchange descriptor (for ECDHE). More...
struct  tls_client_key_exchange_pubkey
 ClientKeyExchange descriptor (for key transport). More...
union  tls_client_key_exchange
 ClientKeyExchange descriptor (unified). 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_client_hello
 KeyShareClientHello descriptor. More...
struct  tls_key_share_entry
 KeyShareEntry descriptor. More...
struct  tls_key_share_hello_retry_request
 KeyShareHelloRetryRequest descriptor. More...
struct  tls_key_share_server_hello
 KeyShareServerHello descriptor. More...
union  tls_key_share_server
 KeyShareServerHello/KeyShareHelloRetryRequest combined descriptor. More...
struct  tls_max_fragment_length
 MaxFragmentLength descriptor. More...
struct  tls_named_group_list
 NamedGroupList descriptor. More...
struct  tls_new_session_ticket
 NewSessionTicket descriptor. More...
struct  tls_psk_key_exchange_modes
 PskKeyExchangeModes 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_server_name
 ServerName descriptor. More...
struct  tls_server_name_list
 ServerNameList descriptor. More...
struct  tls_signature_scheme_list
 SignatureSchemeList descriptor. 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.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static const struct asn1_cursor * tls_asn1 (const struct tls_cursor *cursor)
 Get ASN.1 cursor from TLS cursor.
int tls_parse_map (const uint8_t *map, unsigned int version, const struct tls_cursor *cursor, union tls_ptr_len *desc)
 Parse TLS data structure.
int tls_parse_opt_map (const uint8_t *map, unsigned int version, const struct tls_cursor *cursor, union tls_ptr_len *desc)
 Parse optional TLS data structure.
int tls_build_map (const uint8_t *map, unsigned int version, union tls_ptr_len *desc, struct tls_cursor *cursor)
 Build TLS data structure.
int tls_size_map (const uint8_t *map, unsigned int version, union tls_ptr_len *desc, struct tls_cursor *cursor)
 Calculate length of TLS data structure.
 TLS_DESCR_MAPPING (tls_certificate)
 TLS_DESCR_MAPPING (tls_certificate_entry)
 TLS_DESCR_MAPPING (tls_client_hello)
 TLS_DESCR_MAPPING (tls_client_key_exchange_dhe)
 TLS_DESCR_MAPPING (tls_client_key_exchange_ecdhe)
 TLS_DESCR_MAPPING (tls_client_key_exchange_pubkey)
 TLS_DESCR_MAPPING (tls_digitally_signed)
 TLS_DESCR_MAPPING (tls_extension)
 TLS_DESCR_MAPPING (tls_hello_request)
 TLS_DESCR_MAPPING (tls_key_share_client_hello)
 TLS_DESCR_MAPPING (tls_key_share_entry)
 TLS_DESCR_MAPPING (tls_key_share_hello_retry_request)
 TLS_DESCR_MAPPING (tls_key_share_server_hello)
 TLS_DESCR_MAPPING (tls_max_fragment_length)
 TLS_DESCR_MAPPING (tls_named_group_list)
 TLS_DESCR_MAPPING (tls_new_session_ticket)
 TLS_DESCR_MAPPING (tls_psk_key_exchange_modes)
 TLS_DESCR_MAPPING (tls_renegotiation_info)
 TLS_DESCR_MAPPING (tls_server_hello)
 TLS_DESCR_MAPPING (tls_server_hello_done)
 TLS_DESCR_MAPPING (tls_server_key_exchange_dhe)
 TLS_DESCR_MAPPING (tls_server_key_exchange_ecdhe)
 TLS_DESCR_MAPPING (tls_server_name)
 TLS_DESCR_MAPPING (tls_server_name_list)
 TLS_DESCR_MAPPING (tls_signature_scheme_list)
 TLS_DESCR_MAPPING (tls_supported_version)
 TLS_DESCR_MAPPING (tls_supported_versions)

Detailed Description

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[]:

  • Interpret map[0] as the length of the map[] array. A zero array length is invalid and is treated as a fatal error.
    • Upon reaching the end of the mapping (i.e. N==map[0]), stop processing.
  • Interpret map[N] as the eight bits llllllvv, where:
    • V = vv is the minimal TLS version that includes this field (encoded as a delta from the lowest version currently supported by the codebase).
    • L = llllll is one plus the length of the corresponding fixed-length data structure. An empty fixed-length data structure is pointless, and so we choose a zero fixed length (i.e. L==1) to represent a variable-length data structure. A negative fixed length (i.e. L==0) is invalid and is treated as a fatal error.
  • For a fixed-length data structure (with L>1):
    • When parsing: store the pointer to the start of the fixed-length data as ptrlen[N-1].
    • When building: append a copy of the data from ptrlen[N-1] with length L-1.
  • For a variable-length data structure (with L==1), interpret map[N+1] as the eight bits xxxxxxnn, where:
    • N = nn is the length of the length header that precedes the variable-length data structure. A zero-byte length header is invalid, and so we choose N==0 to represent a field that covers all remaining data.
    • X = xxxxxx is one plus the number of TLS extension types that immediately follow map[N+1] and that represent extensions of interest that may be present within this field. A negative number of extensions (i.e. X==0) is impossible and so we choose this to represent a field that is not used to contain extensions.
    • When parsing: store the pointer to the start of the variable-length data as ptrlen[N-1], and store the decoded length of the variable-length data as ptrlen[N].
    • When building: append a copy of the data from ptrlen[N-1] (with the correct N-byte length header). Take the length of the variable-length data to be X ? 0 : ptrlen[N] (i.e. always build fields that contain extensions as being empty).
  • For each 1<=k<=(X-1) in a variable-length data structure that is used to contain extensions (i.e. that has X>0), interpret T = map[N+2k]:map[N+2k+1] as the inverse of a TLS extension type (in network-endian order):
    • If T==0, then terminate processing with a fatal error.
    • When parsing: for each matching extension type ~T that is found, store the pointer to the start of the extension data as ptrlen[N+2k-1], and store the decoded length of the variable-length extension data as ptrlen[N+2k].
    • When building: if ptrlen[N+2k-1] is set, then append a copy of the data from ptrlen[N+2k-1] with length ptrlen[N+2k] as an extension with type ~T (with the correct extension header, and updating the length of the containing field accordingly).
  • Increment N to the next uninterpreted byte, and loop.

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.

Macro Definition Documentation

◆ TLS_VERSION_TLS_1_1

#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(), tls_version_name(), and tlsfmt_test_exec().

◆ TLS_VERSION_TLS_1_2

#define TLS_VERSION_TLS_1_2   0x0303

◆ TLS_VERSION_TLS_1_3

◆ TLS_VERSION_BASE

◆ TLS_DESCR_COUNT

#define TLS_DESCR_COUNT ( desc)
Value:
( /* Calculate count */ \
( sizeof ( struct desc ) / sizeof ( union tls_ptr_len ) ) + \
/* Check alignment */ \
( 0 * sizeof ( int[ -( sizeof ( struct desc ) % \
sizeof ( union tls_ptr_len ) ) ] ) ) )
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
A pointer/length value.
Definition tlsfmt.h:194

Number of pointer/length values in a descriptor structure.

Parameters
descDescriptor structure name
Return values
countNumber of pointer/length values

Definition at line 207 of file tlsfmt.h.

207#define TLS_DESCR_COUNT( desc ) \
208 ( /* Calculate count */ \
209 ( sizeof ( struct desc ) / sizeof ( union tls_ptr_len ) ) + \
210 /* Check alignment */ \
211 ( 0 * sizeof ( int[ -( sizeof ( struct desc ) % \
212 sizeof ( union tls_ptr_len ) ) ] ) ) )

◆ TLS_DESCR_MAPPING

#define TLS_DESCR_MAPPING ( desc)
Value:
const uint8_t desc ## _map [ 1 /* Mapping size byte */ + \
TLS_DESCR_COUNT ( desc ) ]
unsigned char uint8_t
Definition stdint.h:10

Binary encoding of a descriptor structure mapping.

Parameters
descDescriptor structure name
Return values
mapBinary encoding of the descriptor structure mapping

Definition at line 220 of file tlsfmt.h.

220#define TLS_DESCR_MAPPING( desc ) \
221 const uint8_t desc ## _map [ 1 /* Mapping size byte */ + \
222 TLS_DESCR_COUNT ( desc ) ]

◆ TLS_MAPSZ

#define TLS_MAPSZ ( desc)
Value:
[0] = ( 1 /* Mapping size byte */ + TLS_DESCR_COUNT ( desc ) )
#define TLS_DESCR_COUNT(desc)
Number of pointer/length values in a descriptor structure.
Definition tlsfmt.h:207

Describe size of a descriptor mapping.

Parameters
descDescriptor stucture name

Definition at line 229 of file tlsfmt.h.

229#define TLS_MAPSZ( desc ) \
230 [0] = ( 1 /* Mapping size byte */ + TLS_DESCR_COUNT ( desc ) )

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(), 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().

◆ TLS_INDEX

#define TLS_INDEX ( desc,
field )
Value:
( /* Skip mapping size byte */ \
1 + \
/* Index within ptr/len array */ \
( offsetof ( struct desc, field ) / \
sizeof ( union tls_ptr_len ) ) + \
/* Check alignment */ \
( 0 * sizeof ( int[ -( offsetof ( struct desc, field ) % \
sizeof ( union tls_ptr_len ) ) ] ) ) )
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25

Index of descriptor field.

Parameters
descDescriptor structure name
fieldField name within descriptor structure
Return values
indexIndex within byte array or ptr/len array

Definition at line 239 of file tlsfmt.h.

239#define TLS_INDEX( desc, field ) \
240 ( /* Skip mapping size byte */ \
241 1 + \
242 /* Index within ptr/len array */ \
243 ( offsetof ( struct desc, field ) / \
244 sizeof ( union tls_ptr_len ) ) + \
245 /* Check alignment */ \
246 ( 0 * sizeof ( int[ -( offsetof ( struct desc, field ) % \
247 sizeof ( union tls_ptr_len ) ) ] ) ) )

◆ TLS_EXTNS

#define TLS_EXTNS ( desc,
field )
Value:
( ( sizeof ( ( ( struct desc * ) NULL )->field ) - \
sizeof ( ( ( struct desc * ) NULL )->field.all ) ) \
/ sizeof ( struct tls_cursor ) )
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
A TLS variable-length data cursor.
Definition tlsfmt.h:186

Number of extensions of interest within an extension descriptor.

Parameters
descDescriptor structure name
fieldField name within descriptor structure
Return values
extnsNumber of extensions of interest within this field

Definition at line 256 of file tlsfmt.h.

256#define TLS_EXTNS( desc, field ) \
257 ( ( sizeof ( ( ( struct desc * ) NULL )->field ) - \
258 sizeof ( ( ( struct desc * ) NULL )->field.all ) ) \
259 / sizeof ( struct tls_cursor ) )

◆ TLS_FIXED

#define TLS_FIXED ( desc,
version,
field )
Value:
/* Encoded `llllllvv` */ \
[ TLS_INDEX ( desc, field ) ] = \
( ( (version) - TLS_VERSION_BASE ) + \
( ( sizeof ( *( ( ( struct desc * ) NULL )->field ) ) \
+ 1 ) << 2 ) )
u32 version
Driver version.
Definition ath9k_hw.c:1985
#define TLS_INDEX(desc, field)
Index of descriptor field.
Definition tlsfmt.h:239
#define TLS_VERSION_BASE
Lowest configurable supported version.
Definition tlsfmt.h:183

Describe a fixed-length field.

Parameters
descDescriptor structure name
versionMinimum TLS version that includes this field
fieldField name within descriptor structure

Definition at line 268 of file tlsfmt.h.

268#define TLS_FIXED( desc, version, field ) \
269 /* Encoded `llllllvv` */ \
270 [ TLS_INDEX ( desc, field ) ] = \
271 ( ( (version) - TLS_VERSION_BASE ) + \
272 ( ( sizeof ( *( ( ( struct desc * ) NULL )->field ) ) \
273 + 1 ) << 2 ) )

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(), and TLS_DESCR_MAPPING().

◆ TLS_VARIABLE

#define TLS_VARIABLE ( desc,
version,
field,
bits,
extns )
Value:
/* Encoded `000001vv` */ \
[ TLS_INDEX ( desc, field ) ] = \
( ( (version) - TLS_VERSION_BASE ) + ( 1 << 2 ) ), \
/* Encoded `xxxxxxnn` */ \
[ TLS_INDEX ( desc, field ) + 1 ] = \
( ( ( (bits) + 7 ) / 8 ) + ( (extns) << 2 ) )
static volatile void * bits
Definition bitops.h:28

Describe a variable-length field.

Parameters
descDescriptor structure name
versionMinimum TLS version that includes this field
fieldField name within descriptor structure
bitsNumber of bits used to encode field length
extnsNumber of extensions of interest plus one (if any)

Definition at line 284 of file tlsfmt.h.

284#define TLS_VARIABLE( desc, version, field, bits, extns ) \
285 /* Encoded `000001vv` */ \
286 [ TLS_INDEX ( desc, field ) ] = \
287 ( ( (version) - TLS_VERSION_BASE ) + ( 1 << 2 ) ), \
288 /* Encoded `xxxxxxnn` */ \
289 [ TLS_INDEX ( desc, field ) + 1 ] = \
290 ( ( ( (bits) + 7 ) / 8 ) + ( (extns) << 2 ) )

◆ TLS_EXTRA

#define TLS_EXTRA ( desc,
version,
field )
Value:
TLS_VARIABLE ( desc, version, field, 0, 0 )
#define TLS_VARIABLE(desc, version, field, bits, extns)
Describe a variable-length field.
Definition tlsfmt.h:284

Describe a variable-length field that captures all remaining data.

Parameters
descDescriptor structure name
versionMinimum TLS version that includes this field
fieldField name within descriptor structure

Definition at line 299 of file tlsfmt.h.

299#define TLS_EXTRA( desc, version, field ) \
300 TLS_VARIABLE ( desc, version, field, 0, 0 )

Referenced by TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().

◆ TLS_VAR08

#define TLS_VAR08 ( desc,
version,
field )
Value:
TLS_VARIABLE ( desc, (version), field, 8, 0 )

Describe a variable-length field with an 8-bit length.

Parameters
descDescriptor structure name
versionMinimum TLS version that includes this field
fieldField name within descriptor structure

Definition at line 309 of file tlsfmt.h.

309#define TLS_VAR08( desc, version, field ) \
310 TLS_VARIABLE ( desc, (version), field, 8, 0 )

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(), and TLS_DESCR_MAPPING().

◆ TLS_VAR16

#define TLS_VAR16 ( desc,
version,
field )
Value:
TLS_VARIABLE ( desc, (version), field, 16, 0 )

Describe a variable-length field with a 16-bit length.

Parameters
descDescriptor structure name
versionMinimum TLS version that includes this field
fieldField name within descriptor structure

Definition at line 319 of file tlsfmt.h.

319#define TLS_VAR16( desc, version, field ) \
320 TLS_VARIABLE ( desc, (version), field, 16, 0 )

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().

◆ TLS_VAR24

#define TLS_VAR24 ( desc,
version,
field )
Value:
TLS_VARIABLE ( desc, (version), field, 24, 0 )

Describe a variable-length field with a 24-bit length.

Parameters
descDescriptor structure name
versionMinimum TLS version that includes this field
fieldField name within descriptor structure

Definition at line 329 of file tlsfmt.h.

329#define TLS_VAR24( desc, version, field ) \
330 TLS_VARIABLE ( desc, (version), field, 24, 0 )

Referenced by TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().

◆ TLS_EXT16

#define TLS_EXT16 ( desc,
version,
field )
Value:
TLS_VARIABLE ( desc, (version), field.all, 16, \
( TLS_EXTNS ( desc, field ) + 1 ) )
#define TLS_EXTNS(desc, field)
Number of extensions of interest within an extension descriptor.
Definition tlsfmt.h:256

Describe a variable-length field containing extensions.

Parameters
descDescriptor structure name
versionMinimum TLS version that includes this field
fieldField name within descriptor structure

Definition at line 339 of file tlsfmt.h.

339#define TLS_EXT16( desc, version, field ) \
340 TLS_VARIABLE ( desc, (version), field.all, 16, \
341 ( TLS_EXTNS ( desc, field ) + 1 ) )

Referenced by TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().

◆ TLS_EXTND

#define TLS_EXTND ( desc,
extension,
field )
Value:
[ TLS_INDEX ( desc, field ) ] = \
( ( (extension) >> 8 ) ^ 0xff ), \
[ TLS_INDEX ( desc, field ) + 1 ] = \
( ( (extension) & 0xff ) ^ 0xff )

Describe a variable-length field containing an extension of interest.

Parameters
descDescriptor structure name
extensionExtension type
fieldField name within descriptor structure

Definition at line 350 of file tlsfmt.h.

350#define TLS_EXTND( desc, extension, field ) \
351 [ TLS_INDEX ( desc, field ) ] = \
352 ( ( (extension) >> 8 ) ^ 0xff ), \
353 [ TLS_INDEX ( desc, field ) + 1 ] = \
354 ( ( (extension) & 0xff ) ^ 0xff )

Referenced by TLS_DESCR_MAPPING(), and TLS_DESCR_MAPPING().

◆ TLS_MAP_MIN

#define TLS_MAP_MIN ( byte)
Value:
( TLS_VERSION_BASE + ( (byte) & 0x03 ) )
unsigned char byte
Definition smc9000.h:38

Interpret minimum version from an llllllvv byte.

Parameters
byteMapping byte
Return values
minMinimum TLS version that includes this field

Definition at line 362 of file tlsfmt.h.

Referenced by tls_build_map(), and tls_parse_map().

◆ TLS_MAP_FIXED

#define TLS_MAP_FIXED ( byte)
Value:
( ( (byte) >> 2 ) - 1 )

Interpret fixed length from an llllllvv byte.

Parameters
byteMapping byte
Return values
fixedFixed length

Definition at line 370 of file tlsfmt.h.

Referenced by tls_build_map(), and tls_parse_map().

◆ TLS_MAP_LEN_LEN

#define TLS_MAP_LEN_LEN ( byte)
Value:
( (byte) & 0x03 )

Interpret number of length bytes from an xxxxxxnn byte.

Parameters
byteMapping byte
Return values
len_lenNumber of length bytes

Definition at line 378 of file tlsfmt.h.

Referenced by tls_build_map(), and tls_parse_map().

◆ TLS_MAP_LEN_LEN_MAX

#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().

◆ TLS_MAP_EXTENSIONS

#define TLS_MAP_EXTENSIONS ( byte)
Value:
( ( (byte) >> 2 ) - 1 )

Interpret number of extensions from an xxxxxxnn byte.

Parameters
byteMapping byte
Return values
extensionsNumber of extensions

Definition at line 389 of file tlsfmt.h.

Referenced by tls_build_map(), and tls_parse_map().

◆ tls_parse

#define tls_parse ( type,
version,
cursor,
desc )
Value:
tls_parse_map ( type ## _map, (version), (cursor), \
( ( union tls_ptr_len * ) \
( (desc) == ( ( struct type * ) NULL ) ? \
(desc) : (desc) ) ) )
uint32_t type
Operating system type.
Definition ena.h:1
int tls_parse_map(const uint8_t *map, unsigned int version, const struct tls_cursor *cursor, union tls_ptr_len *desc)
Parse TLS data structure.
Definition tlsfmt.c:172

Parse TLS data structure.

Parameters
typeDescriptor structure name
versionProtocol version
cursorCursor containing TLS data structure
descData structure descriptor to fill in
Return values
rcReturn status code

Definition at line 733 of file tlsfmt.h.

733#define tls_parse( type, version, cursor, desc ) \
734 tls_parse_map ( type ## _map, (version), (cursor), \
735 ( ( union tls_ptr_len * ) \
736 ( (desc) == ( ( struct type * ) NULL ) ? \
737 (desc) : (desc) ) ) )

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().

◆ tls_parse_opt

#define tls_parse_opt ( type,
version,
cursor,
desc )
Value:
tls_parse_opt_map ( type ## _map, (version), (cursor), \
( ( union tls_ptr_len * ) \
( (desc) == ( ( struct type * ) NULL ) ? \
(desc) : (desc) ) ) )
int tls_parse_opt_map(const uint8_t *map, unsigned int version, const struct tls_cursor *cursor, union tls_ptr_len *desc)
Parse optional TLS data structure.
Definition tlsfmt.c:343

Parse optional TLS data structure.

Parameters
typeDescriptor structure name
versionProtocol version
cursorCursor containing TLS data structure
descData structure descriptor to fill in
Return values
rcReturn status code

Definition at line 748 of file tlsfmt.h.

748#define tls_parse_opt( type, version, cursor, desc ) \
749 tls_parse_opt_map ( type ## _map, (version), (cursor), \
750 ( ( union tls_ptr_len * ) \
751 ( (desc) == ( ( struct type * ) NULL ) ? \
752 (desc) : (desc) ) ) )

Referenced by tls_new_server_hello().

◆ tls_build

#define tls_build ( type,
version,
desc,
cursor )
Value:
tls_build_map ( type ## _map, (version), \
( ( union tls_ptr_len * ) \
( (desc) == ( ( struct type * ) NULL ) ? \
(desc) : (desc) ) ), (cursor) )
int tls_build_map(const uint8_t *map, unsigned int version, union tls_ptr_len *desc, struct tls_cursor *cursor)
Build TLS data structure.
Definition tlsfmt.c:468

Build TLS data structure.

Parameters
typeDescriptor structure name
versionProtocol version
descData structure descriptor to fill in
cursorCursor to contain TLS data structure
Return values
rcReturn status code

Definition at line 763 of file tlsfmt.h.

763#define tls_build( type, version, desc, cursor ) \
764 tls_build_map ( type ## _map, (version), \
765 ( ( union tls_ptr_len * ) \
766 ( (desc) == ( ( struct type * ) NULL ) ? \
767 (desc) : (desc) ) ), (cursor) )

Referenced by tls_build_extensions(), tls_client_hello(), tls_send_certificate(), tls_send_certificate_verify(), and tlsfmt_test_exec().

◆ tls_size

#define tls_size ( type,
version,
desc,
cursor )
Value:
tls_size_map ( type ## _map, (version), \
( ( union tls_ptr_len * ) \
( (desc) == ( ( struct type * ) NULL ) ? \
(desc) : (desc) ) ), (cursor) )
int tls_size_map(const uint8_t *map, unsigned int version, union tls_ptr_len *desc, struct tls_cursor *cursor)
Calculate length of TLS data structure.
Definition tlsfmt.c:658

Calculate length of TLS data structure.

Parameters
typeDescriptor structure name
versionProtocol version
descData structure descriptor to fill in
cursorCursor to contain TLS data structure
Return values
rcReturn status code

Definition at line 778 of file tlsfmt.h.

778#define tls_size( type, version, desc, cursor ) \
779 tls_size_map ( type ## _map, (version), \
780 ( ( union tls_ptr_len * ) \
781 ( (desc) == ( ( struct type * ) NULL ) ? \
782 (desc) : (desc) ) ), (cursor) )

Referenced by tls_client_hello(), tls_send_certificate(), tls_send_certificate_verify(), and tlsfmt_test_exec().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ tls_asn1()

const struct asn1_cursor * tls_asn1 ( const struct tls_cursor * cursor)
inlinestatic

Get ASN.1 cursor from TLS cursor.

Parameters
cursorTLS cursor
Return values
asn1ASN.1 object cursor

Definition at line 698 of file tlsfmt.h.

698 {
699 union {
700 const struct tls_cursor tls;
701 const struct asn1_cursor asn1;
702 } *u = container_of ( cursor, typeof ( *u ), tls );
703
704 /* Sanity check */
705 build_assert ( ( ( const void * ) &u->tls.data ) == &u->asn1.data );
706 build_assert ( &u->tls.len == &u->asn1.len );
707
708 return &u->asn1;
709}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
#define build_assert(condition)
Assert a condition at build time (after dead code elimination).
Definition assert.h:88
union @104331263140136355135267063077374276003064103115 u
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An ASN.1 object cursor.
Definition asn1.h:21

References build_assert, container_of, typeof(), and u.

Referenced by tls_verify_signature(), and tlsfmt_test_exec().

◆ tls_parse_map()

int tls_parse_map ( const uint8_t * map,
unsigned int version,
const struct tls_cursor * cursor,
union tls_ptr_len * desc )
extern

Parse TLS data structure.

Parameters
mapData structure descriptor mapping
versionProtocol version
cursorCursor containing TLS data structure
descData structure descriptor to fill in
Return values
rcReturn status code

Definition at line 172 of file tlsfmt.c.

174 {
175 struct tls_cursor *field;
176 void *data;
177 size_t remaining;
178 unsigned int count;
179 unsigned int index;
180 unsigned int next;
181 unsigned int byte;
182 unsigned int minimum;
183 unsigned int len_len;
184 unsigned int len;
185 int fixed;
186 int exts;
187 int rc;
188
189 /* Read initial cursor (may overlap output data structure) */
190 data = cursor->data;
191 remaining = cursor->len;
192 DBGC2 ( map, "TLSFMT %s parsing len %zd\n",
193 tls_map_name ( map ), remaining );
194 DBGC2_HDA ( map, 0, data, remaining );
195
196 /* Get mapping length */
197 count = map[0];
198 if ( ! count ) {
199 DBGC ( map, "TLSFMT %s mapping has no count\n",
200 tls_map_name ( map ) );
201 return -EINVAL;
202 }
203
204 /* Clear data structure descriptor */
205 memset ( desc, 0, ( ( count - 1 ) * sizeof ( desc[0] ) ) );
206
207 /* Parse data via mapping */
208 for ( index = 1 ; ( next = index ) < count ; index = next ) {
209
210 /* Prepare to store field description */
211 field = container_of ( &desc[ index - 1 ].data,
212 struct tls_cursor, data );
213
214 /* Interpret byte as `llllllvv` */
215 byte = map[next++];
216 minimum = TLS_MAP_MIN ( byte );
217 fixed = TLS_MAP_FIXED ( byte );
218 if ( fixed < 0 ) {
219 DBGC ( map, "TLSFMT %s #%d mapping missing\n",
220 tls_map_name ( map ), index );
221 return -EINVAL;
222 }
223 assert ( next <= count );
224
225 /* Handle fixed-length fields */
226 if ( fixed ) {
227 if ( version < minimum ) {
228 DBGC2 ( map, "TLSFMT %s #%d not in version "
229 "%d.%d\n", tls_map_name ( map ),
230 index, ( version >> 8 ),
231 ( version & 0xff ) );
232 continue;
233 }
234 if ( ( ( size_t ) fixed ) > remaining ) {
235 DBGC ( map, "TLSFMT %s #%d too short for "
236 "fixed length %d:\n",
237 tls_map_name ( map ), index, fixed );
238 DBGC_HDA ( map, 0, data, remaining );
239 return -EPROTO;
240 }
241 field->data = data;
242 DBGC2 ( map, "TLSFMT %s #%d len %d\n",
243 tls_map_name ( map ), index, fixed );
244 DBGC2_HDA ( map, 0, field->data, fixed );
245 data += fixed;
246 remaining -= fixed;
247 continue;
248 }
249
250 /* Interpret next byte as `xxxxxxnn` */
251 if ( next >= count ) {
252 DBGC ( map, "TLSFMT %s #%d mapping overrun\n",
253 tls_map_name ( map ), index );
254 return -EINVAL;
255 }
256 byte = map[next++];
257 len_len = TLS_MAP_LEN_LEN ( byte );
258 exts = TLS_MAP_EXTENSIONS ( byte );
259 if ( exts >= 0 )
260 next += ( exts * 2 );
261 if ( next > count ) {
262 DBGC ( map, "TLSFMT %s #%d mapping extensions "
263 "overrun\n", tls_map_name ( map ), index );
264 return -EINVAL;
265 }
266 if ( version < minimum ) {
267 DBGC2 ( map, "TLSFMT %s #%d not in version %d.%d\n",
268 tls_map_name ( map ), index, ( version >> 8 ),
269 ( version & 0xff ) );
270 continue;
271 }
272
273 /* Allow for optional extensions fields */
274 if ( ( exts >= 0 ) && ( ! remaining ) &&
276 DBGC2 ( map, "TLSFMT %s #%d optional in version "
277 "%d.%d\n", tls_map_name ( map ), index,
278 ( version >> 8 ), ( version & 0xff ) );
279 continue;
280 }
281
282 /* Handle variable-length fields */
283 if ( remaining < len_len ) {
284 DBGC ( map, "TLSFMT %s #%d too short for %d-byte "
285 "variable length:\n", tls_map_name ( map ),
286 index, len_len );
287 DBGC_HDA ( map, 0, data, remaining );
288 return -EPROTO;
289 }
290 if ( len_len ) {
291 for ( len = 0 ; len_len ; len_len-- ) {
292 len <<= 8;
293 len |= *( ( const uint8_t * ) data++ );
294 remaining--;
295 }
296 } else {
297 len = remaining;
298 }
299 if ( remaining < len ) {
300 DBGC ( map, "TLSFMT %s #%d too short for variable "
301 "length %d:\n",
302 tls_map_name ( map ), index, len );
303 DBGC_HDA ( map, 0, data, remaining );
304 return -EPROTO;
305 }
306 field->data = data;
307 field->len = len;
308 DBGC2 ( map, "TLSFMT %s #%d len %zd\n",
309 tls_map_name ( map ), index, field->len );
310 DBGC2_HDA ( map, 0, field->data, field->len );
311 data += len;
312 remaining -= len;
313 if ( exts < 0 )
314 continue;
315
316 /* Handle fields containing extensions */
317 if ( ( rc = tls_parse_extensions ( map, index, field,
318 exts ) ) != 0 ) {
319 return rc;
320 }
321 }
322
323 /* Check that all data was consumed */
324 if ( remaining ) {
325 DBGC ( map, "TLSFMT %s has excess data:\n",
326 tls_map_name ( map ) );
327 DBGC_HDA ( map, 0, data, remaining );
328 return -EPROTO;
329 }
330
331 return 0;
332}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
long index
Definition bigint.h:30
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
uint32_t next
Next descriptor address.
Definition dwmac.h:11
ring len
Length.
Definition dwmac.h:226
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition eltorito.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC2(...)
Definition compiler.h:547
#define DBGC2_HDA(...)
Definition compiler.h:548
#define DBGC(...)
Definition compiler.h:530
#define DBGC_HDA(...)
Definition compiler.h:531
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define EINVAL
Invalid argument.
Definition errno.h:472
#define EPROTO
Protocol error.
Definition errno.h:668
void * memset(void *dest, int character, size_t len) __nonnull
static __always_inline int struct dma_mapping * map
Definition dma.h:184
void * data
Data.
Definition tlsfmt.h:188
size_t len
Length of data.
Definition tlsfmt.h:190
static int tls_parse_extensions(const uint8_t *map, unsigned int index, struct tls_cursor *fields, unsigned int count)
Parse TLS extensions within a data structure.
Definition tlsfmt.c:111
static const char * tls_map_name(const uint8_t *map)
Get data structure descriptor mapping name (for debugging).
Definition tlsfmt.c:45
#define TLS_MAP_FIXED(byte)
Interpret fixed length from an llllllvv byte.
Definition tlsfmt.h:370
#define TLS_VERSION_TLS_1_3
TLS version 1.3.
Definition tlsfmt.h:180
#define TLS_MAP_EXTENSIONS(byte)
Interpret number of extensions from an xxxxxxnn byte.
Definition tlsfmt.h:389
#define TLS_MAP_MIN(byte)
Interpret minimum version from an llllllvv byte.
Definition tlsfmt.h:362
#define TLS_MAP_LEN_LEN(byte)
Interpret number of length bytes from an xxxxxxnn byte.
Definition tlsfmt.h:378

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().

◆ tls_parse_opt_map()

int tls_parse_opt_map ( const uint8_t * map,
unsigned int version,
const struct tls_cursor * cursor,
union tls_ptr_len * desc )
extern

Parse optional TLS data structure.

Parameters
mapData structure descriptor mapping
versionProtocol version
cursorCursor containing TLS data structure
descData structure descriptor to fill in
Return values
rcReturn status code

Definition at line 343 of file tlsfmt.c.

345 {
346 unsigned int count;
347 int rc;
348
349 /* Get mapping length */
350 count = map[0];
351 if ( ! count ) {
352 DBGC ( map, "TLSFMT %s mapping has no count\n",
353 tls_map_name ( map ) );
354 return -EINVAL;
355 }
356
357 /* Clear data structure descriptor */
358 memset ( desc, 0, ( ( count - 1 ) * sizeof ( desc[0] ) ) );
359
360 /* Do nothing if optional data structure is not present */
361 if ( ! cursor->data )
362 return 0;
363
364 /* Parse data structure */
365 if ( ( rc = tls_parse_map ( map, version, cursor, desc ) ) != 0 )
366 return rc;
367
368 return 0;
369}

References count, tls_cursor::data, DBGC, desc, EINVAL, map, memset(), rc, tls_map_name(), tls_parse_map(), and version.

Referenced by tls_new_server_hello().

◆ tls_build_map()

int tls_build_map ( const uint8_t * map,
unsigned int version,
union tls_ptr_len * desc,
struct tls_cursor * cursor )
extern

Build TLS data structure.

Parameters
mapData structure descriptor mapping
versionProtocol version
descData structure descriptor
cursorCursor to contain TLS data structure
Return values
rcReturn 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 468 of file tlsfmt.c.

469 {
470 struct tls_cursor *field;
471 void *data;
472 size_t len;
473 size_t max;
474 unsigned int count;
475 unsigned int index;
476 unsigned int next;
477 unsigned int byte;
478 unsigned int minimum;
479 unsigned int len_len;
480 int fixed;
481 int exts;
482 int rc;
483
484 /* Read initial cursor (may overlap output data structure) */
485 data = cursor->data;
486 len = 0;
487
488 /* Get mapping length */
489 count = map[0];
490 if ( ! count ) {
491 DBGC ( map, "TLSFMT %s mapping has no count\n",
492 tls_map_name ( map ) );
493 return -EINVAL;
494 }
495
496 /* Accumulate total length via mapping */
497 for ( index = 1 ; ( next = index ) < count ; index = next ) {
498
499 /* Prepare to read field description */
500 field = container_of ( &desc[ index - 1 ].data,
501 struct tls_cursor, data );
502
503 /* Interpret byte as `llllllvv` */
504 byte = map[next++];
505 minimum = TLS_MAP_MIN ( byte );
506 fixed = TLS_MAP_FIXED ( byte );
507 if ( fixed < 0 ) {
508 DBGC ( map, "TLSFMT %s #%d mapping missing\n",
509 tls_map_name ( map ), index );
510 return -EINVAL;
511 }
512 assert ( next <= count );
513
514 /* Handle fixed-length fields */
515 if ( fixed ) {
516 if ( version < minimum ) {
517 DBGC2 ( map, "TLSFMT %s #%d not in version "
518 "%d.%d\n", tls_map_name ( map ),
519 index, ( version >> 8 ),
520 ( version & 0xff ) );
521 continue;
522 }
523 DBGC2 ( map, "TLSFMT %s #%d len %d\n",
524 tls_map_name ( map ), index, fixed );
525 len += fixed;
526 if ( data ) {
527 if ( field->data ) {
528 memcpy ( data, field->data, fixed );
529 } else {
530 memset ( data, 0, fixed );
531 }
532 field->data = data;
533 data += fixed;
534 DBGC2_HDA ( map, 0, field->data, fixed );
535 }
536 continue;
537 }
538
539 /* Interpret next byte as `xxxxxxnn` */
540 if ( next >= count ) {
541 DBGC ( map, "TLSFMT %s #%d mapping overrun\n",
542 tls_map_name ( map ), index );
543 return -EINVAL;
544 }
545 byte = map[next++];
546 len_len = TLS_MAP_LEN_LEN ( byte );
547 exts = TLS_MAP_EXTENSIONS ( byte );
548 if ( exts >= 0 )
549 next += ( exts * 2 );
550 if ( next > count ) {
551 DBGC ( map, "TLSFMT %s #%d mapping extensions "
552 "overrun\n", tls_map_name ( map ), index );
553 return -EINVAL;
554 }
555 if ( version < minimum ) {
556 DBGC2 ( map, "TLSFMT %s #%d not in version %d.%d\n",
557 tls_map_name ( map ), index, ( version >> 8 ),
558 ( version & 0xff ) );
559 continue;
560 }
561
562 /* Handle variable-length fields */
563 max = ( len_len ? ( ( 1 << ( 8 * len_len ) ) - 1 ) :
564 ( ( 1 << ( 8 * TLS_MAP_LEN_LEN_MAX ) ) - 1 ) );
565 if ( exts >= 0 ) {
566 field->data = ( data ? ( data + len_len ) : NULL );
567 if ( ( rc = tls_build_extensions ( map, index, field,
568 exts ) ) != 0 ) {
569 return rc;
570 }
571 }
572 if ( field->len > max ) {
573 DBGC ( map, "TLSFMT %s #%d len %zd too long\n",
574 tls_map_name ( map ), index, field->len );
575 return -ERANGE;
576 }
577
578 /* Allow for optional extensions fields */
579 if ( ( exts >= 0 ) && ( ! field->len ) &&
581 DBGC2 ( map, "TLSFMT %s #%d optional in version "
582 "%d.%d\n", tls_map_name ( map ), index,
583 ( version >> 8 ), ( version & 0xff ) );
584 continue;
585 }
586
587 /* Build field */
588 DBGC2 ( map, "TLSFMT %s #%d len %zd\n",
589 tls_map_name ( map ), index, field->len );
590 len += ( len_len + field->len );
591 if ( data ) {
592 while ( len_len-- ) {
593 *( ( uint8_t * ) data++ ) =
594 ( field->len >> ( 8 * len_len ) );
595 }
596 if ( exts < 0 ) {
597 if ( field->data ) {
598 memcpy ( data, field->data,
599 field->len );
600 } else {
601 memset ( data, 0, field->len );
602 }
603 }
604 field->data = data;
605 data += field->len;
606 DBGC2_HDA ( map, 0, field->data, field->len );
607 }
608 }
609
610 /* Update cursor (may overlap output data structure) */
611 cursor->len = len;
612 DBGC2 ( map, "TLSFMT %s built len %zd\n",
613 tls_map_name ( map ), cursor->len );
614 if ( data )
615 DBGC2_HDA ( map, 0, ( data - cursor->len ), cursor->len );
616
617 return 0;
618}
#define max(x, y)
Definition ath.h:41
#define ERANGE
Result too large.
Definition errno.h:683
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int tls_build_extensions(const uint8_t *map, unsigned int index, struct tls_cursor *fields, unsigned int count)
Build TLS extensions within a data structure.
Definition tlsfmt.c:380
#define TLS_MAP_LEN_LEN_MAX
Maximum number of length bytes.
Definition tlsfmt.h:381

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_send_client_key_exchange(), and tls_size_map().

◆ tls_size_map()

int tls_size_map ( const uint8_t * map,
unsigned int version,
union tls_ptr_len * desc,
struct tls_cursor * cursor )
extern

Calculate length of TLS data structure.

Parameters
typeDescriptor structure name
versionProtocol version
descData structure descriptor to fill in
cursorCursor to contain TLS data structure
Return values
rcReturn status code

The cursor size will be set to the overall length required to contain the TLS data structure, and the cursor data pointer will be set to NULL.

If this function returns successfully, then a subsequent call to tls_build() with the exact same inputs is guaranteed to succeed and need not be checked for an error return status. The data structure descriptor must not be modified in any way that would affect its length before calling tls_build(): the easiest way to ensure this is to not modify the data structure descriptor at all.

If this function fails, then the cursor length will be set to a value that is too large to be represented by a 24-bit length field. If the cursor itself lies within a containing data structure descriptor (e.g. if tls_size() is being used to calculate the size of an extension within a ClientHello descriptor), then this guarantees that a subsequent call to tls_size() on the containing descriptor will also fail. The caller therefore need only check the return status code from the call to tls_size() for the outermost descriptor.

Note that this optimisation applies only when the result cursor lies within a containing data structure descriptor and so is guaranteed to be consumed by a subsequent call to calculate the length of that containing TLS data structure. If a caller is using the result from tls_size() in any other way (e.g. to add up the lengths of a sequence of CertificateEntry structures), then the caller must check the return status code in the normal way.

Definition at line 658 of file tlsfmt.c.

659 {
660 int rc;
661
662 /* Calculate length */
663 cursor->data = NULL;
664 if ( ( rc = tls_build_map ( map, version, desc, cursor ) ) != 0 ) {
665 /* Set an uncontainable length on error */
666 cursor->len = -1UL;
667 return rc;
668 }
669
670 return 0;
671}

References tls_cursor::data, desc, tls_cursor::len, map, NULL, rc, tls_build_map(), and version.

Referenced by tls_send_client_key_exchange().

◆ TLS_DESCR_MAPPING() [1/27]

TLS_DESCR_MAPPING ( tls_certificate )
extern

◆ TLS_DESCR_MAPPING() [2/27]

TLS_DESCR_MAPPING ( tls_certificate_entry )
extern

◆ TLS_DESCR_MAPPING() [3/27]

TLS_DESCR_MAPPING ( tls_client_hello )
extern

◆ TLS_DESCR_MAPPING() [4/27]

TLS_DESCR_MAPPING ( tls_client_key_exchange_dhe )
extern

◆ TLS_DESCR_MAPPING() [5/27]

TLS_DESCR_MAPPING ( tls_client_key_exchange_ecdhe )
extern

◆ TLS_DESCR_MAPPING() [6/27]

TLS_DESCR_MAPPING ( tls_client_key_exchange_pubkey )
extern

◆ TLS_DESCR_MAPPING() [7/27]

TLS_DESCR_MAPPING ( tls_digitally_signed )
extern

◆ TLS_DESCR_MAPPING() [8/27]

TLS_DESCR_MAPPING ( tls_extension )
extern

◆ TLS_DESCR_MAPPING() [9/27]

TLS_DESCR_MAPPING ( tls_hello_request )
extern

◆ TLS_DESCR_MAPPING() [10/27]

TLS_DESCR_MAPPING ( tls_key_share_client_hello )
extern

◆ TLS_DESCR_MAPPING() [11/27]

TLS_DESCR_MAPPING ( tls_key_share_entry )
extern

◆ TLS_DESCR_MAPPING() [12/27]

TLS_DESCR_MAPPING ( tls_key_share_hello_retry_request )
extern

◆ TLS_DESCR_MAPPING() [13/27]

TLS_DESCR_MAPPING ( tls_key_share_server_hello )
extern

◆ TLS_DESCR_MAPPING() [14/27]

TLS_DESCR_MAPPING ( tls_max_fragment_length )
extern

◆ TLS_DESCR_MAPPING() [15/27]

TLS_DESCR_MAPPING ( tls_named_group_list )
extern

◆ TLS_DESCR_MAPPING() [16/27]

TLS_DESCR_MAPPING ( tls_new_session_ticket )
extern

◆ TLS_DESCR_MAPPING() [17/27]

TLS_DESCR_MAPPING ( tls_psk_key_exchange_modes )
extern

◆ TLS_DESCR_MAPPING() [18/27]

TLS_DESCR_MAPPING ( tls_renegotiation_info )
extern

◆ TLS_DESCR_MAPPING() [19/27]

TLS_DESCR_MAPPING ( tls_server_hello )
extern

◆ TLS_DESCR_MAPPING() [20/27]

TLS_DESCR_MAPPING ( tls_server_hello_done )
extern

◆ TLS_DESCR_MAPPING() [21/27]

TLS_DESCR_MAPPING ( tls_server_key_exchange_dhe )
extern

◆ TLS_DESCR_MAPPING() [22/27]

TLS_DESCR_MAPPING ( tls_server_key_exchange_ecdhe )
extern

◆ TLS_DESCR_MAPPING() [23/27]

TLS_DESCR_MAPPING ( tls_server_name )
extern

◆ TLS_DESCR_MAPPING() [24/27]

TLS_DESCR_MAPPING ( tls_server_name_list )
extern

◆ TLS_DESCR_MAPPING() [25/27]

TLS_DESCR_MAPPING ( tls_signature_scheme_list )
extern

◆ TLS_DESCR_MAPPING() [26/27]

TLS_DESCR_MAPPING ( tls_supported_version )
extern

◆ TLS_DESCR_MAPPING() [27/27]

TLS_DESCR_MAPPING ( tls_supported_versions )
extern