iPXE
tlskey.h File Reference

TLS key schedules. More...

#include <stdint.h>
#include <ipxe/crypto.h>

Go to the source code of this file.

Data Structures

struct  tls_endpoint
 A TLS endpoint. More...
struct  tls_random
 TLS client or server random bytes. More...
struct  tls_transcript
 A TLS running handshake transcript digest. More...
struct  tls_kdf_secret
 A TLS key derivation function secret. More...
struct  tls_traffic_secret
 A TLS traffic secret. More...
struct  tls_key_schedule
 A TLS key schedule. More...
struct  tls_preshared_key
 A TLS pre-shared key. More...
struct  tls_key_schedule_operations
 TLS key schedule operations. More...

Macros

#define TLS_CLIENT   0
 Client endpoint index.
#define TLS_SERVER   1
 Server endpoint index.
#define TLS_RANDOM_LEN   32
 Number of random bytes.
#define TLSKEY_TSF_NONCED   0x0001
 Transcript digest includes a Hello record containing the local nonce.
#define TLSKEY_TSF_FINISHED   0x0002
 Transcript digest includes a Finished record.
#define TLSKEY_KDF_KEYED   0x0001
 Key derivation function has key material.
#define TLSKEY_KDF_MASTER   0x0002
 Key derivation function has a master secret.
#define TLSKEY_KDF_EMS   0x0004
 Key derivation function has an extended master secret.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int tlskey_is_accumulating (struct tls_key_schedule *tlskey)
 Check if key schedule accumulates shared secrets.
int tlskey_start (struct tls_key_schedule *tlskey, const struct tls_key_schedule_operations *op, struct digest_algorithm *digest, const struct tls_random *random)
 Start key schedule.
void tlskey_stop (struct tls_key_schedule *tlskey)
 Stop key schedule.
void tlskey_digest (struct tls_key_schedule *tlskey, const void *data, size_t len)
 Add handshake to running transcript digest.
void tlskey_reset (struct tls_key_schedule *tlskey)
 Reset key schedule.
int tlskey_apply (struct tls_key_schedule *tlskey, const void *shared, size_t shared_len)
 Apply a new shared secret.
int tlskey_master (struct tls_key_schedule *tlskey, int ems)
 Generate master secret.
int tlskey_verify (struct tls_key_schedule *tlskey, const struct tls_endpoint *end, void *verify, size_t verify_len)
 Generate verification data.
int tlskey_traffic (struct tls_key_schedule *tlskey, const struct tls_endpoint *writer, const struct tls_phase *phase)
 Generate traffic secret.
int tlskey_cipher (struct tls_key_schedule *tlskey, const struct tls_endpoint *writer, void *key, size_t key_len, void *iv, size_t iv_len, void *mac, size_t mac_len)
 Generate cipher key material.
int tlskey_tbshash (struct tls_key_schedule *tlskey, const struct tls_endpoint *end, struct digest_algorithm *digest, const void *data, size_t len, void *tbs)
 Generate signable digest value.
int tlskey_save (struct tls_key_schedule *tlskey, const void *nonce, size_t nonce_len, struct tls_preshared_key *psk)
 Save pre-shared key.
int tlskey_load (struct tls_key_schedule *tlskey, int ems, const struct tls_preshared_key *psk)
 Load pre-shared key.
int tlskey_bind (const struct tls_preshared_key *psk, const void *prefix, size_t prefix_len, void *binder, size_t binder_len)
 Generate pre-shared key binder value.

Variables

const struct tls_endpoint tls_client
 Client endpoint.
const struct tls_endpoint tls_server
 Server endpoint.
const struct tls_phase tls_early
 Early traffic phase.
const struct tls_phase tls_handshake
 Handshake traffic phase.
const struct tls_phase tls_application
 Application traffic phase.
const struct tls_key_schedule_operations tlskey_hkdf
 TLS key schedule based on HKDF.
const struct tls_key_schedule_operations tlskey_hash
 TLS key schedule based on P_Hash().
const struct tls_key_schedule_operations tlskey_md5_sha1
 TLS key schedule based on P_MD5()+P_SHA1().

Detailed Description

TLS key schedules.

Definition in file tlskey.h.

Macro Definition Documentation

◆ TLS_CLIENT

#define TLS_CLIENT   0

◆ TLS_SERVER

#define TLS_SERVER   1

◆ TLS_RANDOM_LEN

#define TLS_RANDOM_LEN   32

Number of random bytes.

Definition at line 33 of file tlskey.h.

◆ TLSKEY_TSF_NONCED

#define TLSKEY_TSF_NONCED   0x0001

Transcript digest includes a Hello record containing the local nonce.

Definition at line 69 of file tlskey.h.

Referenced by tlskey_hash_master(), tlskey_hello(), tlskey_tbshash(), and tlskey_verify().

◆ TLSKEY_TSF_FINISHED

#define TLSKEY_TSF_FINISHED   0x0002

Transcript digest includes a Finished record.

Definition at line 72 of file tlskey.h.

Referenced by tlskey_digest(), and tlskey_finished().

◆ TLSKEY_KDF_KEYED

#define TLSKEY_KDF_KEYED   0x0001

Key derivation function has key material.

Definition at line 83 of file tlskey.h.

Referenced by tlskey_apply(), tlskey_master(), and tlskey_traffic().

◆ TLSKEY_KDF_MASTER

#define TLSKEY_KDF_MASTER   0x0002

Key derivation function has a master secret.

Definition at line 86 of file tlskey.h.

Referenced by tlskey_apply(), tlskey_hash_verify(), tlskey_load(), tlskey_master(), and tlskey_save().

◆ TLSKEY_KDF_EMS

#define TLSKEY_KDF_EMS   0x0004

Key derivation function has an extended master secret.

Definition at line 89 of file tlskey.h.

Referenced by tlskey_load(), and tlskey_master().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ tlskey_is_accumulating()

int tlskey_is_accumulating ( struct tls_key_schedule * tlskey)
inlinestatic

Check if key schedule accumulates shared secrets.

Parameters
tlskeyKey schedule
Return values
is_accumulatingKey schedule accumulates all shared secrets

Definition at line 329 of file tlskey.h.

329 {
330 const struct tls_key_schedule_operations *op = tlskey->op;
331
332 return ( op && op->accumulates );
333}
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327
TLS key schedule operations.
Definition tlskey.h:170
const struct tls_key_schedule_operations * op
Key schedule operations.
Definition tlskey.h:102

References op, and tls_key_schedule::op.

Referenced by tls_channel_apply().

◆ tlskey_start()

int tlskey_start ( struct tls_key_schedule * tlskey,
const struct tls_key_schedule_operations * op,
struct digest_algorithm * digest,
const struct tls_random * nonce )
extern

Start key schedule.

Parameters
tlskeyKey schedule
opKey schedule operations
digestDigest algorithm
nonceLocal endpoint random bytes
Return values
rcReturn status code

The random bytes must be the random bytes that the local endpoint will subsequently incorporate within its own ClientHello (or ServerHello, if acting as a server). The caller must guarantee that these are fresh and are unpredictable by the peer. A freshly generated secure channel ephemeral secret can be used to fulfil this requirement.

Definition at line 180 of file tlskey.c.

183 {
184 size_t digestsize = digest->digestsize;
185 size_t ctxsize = digest->ctxsize;
186 size_t secretsize;
187 size_t total;
188 void *dynamic;
189 int rc;
190
191 /* Stop any existing running key schedule */
192 tlskey_stop ( tlskey );
193
194 /* Sanity check */
195 if ( ! digestsize ) {
196 rc = -ENOTTY;
197 goto err_sanity;
198 }
199
200 /* Determine required sizes */
201 secretsize = op->secretsize ( digest );
202 if ( ! secretsize ) {
203 DBGC ( tlskey, "TLSKEY %p cannot use %s with %s\n",
204 tlskey, op->name, digest->name );
205 rc = -ENOTSUP;
206 goto err_secretsize;
207 }
208 total = ( secretsize + /* secret */
209 ctxsize + /* transcript.ctx */
210 digestsize + /* transcript.running */
211 digestsize /* transcript.finishing */ );
212
213 /* Allocate dynamic storage */
214 dynamic = zalloc ( total );
215 if ( ! dynamic ) {
216 rc = -ENOMEM;
217 goto err_alloc;
218 }
219
220 /* Initialise schedule */
221 tlskey->op = op;
222 tlskey->digest = digest;
223 tlskey->secretsize = secretsize;
224 DBGC ( tlskey, "TLSKEY %p using %s with %s\n",
225 tlskey, tlskey->op->name, tlskey->digest->name );
226
227 /* Assign dynamic storage */
228 tlskey->dynamic = dynamic;
229 tlskey->secret = dynamic; dynamic += secretsize;
230 tlskey->transcript.ctx = dynamic; dynamic += ctxsize;
231 tlskey->transcript.running = dynamic; dynamic += digestsize;
232 tlskey->transcript.finishing = dynamic; dynamic += digestsize;
233 assert ( dynamic == ( tlskey->dynamic + total ) );
234
235 /* Initialise transcript digest */
236 digest_init ( digest, tlskey->transcript.ctx );
237 tlskey_digest ( tlskey, NULL, 0 );
238 memcpy ( &tlskey->nonce, nonce, sizeof ( tlskey->nonce ) );
239 DBGC ( tlskey, "TLSKEY %p local nonce:\n", tlskey );
240 DBGC_HDA ( tlskey, 0, &tlskey->nonce, sizeof ( tlskey->nonce ) );
241
242 /* Reset key schedule */
243 tlskey_reset ( tlskey );
244
245 return 0;
246
247 tlskey_stop ( tlskey );
248 err_alloc:
249 err_secretsize:
250 err_sanity:
251 return rc;
252}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
#define DBGC(...)
Definition compiler.h:530
#define DBGC_HDA(...)
Definition compiler.h:531
#define ENOMEM
Not enough space.
Definition errno.h:578
#define ENOTSUP
Operation not supported.
Definition errno.h:633
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:638
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:294
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
uint32_t digestsize
Digest size (i.e.
Definition pccrr.h:1
size_t digestsize
Digest size.
Definition crypto.h:27
size_t ctxsize
Context size.
Definition crypto.h:23
const char * name
Algorithm name.
Definition crypto.h:21
const char * name
Name.
Definition tlskey.h:172
void * secret
Secret(s).
Definition tlskey.h:111
size_t secretsize
Secret size.
Definition tlskey.h:106
struct tls_transcript transcript
Running handshake transcript digest.
Definition tlskey.h:116
struct tls_random nonce
Local endpoint random bytes.
Definition tlskey.h:118
struct digest_algorithm * digest
Digest algorithm.
Definition tlskey.h:104
void * dynamic
Dynamically-allocated storage.
Definition tlskey.h:109
void * finishing
Running digest value up to the most recent Finished (if any).
Definition tlskey.h:63
void * running
Running digest value.
Definition tlskey.h:52
void * ctx
Digest context.
Definition tlskey.h:44
void tlskey_stop(struct tls_key_schedule *tlskey)
Stop key schedule.
Definition tlskey.c:259
void tlskey_reset(struct tls_key_schedule *tlskey)
Reset key schedule.
Definition tlskey.c:492
void tlskey_digest(struct tls_key_schedule *tlskey, const void *data, size_t len)
Add handshake to running transcript digest.
Definition tlskey.c:416
u8 nonce[32]
Nonce value.
Definition wpa.h:25

References assert, tls_transcript::ctx, digest_algorithm::ctxsize, DBGC, DBGC_HDA, tls_key_schedule::digest, digest_init(), digest_algorithm::digestsize, digestsize, tls_key_schedule::dynamic, ENOMEM, ENOTSUP, ENOTTY, tls_transcript::finishing, memcpy(), digest_algorithm::name, tls_key_schedule_operations::name, nonce, tls_key_schedule::nonce, NULL, op, tls_key_schedule::op, rc, tls_transcript::running, tls_key_schedule::secret, tls_key_schedule::secretsize, tlskey_digest(), tlskey_reset(), tlskey_stop(), tls_key_schedule::transcript, and zalloc().

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), and tls_set_digest().

◆ tlskey_stop()

void tlskey_stop ( struct tls_key_schedule * tlskey)
extern

Stop key schedule.

Parameters
tlskeyKey schedule

Definition at line 259 of file tlskey.c.

259 {
260
261 /* Clear and free any dynamic storage */
262 zfree ( tlskey->dynamic );
263
264 /* Clear key schedule contents */
265 memset ( tlskey, 0, sizeof ( *tlskey ) );
266
267 /* Set null digest algorithm */
268 tlskey->digest = &digest_null;
269}
struct digest_algorithm digest_null
Definition crypto_null.c:53
void * memset(void *dest, int character, size_t len) __nonnull
void zfree(void *ptr)
Clear and free memory.
Definition malloc.c:738

References tls_key_schedule::digest, digest_null, tls_key_schedule::dynamic, memset(), and zfree().

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), tls_clear_digest(), and tlskey_start().

◆ tlskey_digest()

void tlskey_digest ( struct tls_key_schedule * tlskey,
const void * data,
size_t len )
extern

Add handshake to running transcript digest.

Parameters
tlskeyKey schedule
dataHandshake record
lenLength of handshake record

Definition at line 416 of file tlskey.c.

417 {
418 struct tls_transcript *transcript = &tlskey->transcript;
419 struct digest_algorithm *digest = tlskey->digest;
420 size_t digestsize = digest->digestsize;
421 size_t ctxsize = digest->ctxsize;
422 unsigned int flags;
423 struct {
425 } tmp;
426
427 /* Append to running transcript digest */
428 digest_update ( digest, transcript->ctx, data, len );
429
430 /* Update running transcript digest output */
431 memcpy ( tmp.ctx, transcript->ctx, ctxsize );
432 digest_final ( digest, tmp.ctx, transcript->running );
433
434 /* Process digested handshake record */
435 flags = tlskey_handshake ( tlskey, data, len );
436 transcript->flags |= flags;
437
438 /* Update the finishing digest value, if applicable */
439 if ( ! ( ( transcript->flags ^ flags ) & TLSKEY_TSF_FINISHED ) ) {
440 memcpy ( transcript->finishing, transcript->running,
441 digestsize );
442 }
443
444 /* Clear temporary secrets */
445 memset ( &tmp, 0, sizeof ( tmp ) );
446}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
unsigned char uint8_t
Definition stdint.h:10
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t flags
Flags.
Definition ena.h:7
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:305
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:299
unsigned long tmp
Definition linux_pci.h:65
A message digest algorithm.
Definition crypto.h:19
A TLS running handshake transcript digest.
Definition tlskey.h:42
unsigned int flags
Transcript flags.
Definition tlskey.h:65
static unsigned int tlskey_handshake(struct tls_key_schedule *tlskey, const void *data, size_t len)
Process digested handshake record.
Definition tlskey.c:385
#define TLSKEY_TSF_FINISHED
Transcript digest includes a Finished record.
Definition tlskey.h:72

References ctx, tls_transcript::ctx, digest_algorithm::ctxsize, data, tls_key_schedule::digest, digest_final(), digest_update(), digest_algorithm::digestsize, digestsize, tls_transcript::finishing, flags, tls_transcript::flags, len, memcpy(), memset(), tls_transcript::running, tlskey_handshake(), TLSKEY_TSF_FINISHED, tmp, and tls_key_schedule::transcript.

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), tls_add_handshake(), and tlskey_start().

◆ tlskey_reset()

void tlskey_reset ( struct tls_key_schedule * tlskey)
extern

Reset key schedule.

Parameters
tlskeyKey schedule

It is safe to reset a key schedule that has been stopped, or that has not yet been started.

Definition at line 492 of file tlskey.c.

492 {
493 const struct tls_key_schedule_operations *op = tlskey->op;
494
495 /* Do nothing if key schedule is stopped */
496 if ( ! op ) {
497 assert ( tlskey->secretsize == 0 );
498 assert ( tlskey->kdf.flags == 0 );
499 assert ( tlskey->traffic[TLS_CLIENT].phase == NULL );
500 assert ( tlskey->traffic[TLS_SERVER].phase == NULL );
501 return;
502 }
503
504 /* Clear secrets, flags, and traffic phases */
505 memset ( tlskey->secret, 0, tlskey->secretsize );
506 tlskey->kdf.flags = 0;
507 tlskey->traffic[TLS_CLIENT].phase = NULL;
508 tlskey->traffic[TLS_SERVER].phase = NULL;
509
510 /* Reset key schedule */
511 op->reset ( tlskey );
512}
unsigned int flags
Key flags.
Definition tlskey.h:79
struct tls_traffic_secret traffic[2]
Traffic secrets.
Definition tlskey.h:124
struct tls_kdf_secret kdf
Key derivation function secret.
Definition tlskey.h:122
const struct tls_phase * phase
Phase.
Definition tlskey.h:96
#define TLS_CLIENT
Client endpoint index.
Definition tlskey.h:27
#define TLS_SERVER
Server endpoint index.
Definition tlskey.h:30

References assert, tls_kdf_secret::flags, tls_key_schedule::kdf, memset(), NULL, op, tls_key_schedule::op, tls_traffic_secret::phase, tls_key_schedule::secret, tls_key_schedule::secretsize, TLS_CLIENT, TLS_SERVER, and tls_key_schedule::traffic.

Referenced by tls_channel_reset(), tlskey_load(), and tlskey_start().

◆ tlskey_apply()

int tlskey_apply ( struct tls_key_schedule * tlskey,
const void * shared,
size_t shared_len )
extern

Apply a new shared secret.

Parameters
tlskeyKey schedule
sharedNew shared secret
shared_lenLength of new shared secret
Return values
rcReturn status code

Definition at line 522 of file tlskey.c.

523 {
524 const struct tls_key_schedule_operations *op = tlskey->op;
525 int rc;
526
527 /* Sanity check */
528 if ( ! op )
529 return -ENOTTY;
530
531 /* All schedules define the master secret as immutable */
532 if ( tlskey->kdf.flags & TLSKEY_KDF_MASTER ) {
533 DBGC ( tlskey, "TLSKEY %p cannot apply a new shared secret "
534 "after generating master secret\n", tlskey );
535 return -EPROTO;
536 }
537
538 /* Apply new shared secret */
539 DBGC ( tlskey, "TLSKEY %p applying secret:\n", tlskey );
540 DBGC_HDA ( tlskey, 0, shared, shared_len );
541 if ( ( rc = op->apply ( tlskey, shared, shared_len ) ) != 0 )
542 return rc;
543
544 /* Mark key schedule as containing key material */
545 tlskey->kdf.flags |= TLSKEY_KDF_KEYED;
546
547 return 0;
548}
#define EPROTO
Protocol error.
Definition errno.h:668
#define TLSKEY_KDF_MASTER
Key derivation function has a master secret.
Definition tlskey.h:86
#define TLSKEY_KDF_KEYED
Key derivation function has key material.
Definition tlskey.h:83

References DBGC, DBGC_HDA, ENOTTY, EPROTO, tls_kdf_secret::flags, tls_key_schedule::kdf, op, tls_key_schedule::op, rc, TLSKEY_KDF_KEYED, and TLSKEY_KDF_MASTER.

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), tls_channel_apply(), tlskey_hash_load(), tlskey_hash_master(), and tlskey_hkdf_master().

◆ tlskey_master()

int tlskey_master ( struct tls_key_schedule * tlskey,
int ems )
extern

Generate master secret.

Parameters
tlskeyKey schedule
emsExtended master secret extension is enabled
Return values
rcReturn status code

Definition at line 557 of file tlskey.c.

557 {
558 const struct tls_key_schedule_operations *op = tlskey->op;
559 int rc;
560
561 /* Sanity check */
562 if ( ! op )
563 return -ENOTTY;
564
565 /* Any conceivable schedule requires key material */
566 if ( ! ( tlskey->kdf.flags & TLSKEY_KDF_KEYED ) ) {
567 DBGC ( tlskey, "TLSKEY %p cannot generate master secret "
568 "without key material\n", tlskey );
569 return -EPROTO;
570 }
571
572 /* All schedules define the master secret as immutable */
573 if ( tlskey->kdf.flags & TLSKEY_KDF_MASTER ) {
574 DBGC ( tlskey, "TLSKEY %p cannot regenerate master secret\n",
575 tlskey );
576 return -EPROTO;
577 }
578
579 /* Generate master secret */
580 DBGC ( tlskey, "TLSKEY %p generating %smaster secret\n",
581 tlskey, ( ems ? "extended " : "" ) );
582 if ( ( rc = op->master ( tlskey, ems ) ) != 0 )
583 return rc;
584
585 /* Mark key schedule as containing master secret */
586 tlskey->kdf.flags |= TLSKEY_KDF_MASTER;
587 if ( ems )
588 tlskey->kdf.flags |= TLSKEY_KDF_EMS;
589
590 return 0;
591}
#define TLSKEY_KDF_EMS
Key derivation function has an extended master secret.
Definition tlskey.h:89

References DBGC, ENOTTY, EPROTO, tls_kdf_secret::flags, tls_key_schedule::kdf, op, tls_key_schedule::op, rc, TLSKEY_KDF_EMS, TLSKEY_KDF_KEYED, and TLSKEY_KDF_MASTER.

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), and tls_send_client_key_exchange().

◆ tlskey_verify()

int tlskey_verify ( struct tls_key_schedule * tlskey,
const struct tls_endpoint * end,
void * verify,
size_t verify_len )
extern

Generate verification data.

Parameters
tlskeyKey schedule
endVerification endpoint
verifyVerification data to fill in
verify_lenLength of verification data
Return values
rcReturn status code

Definition at line 602 of file tlskey.c.

604 {
605 const struct tls_key_schedule_operations *op = tlskey->op;
606 int rc;
607
608 /* Sanity check */
609 if ( ! op )
610 return -ENOTTY;
611
612 /* Verification data must be non-replayable */
613 if ( ! ( tlskey->transcript.flags & TLSKEY_TSF_NONCED ) ) {
614 DBGC ( tlskey, "TLSKEY %p cannot generate verification data "
615 "without a digested nonce\n", tlskey );
616 return -EPROTO;
617 }
618
619 /* Generate verification data */
620 DBGC2 ( tlskey, "TLSKEY %p generating %s verification data\n",
621 tlskey, end->name );
622 if ( ( rc = op->verify ( tlskey, end, verify, verify_len ) ) != 0 )
623 return rc;
624 DBGC ( tlskey, "TLSKEY %p %s verification data:\n",
625 tlskey, end->name );
626 DBGC_HDA ( tlskey, 0, verify, verify_len );
627
628 return 0;
629}
#define DBGC2(...)
Definition compiler.h:547
uint32_t end
Ending offset.
Definition netvsc.h:7
int(* verify)(struct tls_key_schedule *tlskey, const struct tls_endpoint *end, void *verify, size_t verify_len)
Generate verification data.
Definition tlskey.h:243
#define TLSKEY_TSF_NONCED
Transcript digest includes a Hello record containing the local nonce.
Definition tlskey.h:69

References DBGC, DBGC2, DBGC_HDA, end, ENOTTY, EPROTO, tls_transcript::flags, op, tls_key_schedule::op, rc, TLSKEY_TSF_NONCED, tls_key_schedule::transcript, and tls_key_schedule_operations::verify.

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), tls_channel_verify(), and tls_send_finished().

◆ tlskey_traffic()

int tlskey_traffic ( struct tls_key_schedule * tlskey,
const struct tls_endpoint * writer,
const struct tls_phase * phase )
extern

Generate traffic secret.

Parameters
tlskeyKey schedule
writerWriter endpoint
phaseTraffic phase
Return values
rcReturn status code

Definition at line 639 of file tlskey.c.

641 {
642 const struct tls_key_schedule_operations *op = tlskey->op;
643 struct tls_traffic_secret *traffic = &tlskey->traffic[writer->index];
644 unsigned int missing;
645 int rc;
646
647 /* Sanity check */
648 if ( ! op )
649 return -ENOTTY;
650
651 /* Check flags required for this traffic phase */
653 missing = ( ( tlskey->kdf.flags ^ phase->flags ) & phase->flags );
654 if ( missing ) {
655 DBGC ( tlskey, "TLSKEY %p cannot generate %s %s traffic "
656 "secrets (missing KDF flags %#04x)\n",
657 tlskey, writer->name, phase->name, missing );
658 return -EPROTO;
659 }
660
661 /* Generate traffic secret */
662 DBGC2 ( tlskey, "TLSKEY %p generating %s %s traffic secret\n",
663 tlskey, writer->name, phase->name );
664 if ( ( rc = op->traffic ( tlskey, writer, phase ) ) != 0 )
665 return rc;
666
667 /* Record phase */
668 traffic->phase = phase;
669
670 return 0;
671}
uint8_t index
Endpoint index.
Definition tlskey.h:21
const char name[7]
Name (for key expansion labels).
Definition tlskey.h:23
const char * name
Name.
Definition tlskey.c:129
uint8_t flags
Required key derivation function flags.
Definition tlskey.c:133
A TLS traffic secret.
Definition tlskey.h:92

References assert, DBGC, DBGC2, ENOTTY, EPROTO, tls_kdf_secret::flags, tls_phase::flags, tls_endpoint::index, tls_key_schedule::kdf, tls_endpoint::name, tls_phase::name, op, tls_key_schedule::op, tls_traffic_secret::phase, rc, TLSKEY_KDF_KEYED, and tls_key_schedule::traffic.

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), and tls_change_cipher().

◆ tlskey_cipher()

int tlskey_cipher ( struct tls_key_schedule * tlskey,
const struct tls_endpoint * writer,
void * key,
size_t key_len,
void * iv,
size_t iv_len,
void * mac,
size_t mac_len )
extern

Generate cipher key material.

Parameters
tlskeyKey schedule
writerWriter endpoint
keyCipher key to fill in
key_lenLength of cipher key
ivFixed portion of initialisation vector to fill in
iv_lenLength of fixed portion of initialisation vector
macMAC secret to fill in
mac_lenLength of MAC secret
Return values
rcReturn status code

For key schedules that include a ratchet mechanism, each call consumes the current generation of traffic secret and replaces it with the next generation. Repeated calls may therefore be used to obtain multiple generations of the cipher key material.

Definition at line 691 of file tlskey.c.

694 {
695 const struct tls_key_schedule_operations *op = tlskey->op;
696 struct tls_traffic_secret *traffic = &tlskey->traffic[writer->index];
697 int rc;
698
699 /* Sanity check */
700 if ( ! op )
701 return -ENOTTY;
702
703 /* Ensure that traffic secret has actually been generated */
704 if ( ! traffic->phase ) {
705 DBGC ( tlskey, "TLSKEY %p cannot generate cipher key "
706 "material without traffic secrets\n", tlskey );
707 return -EPROTO;
708 }
709
710 /* Generate cipher key material */
711 DBGC2 ( tlskey, "TLSKEY %p generating %s %s cipher key material\n",
712 tlskey, writer->name, traffic->phase->name );
713 if ( ( rc = op->cipher ( tlskey, writer, key, key_len, iv, iv_len,
714 mac, mac_len ) ) != 0 ) {
715 return rc;
716 }
717 if ( key_len ) {
718 DBGC ( tlskey, "TLSKEY %p %s key:\n", tlskey, writer->name );
719 DBGC_HDA ( tlskey, 0, key, key_len );
720 }
721 if ( iv_len ) {
722 DBGC ( tlskey, "TLSKEY %p %s IV:\n", tlskey, writer->name );
723 DBGC_HDA ( tlskey, 0, iv, iv_len );
724 }
725 if ( mac_len ) {
726 DBGC ( tlskey, "TLSKEY %p %s MAC:\n", tlskey, writer->name );
727 DBGC_HDA ( tlskey, 0, mac, mac_len );
728 }
729
730 return 0;
731}
union @162305117151260234136356364136041353210355154177 key
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13
u8 iv[16]
Initialization vector.
Definition wpa.h:33

References DBGC, DBGC2, DBGC_HDA, ENOTTY, EPROTO, tls_endpoint::index, iv, key, mac, tls_endpoint::name, tls_phase::name, op, tls_key_schedule::op, tls_traffic_secret::phase, rc, and tls_key_schedule::traffic.

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), and tls_change_cipher().

◆ tlskey_tbshash()

int tlskey_tbshash ( struct tls_key_schedule * tlskey,
const struct tls_endpoint * end,
struct digest_algorithm * digest,
const void * data,
size_t len,
void * tbs )
extern

Generate signable digest value.

Parameters
tlskeyKey schedule
endEndpoint
digestSignature digest algorithm
dataAdditional data
lenLength of additional data
tbsSignable digest value to fill in
Return values
rcReturn status code

Definition at line 744 of file tlskey.c.

747 {
748 const struct tls_key_schedule_operations *op = tlskey->op;
749 int rc;
750
751 /* Sanity check */
752 if ( ! op )
753 return -ENOTTY;
754
755 /* Signable digest values must be non-replayable */
756 if ( ! ( tlskey->transcript.flags & TLSKEY_TSF_NONCED ) ) {
757 DBGC ( tlskey, "TLSKEY %p cannot generate signable digest "
758 "without a digested nonce\n", tlskey );
759 return -EPROTO;
760 }
761
762 /* Generate digest value */
763 DBGC2 ( tlskey, "TLSKEY %p generating signable %s %s digest\n",
764 tlskey, end->name, digest->name );
765 if ( ( rc = op->tbshash ( tlskey, end, digest, data, len,
766 tbs ) ) != 0 ) {
767 return rc;
768 }
769 DBGC ( tlskey, "TLSKEY %p generated signable %s %s digest:\n",
770 tlskey, end->name, digest->name );
771 DBGC_HDA ( tlskey, 0, tbs, digest->digestsize );
772
773 return 0;
774}

References data, DBGC, DBGC2, DBGC_HDA, digest_algorithm::digestsize, end, ENOTTY, EPROTO, tls_transcript::flags, len, digest_algorithm::name, op, tls_key_schedule::op, rc, TLSKEY_TSF_NONCED, and tls_key_schedule::transcript.

Referenced by dummy_hash(), rfc8448_simple_test(), tls_new_server_key_exchange(), and tls_send_certificate_verify().

◆ tlskey_save()

int tlskey_save ( struct tls_key_schedule * tlskey,
const void * nonce,
size_t nonce_len,
struct tls_preshared_key * psk )
extern

Save pre-shared key.

Parameters
tlskeyKey schedule
nonceTicket nonce
nonce_lenLength of ticket nonce
pskPre-shared key to fill in
Return values
rcReturn status code

Definition at line 785 of file tlskey.c.

786 {
787 const struct tls_key_schedule_operations *op = tlskey->op;
788 struct digest_algorithm *digest = tlskey->digest;
789 int rc;
790
791 /* Clear any existing pre-shared key */
792 memset ( psk, 0, sizeof ( *psk ) );
793
794 /* Sanity check */
795 if ( ! op )
796 return -ENOTTY;
797
798 /* Session resumption requires a master secret */
799 if ( ! ( tlskey->kdf.flags & TLSKEY_KDF_MASTER ) ) {
800 DBGC ( tlskey, "TLSKEY %p cannot save key without a master "
801 "secret\n", tlskey );
802 return -EPROTO;
803 }
804
805 /* Save key material */
806 DBGC2 ( tlskey, "TLSKEY %p saving key\n", tlskey );
807 if ( ( rc = op->save ( tlskey, nonce, nonce_len, psk ) ) != 0 )
808 return rc;
809 DBGC ( tlskey, "TLSKEY %p saved key:\n", tlskey );
810 DBGC_HDA ( tlskey, 0, &psk->key, sizeof ( psk->key ) );
811
812 /* Record key properties */
813 psk->op = op;
814 psk->digest = digest;
815 psk->flags = tlskey->kdf.flags;
816
817 return 0;
818}
struct digest_algorithm * digest
Digest algorithm (if set).
Definition tlskey.h:132
unsigned int flags
Key flags.
Definition tlskey.h:134
union tls_preshared_key::@022173016027117201055347232316162256252261104170 key
Key material.
const struct tls_key_schedule_operations * op
Key schedule operations (if set).
Definition tlskey.h:130

References DBGC, DBGC2, DBGC_HDA, tls_key_schedule::digest, tls_preshared_key::digest, ENOTTY, EPROTO, tls_kdf_secret::flags, tls_preshared_key::flags, tls_key_schedule::kdf, tls_preshared_key::key, memset(), nonce, op, tls_key_schedule::op, tls_preshared_key::op, rc, and TLSKEY_KDF_MASTER.

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_simple_test(), and tls_channel_save().

◆ tlskey_load()

int tlskey_load ( struct tls_key_schedule * tlskey,
int ems,
const struct tls_preshared_key * psk )
extern

Load pre-shared key.

Parameters
tlskeyKey schedule
emsExtended master secret extension is enabled
pskPre-shared key
Return values
rcReturn status code

Definition at line 828 of file tlskey.c.

829 {
830 const struct tls_key_schedule_operations *op = tlskey->op;
831 struct digest_algorithm *digest = tlskey->digest;
832 int rc;
833
834 /* Reset key schedule */
835 tlskey_reset ( tlskey );
836
837 /* Sanity check */
838 if ( ! op )
839 return -ENOTTY;
840
841 /* Session resumption requires a master secret */
842 if ( ! ( psk->flags & TLSKEY_KDF_MASTER ) ) {
843 DBGC ( tlskey, "TLSKEY %p cannot load from a non-master "
844 "secret\n", tlskey );
845 return -EPROTO;
846 }
847
848 /* Pre-shared key must match extended/non-extended usage */
849 if ( ( !! ems ) != ( !! ( psk->flags & TLSKEY_KDF_EMS ) ) ) {
850 DBGC ( tlskey, "TLSKEY %p cannot load from %sextended master "
851 "secret\n", tlskey, ( ems ? "non-" : "" ) );
852 return -EPERM;
853 }
854
855 /* Pre-shared key must match schedule and digest */
856 if ( ( op != psk->op ) || ( digest != psk->digest ) ) {
857 DBGC ( tlskey, "TLSKEY %p cannot load from %s with %s\n",
858 tlskey, ( psk->op ? psk->op->name : "(unknown)" ),
859 ( psk->digest ? psk->digest->name : "(unknown)" ) );
860 return -EPERM;
861 }
862
863 /* Load key material */
864 DBGC ( tlskey, "TLSKEY %p loading key:\n", tlskey );
865 DBGC_HDA ( tlskey, 0, &psk->key, sizeof ( psk->key ) );
866 if ( ( rc = op->load ( tlskey, psk ) ) != 0 )
867 return rc;
868
869 /* Set flags */
870 tlskey->kdf.flags = ( psk->flags & op->mask );
871
872 return 0;
873}
#define EPERM
Operation not permitted.
Definition errno.h:658

References DBGC, DBGC_HDA, tls_key_schedule::digest, tls_preshared_key::digest, ENOTTY, EPERM, EPROTO, tls_kdf_secret::flags, tls_preshared_key::flags, tls_key_schedule::kdf, tls_preshared_key::key, digest_algorithm::name, tls_key_schedule_operations::name, op, tls_key_schedule::op, tls_preshared_key::op, rc, TLSKEY_KDF_EMS, TLSKEY_KDF_MASTER, and tlskey_reset().

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), and tls_channel_load().

◆ tlskey_bind()

int tlskey_bind ( const struct tls_preshared_key * psk,
const void * prefix,
size_t prefix_len,
void * binder,
size_t binder_len )
extern

Generate pre-shared key binder value.

Parameters
pskPre-shared key
prefixClientHello prefix
prefix_lenLength of ClientHello prefix
binderBinder value to fill in
binder_lenLength of binder value
Return values
rcReturn status code

Definition at line 885 of file tlskey.c.

886 {
887 const struct tls_key_schedule_operations *op = psk->op;
888 struct digest_algorithm *digest = psk->digest;
889 int rc;
890
891 /* Generate prefix digest and binder value */
892 if ( op && digest ) {
893 size_t digestsize = digest->digestsize;
894 size_t ctxsize = digest->ctxsize;
897
898 /* Calculate prefix digest */
899 digest_init ( digest, ctx );
900 digest_update ( digest, ctx, prefix, prefix_len );
901 digest_final ( digest, ctx, out );
902
903 /* Generate binder value */
904 DBGC2 ( psk, "TLSKEY %p generating key binder:\n", psk );
905 DBGC2_HDA ( psk, 0, &psk->key, sizeof ( psk->key ) );
906 if ( ( rc = op->bind ( psk, out, binder, binder_len ) ) != 0 )
907 return rc;
908 DBGC ( psk, "TLSKEY %p generated key binder:\n", psk );
909 DBGC_HDA ( psk, 0, binder, binder_len );
910
911 return 0;
912 }
913
914 DBGC ( psk, "TLSKEY %p cannot bind empty pre-shared key\n", psk );
915 return -ENOENT;
916}
__be32 out[4]
Definition CIB_PRM.h:8
#define DBGC2_HDA(...)
Definition compiler.h:548
#define ENOENT
No such file or directory.
Definition errno.h:558
char prefix[4]
Definition vmconsole.c:53

References ctx, digest_algorithm::ctxsize, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, tls_preshared_key::digest, digest_final(), digest_init(), digest_update(), digest_algorithm::digestsize, digestsize, ENOENT, tls_preshared_key::key, op, tls_preshared_key::op, out, prefix, and rc.

Referenced by rfc8448_resumed_test().

Variable Documentation

◆ tls_client

const struct tls_endpoint tls_client
extern

Client endpoint.

Definition at line 102 of file tlskey.c.

102 {
103 .index = TLS_CLIENT,
104 .name = "client",
105};

◆ tls_server

const struct tls_endpoint tls_server
extern

Server endpoint.

Definition at line 108 of file tlskey.c.

108 {
109 .index = TLS_SERVER,
110 .name = "server",
111};

◆ tls_early

const struct tls_phase tls_early
extern

Early traffic phase.

Definition at line 137 of file tlskey.c.

137 {
138 .name = "early",
139 .label = "e",
140 .flags = TLSKEY_KDF_KEYED,
141};

Referenced by rfc8448_resumed_test().

◆ tls_handshake

const struct tls_phase tls_handshake
extern

Handshake traffic phase.

Definition at line 144 of file tlskey.c.

144 {
145 .name = "handshake",
146 .label = "hs",
147 .flags = TLSKEY_KDF_KEYED,
148};

Referenced by rfc8448_resumed_test(), rfc8448_simple_test(), and tlskey_hkdf_verify().

◆ tls_application

const struct tls_phase tls_application
extern

Application traffic phase.

Definition at line 151 of file tlskey.c.

151 {
152 .name = "application",
153 .label = "ap",
154 .flags = ( TLSKEY_KDF_KEYED | TLSKEY_KDF_MASTER ),
155};

Referenced by dummy_hash(), dummy_md5_sha1(), rfc8448_resumed_test(), rfc8448_simple_test(), tls_change_cipher(), tlskey_hash_traffic(), and tlskey_hkdf_cipher().

◆ tlskey_hkdf

const struct tls_key_schedule_operations tlskey_hkdf
extern

TLS key schedule based on HKDF.

Definition at line 1369 of file tlskey.c.

1369 {
1370 .name = "HKDF",
1371 .accumulates = 1,
1372 .mask = TLSKEY_KDF_KEYED,
1373 .secretsize = tlskey_hkdf_secretsize,
1374 .expand = tlskey_hkdf_expand,
1375 .reset = tlskey_hkdf_reset,
1376 .apply = tlskey_hkdf_apply,
1377 .master = tlskey_hkdf_master,
1378 .verify = tlskey_hkdf_verify,
1379 .traffic = tlskey_hkdf_traffic,
1380 .cipher = tlskey_hkdf_cipher,
1381 .tbshash = tlskey_hkdf_tbshash,
1382 .save = tlskey_hkdf_save,
1383 .load = tlskey_hkdf_load,
1384 .bind = tlskey_hkdf_bind,
1385};
static void tlskey_hkdf_expand(struct digest_algorithm *digest, const void *secret, const char *label, const void *seed, size_t seed_len, void *out, size_t out_len)
Expand key material.
Definition tlskey.c:948
static int tlskey_hkdf_master(struct tls_key_schedule *tlskey, int ems)
Generate master secret.
Definition tlskey.c:1083
static int tlskey_hkdf_cipher(struct tls_key_schedule *tlskey, const struct tls_endpoint *writer, void *key, size_t key_len, void *iv, size_t iv_len, void *mac __unused, size_t mac_len)
Generate cipher key material.
Definition tlskey.c:1182
static void tlskey_hkdf_reset(struct tls_key_schedule *tlskey)
Reset key schedule.
Definition tlskey.c:1030
static int tlskey_hkdf_verify(struct tls_key_schedule *tlskey, const struct tls_endpoint *end, void *verify, size_t verify_len)
Generate verification data.
Definition tlskey.c:1113
static int tlskey_hkdf_save(struct tls_key_schedule *tlskey, const void *nonce, size_t nonce_len, struct tls_preshared_key *psk)
Save pre-shared key.
Definition tlskey.c:1266
static int tlskey_hkdf_load(struct tls_key_schedule *tlskey, const struct tls_preshared_key *psk)
Load pre-shared key.
Definition tlskey.c:1304
static int tlskey_hkdf_bind(const struct tls_preshared_key *psk, const void *hash, void *binder, size_t binder_len)
Generate pre-shared key binder value.
Definition tlskey.c:1331
static size_t tlskey_hkdf_secretsize(struct digest_algorithm *digest)
Calculate secret size.
Definition tlskey.c:931
static int tlskey_hkdf_apply(struct tls_key_schedule *tlskey, const void *shared, size_t shared_len)
Apply a new shared secret.
Definition tlskey.c:1054
static int tlskey_hkdf_tbshash(struct tls_key_schedule *tlskey, const struct tls_endpoint *end, struct digest_algorithm *digest, const void *data __unused, size_t len, void *tbs)
Generate signable digest value.
Definition tlskey.c:1225
static int tlskey_hkdf_traffic(struct tls_key_schedule *tlskey, const struct tls_endpoint *writer, const struct tls_phase *phase)
Generate traffic secret.
Definition tlskey.c:1149

Referenced by rfc8448_resumed_test(), and rfc8448_simple_test().

◆ tlskey_hash

const struct tls_key_schedule_operations tlskey_hash
extern

TLS key schedule based on P_Hash().

Definition at line 1819 of file tlskey.c.

1819 {
1820 .name = "P_Hash()",
1821 .accumulates = 0,
1823 .secretsize = tlskey_hash_secretsize,
1824 .expand = tlskey_hash_expand,
1825 .reset = tlskey_hash_reset,
1826 .apply = tlskey_hash_apply,
1827 .master = tlskey_hash_master,
1828 .verify = tlskey_hash_verify,
1829 .traffic = tlskey_hash_traffic,
1830 .cipher = tlskey_hash_cipher,
1831 .tbshash = tlskey_hash_tbshash,
1832 .save = tlskey_hash_save,
1833 .load = tlskey_hash_load,
1834 .bind = tlskey_hash_bind,
1835};
static int tlskey_hash_tbshash(struct tls_key_schedule *tlskey, const struct tls_endpoint *end, struct digest_algorithm *digest, const void *data, size_t len, void *tbs)
Generate signable digest value.
Definition tlskey.c:1687
static int tlskey_hash_cipher(struct tls_key_schedule *tlskey, const struct tls_endpoint *writer, void *key, size_t key_len, void *iv, size_t iv_len, void *mac, size_t mac_len)
Generate cipher key material.
Definition tlskey.c:1634
static int tlskey_hash_load(struct tls_key_schedule *tlskey, const struct tls_preshared_key *psk)
Load pre-shared key.
Definition tlskey.c:1780
static int tlskey_hash_verify(struct tls_key_schedule *tlskey, const struct tls_endpoint *end, void *verify, size_t verify_len)
Generate verification data.
Definition tlskey.c:1566
static int tlskey_hash_master(struct tls_key_schedule *tlskey, int ems)
Generate master secret.
Definition tlskey.c:1513
static void tlskey_hash_reset(struct tls_key_schedule *tlskey)
Reset key schedule.
Definition tlskey.c:1472
static int tlskey_hash_traffic(struct tls_key_schedule *tlskey, const struct tls_endpoint *writer, const struct tls_phase *phase)
Generate traffic secret.
Definition tlskey.c:1603
static int tlskey_hash_save(struct tls_key_schedule *tlskey, const void *nonce __unused, size_t nonce_len, struct tls_preshared_key *psk)
Save pre-shared key.
Definition tlskey.c:1747
static int tlskey_hash_bind(const struct tls_preshared_key *psk __unused, const void *hash __unused, void *binder __unused, size_t binder_len)
Generate pre-shared key binder value.
Definition tlskey.c:1807
static int tlskey_hash_apply(struct tls_key_schedule *tlskey, const void *shared, size_t shared_len)
Apply a new shared secret.
Definition tlskey.c:1489
static size_t tlskey_hash_secretsize(struct digest_algorithm *digest)
Calculate secret size.
Definition tlskey.c:1403
static void tlskey_hash_expand(struct digest_algorithm *digest, const void *secret, const char *label, const void *seed, size_t seed_len, void *out, size_t out_len)
Expand key material.
Definition tlskey.c:1420

Referenced by dummy_hash(), and tls_set_digest().

◆ tlskey_md5_sha1

const struct tls_key_schedule_operations tlskey_md5_sha1
extern

TLS key schedule based on P_MD5()+P_SHA1().

Definition at line 1993 of file tlskey.c.

1993 {
1994 .name = "P_MD5()+P_SHA1()",
1995 .accumulates = 0,
1997 .secretsize = tlskey_md5_sha1_secretsize,
1998 .expand = tlskey_md5_sha1_expand,
1999 .reset = tlskey_hash_reset,
2000 .apply = tlskey_md5_sha1_apply,
2001 .master = tlskey_hash_master,
2002 .verify = tlskey_hash_verify,
2003 .traffic = tlskey_hash_traffic,
2004 .cipher = tlskey_hash_cipher,
2005 .tbshash = tlskey_hash_tbshash,
2006 .save = tlskey_md5_sha1_save,
2007 .load = tlskey_hash_load,
2008 .bind = tlskey_hash_bind,
2009};
static void tlskey_md5_sha1_expand(struct digest_algorithm *digest, const void *secret, const char *label, const void *seed, size_t seed_len, void *out, size_t out_len)
Expand key material.
Definition tlskey.c:1877
static int tlskey_md5_sha1_save(struct tls_key_schedule *tlskey, const void *nonce __unused, size_t nonce_len, struct tls_preshared_key *psk)
Save pre-shared key.
Definition tlskey.c:1961
static size_t tlskey_md5_sha1_secretsize(struct digest_algorithm *digest)
Calculate secret size.
Definition tlskey.c:1850
static int tlskey_md5_sha1_apply(struct tls_key_schedule *tlskey, const void *shared, size_t shared_len)
Apply a new shared secret.
Definition tlskey.c:1916

Referenced by dummy_md5_sha1(), and tls_set_digest().