Function hpke::KeySchedule
source · [−]pub fn KeySchedule(
config: HPKEConfig,
shared_secret: &SharedSecret,
info: &Info,
psk: &Psk,
psk_id: &PskId
) -> ContextResult
Expand description
Creating the Encryption Context
The variants of HPKE defined in this document share a common key schedule that translates the protocol inputs into an encryption context. The key schedule inputs are as follows:
mode
- A one-byte value indicating the HPKE mode, defined inMode
.shared_secret
- A KEM shared secret generated for this transaction.info
- Application-supplied information (optional; default value “”).psk
- A pre-shared key (PSK) held by both the sender and the recipient (optional; default value “”).psk_id
- An identifier for the PSK (optional; default value “”).
Senders and recipients MUST validate KEM inputs and outputs as described
in KEM
.
The psk
and psk_id
fields MUST appear together or not at all.
That is, if a non-default value is provided for one of them, then
the other MUST be set to a non-default value. This requirement is
encoded in VerifyPSKInputs()
below.
The psk
, psk_id
, and info
fields have maximum lengths that depend
on the KDF itself, on the definition of LabeledExtract()
, and on the
constant labels used together with them. See KDF Input Length for
precise limits on these lengths.
The key
, base_nonce
, and exporter_secret
computed by the key schedule
have the property that they are only known to the holder of the recipient
private key, and the entity that used the KEM to generate shared_secret
and
enc
.
In the Auth and AuthPSK modes, the recipient is assured that the sender
held the private key skS
. This assurance is limited for the DHKEM
variants defined in this document because of key-compromise impersonation,
as described in hpke_kem
and the security properties section. If in the PSK and
AuthPSK modes, the psk
and psk_id
arguments are provided as required,
then the recipient is assured that the sender held the corresponding
pre-shared key. See the security properties section on the module page for more details.
The HPKE algorithm identifiers, i.e., the KEM kem_id
, KDF kdf_id
, and
AEAD aead_id
2-byte code points as defined in KEM
, KDF
,
and AEAD
, respectively, are assumed implicit from the implementation
and not passed as parameters.
def KeySchedule<ROLE>(mode, shared_secret, info, psk, psk_id):
VerifyPSKInputs(mode, psk, psk_id)
psk_id_hash = LabeledExtract("", "psk_id_hash", psk_id)
info_hash = LabeledExtract("", "info_hash", info)
key_schedule_context = concat(mode, psk_id_hash, info_hash)
secret = LabeledExtract(shared_secret, "secret", psk)
key = LabeledExpand(secret, "key", key_schedule_context, Nk)
base_nonce = LabeledExpand(secret, "base_nonce",
key_schedule_context, Nn)
exporter_secret = LabeledExpand(secret, "exp",
key_schedule_context, Nh)
return Context<ROLE>(key, base_nonce, 0, exporter_secret)
The ROLE
template parameter is either S or R, depending on the role of
sender or recipient, respectively. See HPKE DEM for a discussion of the
key schedule output, including the role-specific Context
structure and its API.
Note that the key_schedule_context
construction in KeySchedule()
is
equivalent to serializing a structure of the following form in the TLS presentation
syntax:
struct {
uint8 mode;
opaque psk_id_hash[Nh];
opaque info_hash[Nh];
} KeyScheduleContext;
This function takes the <MODE>
as argument in HPKEConfig
.