# Trying to understand the struct HkdfLabel from tls1.3 RFC8446

I'm looking at RFC 8446 section 7.1 and trying to understand the following:

HKDF-Expand-Label(Secret, Label, Context, Length) =
HKDF-Expand(Secret, HkdfLabel, Length)

Where HkdfLabel is specified as:

struct {
uint16 length = Length;
opaque label<7..255> = "tls13 " + Label;
opaque context<0..255> = Context;
} HkdfLabel;

Derive-Secret(Secret, Label, Messages) =
HKDF-Expand-Label(Secret, Label,
Transcript-Hash(Messages), Hash.length)


HkdfLabel appears to be a concatenation of a few fields, to make it "fit" into the signature of Hkdf.Expand(...). A few things I'm unclear on:

• Are the pieces that make up the struct of HkdfLabel expected to be concatenated in the order they're defined? e.g. length||label||context
• length = the hash length in bytes?
• the first 0..6 bits of label are not specified, assuming 0?
• "tls13 " + Label may be more or less bits than 7..255 allows for the assignment to label. Is the expectation that it's zeroes if not long enough, or truncated to 256 bits if too long?
• same basic uncertainty around context, is the idea that context will always be exactly 256 bits?
• Assuming the above is correct, does that mean HkdfLabel will always be exactly 528 bits?
• HkdfLabel = hashLength<0..15>||label<0..255>||context<0..255>
• The RFC should be self-explaining. Your questions are not exactly fitting our scope. Here the implementation from BoringSSL that may help your cause. – kelalaka Jul 7 '20 at 19:04

Section 3 explains the data structures and their representation as octet strings (or byte strings: this RFC uses “octet” and “byte” interchangeably). See in particular §3.1:

Multiple-byte data items are concatenations of bytes, from left to right, from top to bottom.

An HkdfLabel is the concatenation of 2 bytes for length (big-endian, see §3.3), 7 to 255 bytes for label, and 0 to 255 bytes for context. §3.4 explains the notation <7..255> it means between 7 and 255 bytes inclusive. The length of the HkdfLabel can therefore be anywhere from 9 to 514 bytes.

The length field in the HkdfLabel returned by HKDF-Expand-Label is the value that was passed as the Length argument. When it's called from Derived-Secret, this is the length of the hash in bytes (not bits) (§7.1: “Hash.length is its output length in bytes”).

The first 6 bytes of label are 74 6c 73 31 33 20, the ASCII encoding of "tls 13" (§7.1: “The labels specified in this document are all ASCII strings”).

"tls13 " + Label is the concatenation of a 6-byte string with Label. Since the result must be at least 7 bytes long, this effectively forbids empty labels, which I can't find stated explicitly anywhere. There is no padding or truncation. Note that once again, these are lengths in bytes (octets), not bits. The label must also be at most 249 bytes long to fit.

Context can be anywhere from 0 to 255 bytes