iPXE
channel.c File Reference

Secure channel abstraction. More...

#include <string.h>
#include <errno.h>
#include <ipxe/malloc.h>
#include <ipxe/crypto.h>
#include <ipxe/hkdf.h>
#include <ipxe/rbg.h>
#include <ipxe/channel.h>

Go to the source code of this file.

Macros

#define ENOTTY_TRANSPORT   __einfo_error ( EINFO_ENOTTY_TRANSPORT )
#define EINFO_ENOTTY_TRANSPORT   __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Untransportable key" )
#define EPERM_NOT_CONFIDENTIAL   __einfo_error ( EINFO_EPERM_NOT_CONFIDENTIAL )
#define EINFO_EPERM_NOT_CONFIDENTIAL   __einfo_uniqify ( EINFO_EPERM, 0x01, "Not confidential" )
#define EPERM_NOT_VALID   __einfo_error ( EINFO_EPERM_NOT_VALID )
#define EINFO_EPERM_NOT_VALID   __einfo_uniqify ( EINFO_EPERM, 0x02, "Peer certificate not valid" )
#define EPROTO_NOT_KEYED   __einfo_error ( EINFO_EPROTO_NOT_KEYED )
#define EINFO_EPROTO_NOT_KEYED   __einfo_uniqify ( EINFO_EPROTO, 0x01, "No shared key material" )
#define EPROTO_NOT_BOUND   __einfo_error ( EINFO_EPROTO_NOT_BOUND )
#define EINFO_EPROTO_NOT_BOUND   __einfo_uniqify ( EINFO_EPROTO, 0x02, "No bound peer identity" )
#define EPROTO_NOT_CONFIRMED   __einfo_error ( EINFO_EPROTO_NOT_CONFIRMED )
#define EINFO_EPROTO_NOT_CONFIRMED   __einfo_uniqify ( EINFO_EPROTO, 0x03, "No confirmed peer identity" )

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void channel_unbind (struct secure_channel *channel)
 Clear bound peer identity.
static void channel_unconfirm (struct secure_channel *channel)
 Clear confirmed peer identity.
static void channel_unestablish (struct secure_channel *channel)
 Clear established peer identity.
static int channel_ephemeral_init (struct secure_channel *channel)
 Initialise ephemeral master secret.
void channel_ephemeral (struct secure_channel *channel, const void *info, size_t info_len, void *out, size_t len)
 Generate ephemeral secret.
void channel_ephemeral_label (struct secure_channel *channel, const char *label, void *out, size_t len)
 Generate labelled ephemeral secret.
static void channel_ephemeral_replace (struct secure_channel *channel)
 Replace ephemeral master secret.
void channel_unkey (struct secure_channel *channel)
 Clear shared secret.
static void channel_key_private (struct secure_channel *channel, struct exchange_algorithm *exchange, void *private)
 Generate private key.
int channel_key_share (struct secure_channel *channel, struct exchange_algorithm *exchange, void *public)
 Share public key.
static int channel_key (struct secure_channel *channel, struct exchange_algorithm *exchange, const void *partner, void *shared)
 Generate and apply shared secret.
int channel_key_agree (struct secure_channel *channel, struct exchange_algorithm *exchange, const void *partner)
 Agree shared secret.
static int channel_key_transport (struct secure_channel *channel, struct exchange_algorithm *exchange, void *shared)
 Transport shared secret.
static int channel_bind (struct secure_channel *channel, struct x509_certificate *identity)
 Set bound peer identity.
int channel_bind_verify (struct secure_channel *channel, struct x509_certificate *identity, struct pubkey_algorithm *pubkey, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
 Bind peer identity via ephemeral public key signature verification.
int channel_bind_encrypt (struct secure_channel *channel, struct x509_certificate *identity, struct exchange_algorithm *exchange, struct pubkey_algorithm *pubkey, struct asn1_builder *ciphertext)
 Bind peer identity via shared secret encryption.
int channel_save (struct secure_channel *channel, struct secure_preshared_identity *psid)
 Save a pre-shared key.
int channel_load (struct secure_channel *channel, struct secure_preshared_identity *psid)
 Load a pre-shared key.
int channel_confirm (struct secure_channel *channel, const void *auth, size_t len)
 Confirm peer identity.
int channel_establish (struct secure_channel *channel, const char *name, struct x509_root *root)
 Establish channel as trusted for application data.
static void channel_dead_crypt (struct cipher_algorithm *cipher __unused, void *ctx __unused, const void *src __unused, void *dst, size_t len)
 Encrypt or decrypt data via dead cipher.
static const char * channel_pipe_name (struct secure_channel *channel, struct secure_pipe *pipe)
 Get pipe name (for debugging).
static void channel_clear_cipher (struct secure_pipe *pipe)
 Clear cipher algorithm.
int channel_set_cipher (struct secure_channel *channel, struct secure_pipe *pipe, struct cipher_algorithm *cipher, const void *key, size_t len)
 Set cipher algorithm and key.
int channel_open (struct secure_channel *channel)
 Open secure channel.
void channel_reopen (struct secure_channel *channel)
 Reopen secure channel.
void channel_close (struct secure_channel *channel)
 Close secure channel.

Variables

struct cipher_algorithm channel_dead_cipher
 Dead cipher.

Detailed Description

Secure channel abstraction.

We define a concept of a secure channel as comprising a pair of ciphers (one for transmit, one for receive) together with the cryptographic state required to establish that these ciphers may be used for encrypted communication with a trusted peer. The model is loosely constructed as a generalisation of TLS minus the protocol specifics.

The channel starts out with both ciphers operating in plaintext mode. Over this initially unencrypted channel, a shared secret is agreed, bound to a peer identity, and used to derive keys for the transmit and receive ciphers.

The major channel operations are:

  • Key exchange: a shared secret is agreed (e.g. via Ephemeral Diffie-Hellman key exchange)
  • Key binding: the shared secret is bound to a peer identity (i.e. to a long-term public key as recorded in an X.509 certificate)
  • Key derivation: the transmit and receive cipher keys are derived from the shared secret
  • Key confirmation: the peer demonstrates possession of the identity-bound shared secret
  • Identity validation: the long-term public key representing the peer identity is validated as being trusted and as matching the required identity (e.g. a TLS host name)

The channel maintains the following security properties:

  • "keyed": a boolean flag indicating that the channel contains key material derived from the shared secret
  • "bound": a certificate reference representing the peer identity to which the shared secret has been bound
  • "confirmed": a certificate reference representing the peer identity that has demonstrated possession of the identity-bound shared secret
  • "established": a certificate reference representing the peer identity that has demonstrated possession of the identity-bound shared secret and has been verified as valid

The peer identities are stored as references to X.509 certificates. The secure channel conceptual model is agnostic about how peer identities may be represented, but X.509 certificates are most convenient for use within iPXE. Validation of the certificate chain is outside the scope of the secure channel and must be performed separately.

When the channel has a "confirmed" certificate reference and that certificate has separately been marked as valid, the secure channel may become established and may subsequently be used to transmit and receive application data.

The channel is a passive entity: it does not itself initiate any messages. All communication is driven by the consumer (such as the TLS protocol). The set of operations described above that are used to establish a secure channel must be performed by the consumer according to its protocol definition.

The order of these operations may vary based upon both the protocol definition and the options negotiated at runtime with the peer. The secure channel abstraction is responsible for maintaining the listed security properties and determining whether or not the required security conditions have been met, regardless of the order in which operations are performed by the consumer.

Definition in file channel.c.

Macro Definition Documentation

◆ ENOTTY_TRANSPORT

#define ENOTTY_TRANSPORT   __einfo_error ( EINFO_ENOTTY_TRANSPORT )

Definition at line 114 of file channel.c.

Referenced by channel_key_transport().

◆ EINFO_ENOTTY_TRANSPORT

#define EINFO_ENOTTY_TRANSPORT   __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Untransportable key" )

Definition at line 115 of file channel.c.

115#define EINFO_ENOTTY_TRANSPORT \
116 __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Untransportable key" )

◆ EPERM_NOT_CONFIDENTIAL

#define EPERM_NOT_CONFIDENTIAL   __einfo_error ( EINFO_EPERM_NOT_CONFIDENTIAL )

Definition at line 117 of file channel.c.

Referenced by channel_confirm(), channel_establish(), and channel_set_cipher().

◆ EINFO_EPERM_NOT_CONFIDENTIAL

#define EINFO_EPERM_NOT_CONFIDENTIAL   __einfo_uniqify ( EINFO_EPERM, 0x01, "Not confidential" )

Definition at line 118 of file channel.c.

118#define EINFO_EPERM_NOT_CONFIDENTIAL \
119 __einfo_uniqify ( EINFO_EPERM, 0x01, "Not confidential" )

◆ EPERM_NOT_VALID

#define EPERM_NOT_VALID   __einfo_error ( EINFO_EPERM_NOT_VALID )

Definition at line 120 of file channel.c.

Referenced by channel_establish().

◆ EINFO_EPERM_NOT_VALID

#define EINFO_EPERM_NOT_VALID   __einfo_uniqify ( EINFO_EPERM, 0x02, "Peer certificate not valid" )

Definition at line 121 of file channel.c.

121#define EINFO_EPERM_NOT_VALID \
122 __einfo_uniqify ( EINFO_EPERM, 0x02, "Peer certificate not valid" )

◆ EPROTO_NOT_KEYED

#define EPROTO_NOT_KEYED   __einfo_error ( EINFO_EPROTO_NOT_KEYED )

Definition at line 123 of file channel.c.

Referenced by channel_bind(), and channel_set_cipher().

◆ EINFO_EPROTO_NOT_KEYED

#define EINFO_EPROTO_NOT_KEYED   __einfo_uniqify ( EINFO_EPROTO, 0x01, "No shared key material" )

Definition at line 124 of file channel.c.

124#define EINFO_EPROTO_NOT_KEYED \
125 __einfo_uniqify ( EINFO_EPROTO, 0x01, "No shared key material" )

◆ EPROTO_NOT_BOUND

#define EPROTO_NOT_BOUND   __einfo_error ( EINFO_EPROTO_NOT_BOUND )

Definition at line 126 of file channel.c.

Referenced by channel_confirm(), channel_load(), and channel_save().

◆ EINFO_EPROTO_NOT_BOUND

#define EINFO_EPROTO_NOT_BOUND   __einfo_uniqify ( EINFO_EPROTO, 0x02, "No bound peer identity" )

Definition at line 127 of file channel.c.

127#define EINFO_EPROTO_NOT_BOUND \
128 __einfo_uniqify ( EINFO_EPROTO, 0x02, "No bound peer identity" )

◆ EPROTO_NOT_CONFIRMED

#define EPROTO_NOT_CONFIRMED   __einfo_error ( EINFO_EPROTO_NOT_CONFIRMED )

Definition at line 129 of file channel.c.

Referenced by channel_establish().

◆ EINFO_EPROTO_NOT_CONFIRMED

#define EINFO_EPROTO_NOT_CONFIRMED   __einfo_uniqify ( EINFO_EPROTO, 0x03, "No confirmed peer identity" )

Definition at line 130 of file channel.c.

130#define EINFO_EPROTO_NOT_CONFIRMED \
131 __einfo_uniqify ( EINFO_EPROTO, 0x03, "No confirmed peer identity" )

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ channel_unbind()

void channel_unbind ( struct secure_channel * channel)
static

Clear bound peer identity.

Parameters
channelSecure channel

Definition at line 545 of file channel.c.

545 {
546
547 /* Key confirmation is defined only for the currently bound
548 * identity, and so any existing confirmed peer identity must
549 * be cleared.
550 */
552
553 /* Drop and clear reference */
554 x509_put ( channel->props.bound );
555 channel->props.bound = NULL;
556}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
static void channel_unconfirm(struct secure_channel *channel)
Clear confirmed peer identity.
Definition channel.c:867
uint32_t channel
RNDIS channel.
Definition netvsc.h:3
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition x509.h:278

References channel, channel_unconfirm(), NULL, and x509_put().

Referenced by channel_bind(), channel_key(), and channel_unkey().

◆ channel_unconfirm()

void channel_unconfirm ( struct secure_channel * channel)
static

Clear confirmed peer identity.

Parameters
channelSecure channel

Definition at line 867 of file channel.c.

867 {
868
869 /* Establishment is defined only for the currently confirmed
870 * identity, and so any existing established identity must be
871 * cleared.
872 */
874
875 /* Drop and clear reference */
876 x509_put ( channel->props.confirmed );
877 channel->props.confirmed = NULL;
878}
static void channel_unestablish(struct secure_channel *channel)
Clear established peer identity.
Definition channel.c:971

References channel, channel_unestablish(), NULL, and x509_put().

Referenced by channel_confirm(), and channel_unbind().

◆ channel_unestablish()

void channel_unestablish ( struct secure_channel * channel)
static

Clear established peer identity.

Parameters
channelSecure channel

Definition at line 971 of file channel.c.

971 {
972
973 /* Drop and clear reference */
974 x509_put ( channel->props.established );
975 channel->props.established = NULL;
976}

References channel, NULL, and x509_put().

Referenced by channel_establish(), and channel_unconfirm().

◆ channel_ephemeral_init()

int channel_ephemeral_init ( struct secure_channel * channel)
static

Initialise ephemeral master secret.

Parameters
channelSecure channel
Return values
rcReturn status code

Definition at line 164 of file channel.c.

164 {
166 static const char salt[16] = "channel master";
167 int rc;
168
169 /* Generate random bits with no additional input and without
170 * prediction resistance
171 */
172 if ( ( rc = rbg_generate ( NULL, 0, 0, channel->ephemeral,
173 sizeof ( channel->ephemeral ) ) ) != 0 ) {
174 DBGC ( channel, "CHANNEL %p could not generate random data: "
175 "%s\n", channel, strerror ( rc ) );
176 return rc;
177 }
178
179 /* Generate ephemeral master secret */
180 hkdf_extract ( digest, salt, sizeof ( salt ), channel->ephemeral,
181 sizeof ( channel->ephemeral ), channel->ephemeral );
182
183 return 0;
184}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define channel_ephemeral_algorithm
Ephemeral master secret digest algorithm.
Definition channel.h:19
#define DBGC(...)
Definition compiler.h:530
void hkdf_extract(struct digest_algorithm *digest, const void *salt, size_t salt_len, const void *ikm, size_t ikm_len, void *prk)
Extract fixed-length pseudorandom key.
Definition hkdf.c:56
int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
Definition rbg.c:117
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A message digest algorithm.
Definition crypto.h:19

References channel, channel_ephemeral_algorithm, DBGC, hkdf_extract(), NULL, rbg_generate(), rc, and strerror().

Referenced by channel_open().

◆ channel_ephemeral()

void channel_ephemeral ( struct secure_channel * channel,
const void * info,
size_t info_len,
void * out,
size_t len )

Generate ephemeral secret.

Parameters
channelSecure channel
infoAdditional information
info_lenLength of additional information
outEphemeral secret to fill in
lenLength of ephemeral secret

Definition at line 195 of file channel.c.

196 {
198
199 /* Additional info should always be provided */
200 assert ( info != NULL );
201 assert ( info_len > 0 );
202
203 /* Generate from ephemeral master secret and additional information */
204 hkdf_expand ( digest, channel->ephemeral, info, info_len, out, len );
205}
__be32 out[4]
Definition CIB_PRM.h:8
u32 info
Definition ar9003_mac.h:0
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
ring len
Length.
Definition dwmac.h:226
void hkdf_expand(struct digest_algorithm *digest, const void *prk, const void *info, size_t info_len, void *out, size_t len)
Expand pseudorandom key.
Definition hkdf.c:95
uint8_t info_len
Reject information length.
Definition ib_mad.h:7

References assert, channel, channel_ephemeral_algorithm, hkdf_expand(), info, info_len, len, NULL, and out.

Referenced by channel_ephemeral_label(), and tls_send_record().

◆ channel_ephemeral_label()

void channel_ephemeral_label ( struct secure_channel * channel,
const char * label,
void * out,
size_t len )

Generate labelled ephemeral secret.

Parameters
channelSecure channel
labelAdditional information string
outEphemeral secret to fill in
lenLength of ephemeral secret

Definition at line 215 of file channel.c.

216 {
217
218 /* Generate from ephemeral master secret and label */
220 DBGC2 ( channel, "CHANNEL %p ephemeral \"%s\":\n", channel, label );
221 DBGC2_HDA ( channel, 0, out, len );
222}
void channel_ephemeral(struct secure_channel *channel, const void *info, size_t info_len, void *out, size_t len)
Generate ephemeral secret.
Definition channel.c:195
#define DBGC2(...)
Definition compiler.h:547
#define DBGC2_HDA(...)
Definition compiler.h:548
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
A text label widget.
Definition label.h:16

References channel, channel_ephemeral(), DBGC2, DBGC2_HDA, len, out, and strlen().

Referenced by channel_ephemeral_replace(), channel_key_private(), tls_nonce(), and tls_session().

◆ channel_ephemeral_replace()

void channel_ephemeral_replace ( struct secure_channel * channel)
static

Replace ephemeral master secret.

Parameters
channelSecure channel

Definition at line 229 of file channel.c.

229 {
230
231 /* Generate a new ephemeral master key */
232 channel_ephemeral_label ( channel, "channel replace",
233 channel->ephemeral,
234 sizeof ( channel->ephemeral ) );
235}
void channel_ephemeral_label(struct secure_channel *channel, const char *label, void *out, size_t len)
Generate labelled ephemeral secret.
Definition channel.c:215

References channel, and channel_ephemeral_label().

Referenced by channel_close(), and channel_reopen().

◆ channel_unkey()

void channel_unkey ( struct secure_channel * channel)

Clear shared secret.

Parameters
channelSecure channel

Definition at line 273 of file channel.c.

273 {
274
275 /* Key binding is defined only for the current shared secret,
276 * and so any existing bound peer identity must be cleared.
277 */
279
280 /* Clear shared key */
281 channel->props.keyed = 0;
282
283 /* Reset the key schedule */
284 channel->op->reset ( channel );
285}
static void channel_unbind(struct secure_channel *channel)
Clear bound peer identity.
Definition channel.c:545

References channel, and channel_unbind().

Referenced by channel_bind_encrypt(), channel_close(), channel_key(), channel_load(), channel_open(), channel_reopen(), and tls_clear_digest().

◆ channel_key_private()

void channel_key_private ( struct secure_channel * channel,
struct exchange_algorithm * exchange,
void * private )
static

Generate private key.

Parameters
channelSecure channel
exchangeKey exchange algorithm
privatePrivate key to fill in

Definition at line 294 of file channel.c.

296 {
297 size_t privsize = exchange->privsize;
298 const char *label;
299
300 /* Use exchange algorithm name as additional information */
301 label = exchange->name;
302
303 /* (Re)generate private key
304 *
305 * Note that key exchange private keys are always small enough
306 * to fit on the stack, even for algorithms such as FFDHE that
307 * have large public and shared keys.
308 */
309 channel_ephemeral_label ( channel, label, private, privsize );
310}
size_t privsize
Private key size.
Definition crypto.h:214
const char * name
Algorithm name.
Definition crypto.h:212

References channel, channel_ephemeral_label(), exchange_algorithm::name, and exchange_algorithm::privsize.

Referenced by channel_key(), and channel_key_share().

◆ channel_key_share()

int channel_key_share ( struct secure_channel * channel,
struct exchange_algorithm * exchange,
void * public )

Share public key.

Parameters
channelSecure channel
exchangeKey exchange algorithm
publicPublic key to fill in
Return values
rcReturn status code

Definition at line 320 of file channel.c.

321 {
322 size_t privsize = exchange->privsize;
323 size_t pubsize = exchange->pubsize;
324 uint8_t private[privsize];
325 int rc;
326
327 /* (Re)generate private key */
328 channel_key_private ( channel, exchange, private );
329
330 /* Generate public key */
331 if ( ( rc = exchange_share ( exchange, private, public ) ) != 0 ) {
332 DBGC ( channel, "CHANNEL %p could not share \"%s\": %s\n",
333 channel, exchange->name, strerror ( rc ) );
334 goto err_share;
335 }
336
337 /* Show public key (for debugging) */
338 DBGC2 ( channel, "CHANNEL %p sharing \"%s\":\n",
339 channel, exchange->name );
340 DBGC2_HDA ( channel, 0, public, pubsize );
341
342 err_share:
343 /* Erase private key */
344 memset ( private, 0, sizeof ( private ) );
345 return rc;
346}
unsigned char uint8_t
Definition stdint.h:10
static void channel_key_private(struct secure_channel *channel, struct exchange_algorithm *exchange, void *private)
Generate private key.
Definition channel.c:294
static int exchange_share(struct exchange_algorithm *exchange, const void *private, void *public)
Definition crypto.h:397
void * memset(void *dest, int character, size_t len) __nonnull
size_t pubsize
Public key size.
Definition crypto.h:216

References channel, channel_key_private(), DBGC, DBGC2, DBGC2_HDA, exchange_share(), memset(), exchange_algorithm::name, exchange_algorithm::privsize, exchange_algorithm::pubsize, rc, and strerror().

Referenced by tls_key_share().

◆ channel_key()

int channel_key ( struct secure_channel * channel,
struct exchange_algorithm * exchange,
const void * partner,
void * shared )
static

Generate and apply shared secret.

Parameters
channelSecure channel
exchangeKey exchange algorithm
partnerPartner public key
sharedShared secret to fill in
Return values
rcReturn status code

Definition at line 357 of file channel.c.

359 {
360 size_t sharedsize = exchange->sharedsize;
361 size_t privsize = exchange->privsize;
362 uint8_t private[privsize];
363 int accumulated;
364 int rc;
365
366 /* (Re)generate private key */
367 channel_key_private ( channel, exchange, private );
368
369 /* Generate shared secret */
370 if ( ( rc = exchange_agree ( exchange, private, partner,
371 shared ) ) != 0 ) {
372 DBGC ( channel, "CHANNEL %p could not agree \"%s\": %s\n",
373 channel, exchange->name, strerror ( rc ) );
374 goto err_agree;
375 }
376
377 /* Show shared secret (for debugging) */
378 DBGC2 ( channel, "CHANNEL %p agreed \"%s\":\n",
379 channel, exchange->name );
380 DBGC2_HDA ( channel, 0, shared, sharedsize );
381
382 /* Apply shared secret to key schedule */
383 accumulated = 0;
384 if ( ( rc = channel->op->apply ( channel, exchange, shared,
385 &accumulated ) ) != 0 ) {
386 DBGC ( channel, "CHANNEL %p could not apply \"%s\": %s\n",
387 channel, exchange->name, strerror ( rc ) );
388 goto err_apply;
389 }
390
391 /* If the accumulation flag was not set, then the ability of
392 * the peer to subsequently demonstrate possession of the key
393 * material suffices to demonstrate possession of this shared
394 * secret, but does not necessarily suffice to demonstrate
395 * possession of any previously applied shared secrets. Any
396 * binding of the peer identity is therefore no longer valid.
397 */
398 if ( ! accumulated )
400
401 /* Channel now possesses a shared secret */
402 channel->props.keyed = 1;
403 DBGC ( channel, "CHANNEL %p key material obtained via \"%s\"\n",
404 channel, exchange->name );
405
406 err_apply:
407 err_agree:
408 /* Clear generated shared secret on any error */
409 if ( rc != 0 )
411 /* Erase private key */
412 memset ( private, 0, sizeof ( private ) );
413 return rc;
414}
void channel_unkey(struct secure_channel *channel)
Clear shared secret.
Definition channel.c:273
struct eth_slow_lacp_entity_tlv partner
Partner information.
Definition eth_slow.h:5
static int exchange_agree(struct exchange_algorithm *exchange, const void *private, const void *partner, void *shared)
Definition crypto.h:403
size_t sharedsize
Shared secret size.
Definition crypto.h:218

References channel, channel_key_private(), channel_unbind(), channel_unkey(), DBGC, DBGC2, DBGC2_HDA, exchange_agree(), memset(), exchange_algorithm::name, partner, exchange_algorithm::privsize, rc, exchange_algorithm::sharedsize, and strerror().

Referenced by channel_key_agree(), and channel_key_transport().

◆ channel_key_agree()

int channel_key_agree ( struct secure_channel * channel,
struct exchange_algorithm * exchange,
const void * partner )

Agree shared secret.

Parameters
channelSecure channel
exchangeKey exchange algorithm
partnerPartner public key
Return values
rcReturn status code

Definition at line 424 of file channel.c.

426 {
427 size_t sharedsize = exchange->sharedsize;
428 size_t pubsize = exchange->pubsize;
429 void *tmp;
430 int rc;
431
432 /* Show partner public key (for debugging) */
433 DBGC2 ( channel, "CHANNEL %p partner \"%s\":\n",
434 channel, exchange->name );
435 DBGC2_HDA ( channel, 0, partner, pubsize );
436
437 /* Allocate space for shared secret (may be too large for stack) */
438 tmp = zalloc ( sharedsize );
439 if ( ! tmp ) {
440 rc = -ENOMEM;
441 goto err_alloc;
442 }
443
444 /* Generate and apply shared secret */
445 if ( ( rc = channel_key ( channel, exchange, partner, tmp ) ) != 0 )
446 goto err_key;
447
448 err_key:
449 /* Erase shared secret */
450 zfree ( tmp );
451 err_alloc:
452 return rc;
453}
static int channel_key(struct secure_channel *channel, struct exchange_algorithm *exchange, const void *partner, void *shared)
Generate and apply shared secret.
Definition channel.c:357
#define ENOMEM
Not enough space.
Definition errno.h:578
unsigned long tmp
Definition linux_pci.h:65
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
void zfree(void *ptr)
Clear and free memory.
Definition malloc.c:738

References channel, channel_key(), DBGC2, DBGC2_HDA, ENOMEM, exchange_algorithm::name, partner, exchange_algorithm::pubsize, rc, exchange_algorithm::sharedsize, tmp, zalloc(), and zfree().

Referenced by tls_key_agree().

◆ channel_key_transport()

int channel_key_transport ( struct secure_channel * channel,
struct exchange_algorithm * exchange,
void * shared )
static

Transport shared secret.

Parameters
channelSecure channel
exchangeKey exchange algorithm
sharedShared secret to fill in
Return values
rcReturn status code

Key transport is modelled as a key exchange algorithm with a public key size of zero: the shared secret is unilaterally generated by the local endpoint and must then be transported to the peer.

Definition at line 467 of file channel.c.

469 {
470 int rc;
471
472 /* Sanity check */
473 if ( ! is_key_transport ( exchange ) ) {
474 DBGC ( channel, "CHANNEL %p cannot transport \"%s\"\n",
475 channel, exchange->name );
476 return -ENOTTY_TRANSPORT;
477 }
478
479 /* Generate and apply shared secret */
480 if ( ( rc = channel_key ( channel, exchange, NULL, shared ) ) != 0 )
481 return rc;
482
483 return 0;
484}
#define ENOTTY_TRANSPORT
Definition channel.c:114
static int is_key_transport(struct exchange_algorithm *exchange)
Definition crypto.h:409

References channel, channel_key(), DBGC, ENOTTY_TRANSPORT, is_key_transport(), exchange_algorithm::name, NULL, and rc.

Referenced by channel_bind_encrypt().

◆ channel_bind()

int channel_bind ( struct secure_channel * channel,
struct x509_certificate * identity )
static

Set bound peer identity.

Parameters
channelSecure channel
identityIdentity to be bound
Return values
rcReturn status code

Definition at line 565 of file channel.c.

566 {
567
568 /* Clear any existing binding */
570
571 /* Fail if there is no shared secret to be bound */
572 if ( ! channel->props.keyed ) {
573 DBGC ( channel, "CHANNEL %p cannot bind to empty key\n",
574 channel );
575 return -EPROTO_NOT_KEYED;
576 }
577
578 /* Record bound peer identity */
579 channel->props.bound = x509_get ( identity );
580 DBGC ( channel, "CHANNEL %p key material bound to \"%s\"\n",
581 channel, x509_name ( identity ) );
582
583 return 0;
584}
#define EPROTO_NOT_KEYED
Definition channel.c:123
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition x509.c:147
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition x509.h:267

References channel, channel_unbind(), DBGC, EPROTO_NOT_KEYED, x509_get(), and x509_name().

Referenced by channel_bind_encrypt(), channel_bind_verify(), and channel_load().

◆ channel_bind_verify()

int channel_bind_verify ( struct secure_channel * channel,
struct x509_certificate * identity,
struct pubkey_algorithm * pubkey,
struct digest_algorithm * digest,
const void * value,
const struct asn1_cursor * signature )

Bind peer identity via ephemeral public key signature verification.

Parameters
channelSecure channel
identityIdentity to be bound
pubkeyPublic-key algorithm
digestDigest algorithm
valueDigest value (must cover peer's ephemeral public key)
signatureSignature
Return values
rcReturn status code

The peer may delegate authority to the shared secret by signing a digest that covers at least its own ephemeral public key (e.g. the Diffie-Hellman parameters provided in a ServerKeyExchange record) and a challenge nonce (e.g. the TLS client random bytes).

The consumer asserts to the secure channel that the digest covers at least the peer's ephemeral public key and a nonce. The digest may cover arbitrary additional information (e.g. the entire transcript hash as signed by a CertificateVerify record).

This assertion is an unverifiable promise made by the consumer: there is no way for the secure channel itself to determine what is covered by the digest.

Definition at line 611 of file channel.c.

615 {
616 const struct asn1_cursor *key = &identity->subject.public_key.raw;
617 int rc;
618
619 /* Verify signature */
620 if ( ( rc = pubkey_verify ( pubkey, key, digest, value,
621 signature ) ) != 0 ) {
622 DBGC ( channel, "CHANNEL %p could not verify binding: %s\n",
623 channel, strerror ( rc ) );
624 return rc;
625 }
626
627 /* Bind to the identity that signed the shared secret */
628 if ( ( rc = channel_bind ( channel, identity ) ) != 0 )
629 return rc;
630
631 return 0;
632}
u8 signature
CPU signature.
Definition CIB_PRM.h:7
union @162305117151260234136356364136041353210355154177 key
pseudo_bit_t value[0x00020]
Definition arbel.h:2
static int channel_bind(struct secure_channel *channel, struct x509_certificate *identity)
Set bound peer identity.
Definition channel.c:565
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Definition crypto.h:383
An ASN.1 object cursor.
Definition asn1.h:21
struct x509_subject subject
Subject.
Definition x509.h:245
struct asn1_cursor raw
Raw public key information.
Definition x509.h:52
struct x509_public_key public_key
Public key information.
Definition x509.h:66

References channel, channel_bind(), DBGC, key, pubkey_verify(), x509_subject::public_key, x509_public_key::raw, rc, signature, strerror(), x509_certificate::subject, and value.

Referenced by tls_new_server_key_exchange().

◆ channel_bind_encrypt()

int channel_bind_encrypt ( struct secure_channel * channel,
struct x509_certificate * identity,
struct exchange_algorithm * exchange,
struct pubkey_algorithm * pubkey,
struct asn1_builder * ciphertext )

Bind peer identity via shared secret encryption.

Parameters
channelSecure channel
identityIdentity to be bound
exchangeKey exchange algorithm
pubkeyPublic-key algorithm
ciphertextEncrypted shared secret
Return values
rcReturn status code

The local endpoint may delegate authority to the shared secret by encrypting a unilaterally chosen shared secret (e.g. a classic TLS static RSA pre-master secret).

Definition at line 648 of file channel.c.

652 {
653 const struct asn1_cursor *key = &identity->subject.public_key.raw;
654 size_t sharedsize = exchange->sharedsize;
655 struct asn1_cursor plaintext;
656 void *tmp;
657 int rc;
658
659 /* Allocate space for shared secret (may be too large for stack) */
660 tmp = zalloc ( sharedsize );
661 if ( ! tmp ) {
662 rc = -ENOMEM;
663 goto err_alloc;
664 }
665 plaintext.data = tmp;
666 plaintext.len = sharedsize;
667
668 /* Generate unencrypted shared secret */
669 if ( ( rc = channel_key_transport ( channel, exchange, tmp ) ) != 0 )
670 goto err_transport;
671
672 /* Encrypt shared secret */
673 if ( ( rc = pubkey_encrypt ( pubkey, key, &plaintext,
674 ciphertext ) ) != 0 ) {
675 DBGC ( channel, "CHANNEL %p could not encrypt \"%s\": %s\n",
676 channel, exchange->name, strerror ( rc ) );
677 goto err_encrypt;
678 }
679
680 /* Bind to the identity that can decrypt the shared secret */
681 if ( ( rc = channel_bind ( channel, identity ) ) != 0 )
682 goto err_bind;
683
684 err_bind:
685 err_encrypt:
686 err_transport:
687 /* Clear the generated shared secret on any error */
688 if ( rc != 0 )
690 /* Erase unencrypted shared secret */
691 zfree ( tmp );
692 err_alloc:
693 return rc;
694}
static int channel_key_transport(struct secure_channel *channel, struct exchange_algorithm *exchange, void *shared)
Transport shared secret.
Definition channel.c:467
static int pubkey_encrypt(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext)
Definition crypto.h:362

References channel, channel_bind(), channel_key_transport(), channel_unkey(), asn1_cursor::data, DBGC, ENOMEM, key, asn1_cursor::len, exchange_algorithm::name, pubkey_encrypt(), x509_subject::public_key, x509_public_key::raw, rc, exchange_algorithm::sharedsize, strerror(), x509_certificate::subject, tmp, zalloc(), and zfree().

Referenced by tls_key_encrypt().

◆ channel_save()

int channel_save ( struct secure_channel * channel,
struct secure_preshared_identity * psid )

Save a pre-shared key.

Parameters
channelSecure channel
psidPre-shared bound peer identity
Return values
rcReturn status code

Definition at line 738 of file channel.c.

739 {
740 struct x509_certificate *identity;
741 int rc;
742
743 /* Clear any existing pre-shared bound peer identity */
745
746 /* Fail if there is no bound peer identity to save */
747 identity = channel->props.bound;
748 if ( ! identity ) {
749 DBGC ( channel, "CHANNEL %p cannot create pre-shared key "
750 "for unbound peer\n", channel );
751 return -EPROTO_NOT_BOUND;
752 }
753
754 /* Fail if consumer does not support pre-shared keys */
755 if ( ! channel->op->save ) {
756 DBGC ( channel, "CHANNEL %p does not support pre-shared "
757 "keys\n", channel );
758 return -ENOTSUP;
759 }
760
761 /* Save pre-shared key */
762 if ( ( rc = channel->op->save ( channel, psid ) ) != 0 ) {
763 DBGC ( channel, "CHANNEL %p could not save pre-shared "
764 "key: %s\n", channel, strerror ( rc ) );
765 return rc;
766 }
767
768 /* Record pre-shared bound peer identity */
769 psid->bound = x509_get ( identity );
770 DBGC ( channel, "CHANNEL %p key material saved for \"%s\"\n",
771 channel, x509_name ( identity ) );
772
773 return 0;
774}
#define EPROTO_NOT_BOUND
Definition channel.c:126
static void channel_clear_preshared(struct secure_preshared_identity *psid)
Clear pre-shared bound peer identity.
Definition channel.h:282
#define ENOTSUP
Operation not supported.
Definition errno.h:633
struct x509_certificate * bound
Bound peer identity.
Definition channel.h:99
An X.509 certificate.
Definition x509.h:216

References secure_preshared_identity::bound, channel, channel_clear_preshared(), DBGC, ENOTSUP, EPROTO_NOT_BOUND, rc, strerror(), x509_get(), and x509_name().

Referenced by tls_save().

◆ channel_load()

int channel_load ( struct secure_channel * channel,
struct secure_preshared_identity * psid )

Load a pre-shared key.

Parameters
channelSecure channel
psidPre-shared bound peer identity
Return values
rcReturn status code

Definition at line 783 of file channel.c.

784 {
785 struct x509_certificate *identity;
786 int rc;
787
788 /* Clear any existing shared secret */
790
791 /* Fail if there is no bound peer identity to resume */
792 identity = psid->bound;
793 if ( ! identity ) {
794 DBGC ( channel, "CHANNEL %p cannot resume from empty "
795 "pre-shared key\n", channel );
797 goto err_empty;
798 }
799
800 /* Fail if consumer does not support pre-shared keys */
801 if ( ! channel->op->load ) {
802 DBGC ( channel, "CHANNEL %p does not support pre-shared "
803 "keys\n", channel );
804 rc = -ENOTSUP;
805 goto err_unsupported;
806 }
807
808 /* Load pre-shared key */
809 if ( ( rc = channel->op->load ( channel, psid ) ) != 0 ) {
810 DBGC ( channel, "CHANNEL %p could not load pre-shared key: "
811 "%s\n", channel, strerror ( rc ) );
812 goto err_load;
813 }
814
815 /* Channel now possesses a shared secret */
816 channel->props.keyed = 1;
817 DBGC ( channel, "CHANNEL %p key material obtained from pre-shared "
818 "key\n", channel );
819
820 /* Bind to the identity that was bound to the pre-shared key */
821 if ( ( rc = channel_bind ( channel, identity ) ) != 0 )
822 goto err_bind;
823
824 return 0;
825
826 err_bind:
827 err_load:
828 err_unsupported:
829 err_empty:
831 return rc;
832}

References secure_preshared_identity::bound, channel, channel_bind(), channel_unkey(), DBGC, ENOTSUP, EPROTO_NOT_BOUND, rc, and strerror().

Referenced by tls_resume().

◆ channel_confirm()

int channel_confirm ( struct secure_channel * channel,
const void * auth,
size_t len )

Confirm peer identity.

Parameters
channelSecure channel
authAuthenticator value
lenLength of authenticator value
Return values
rcReturn status code

The consumer asserts to the secure channel that the authenticator value was received after the receive pipe was transitioned to a cipher capable of providing confidentiality.

This assertion is an unverifiable promise made by the consumer: there is no way for the secure channel itself to determine when the authenticator value was received.

Definition at line 896 of file channel.c.

897 {
898 struct x509_certificate *identity;
899 int rc;
900
901 /* Clear any existing confirmed peer identity */
903
904 /* Fail if there is no bound peer identity to authenticate */
905 identity = channel->props.bound;
906 if ( ! identity ) {
907 DBGC ( channel, "CHANNEL %p cannot authenticate unbound "
908 "peer\n", channel );
909 return -EPROTO_NOT_BOUND;
910 }
911
912 /* Sanity check: binding is not possible without keying */
913 assert ( channel->props.keyed );
914
915 /* Require key confirmation over a confidential channel */
916 if ( ! channel->rx.cipher->confidential ) {
917 DBGC ( channel, "CHANNEL %p cannot confirm key with a "
918 "non-confidential cipher\n", channel );
920 }
921
922 /* Verify authentication data */
923 if ( ( rc = channel->op->verify ( channel, auth, len ) ) != 0 ) {
924 DBGC ( channel, "CHANNEL %p failed to authenticate: %s\n",
925 channel, strerror ( rc ) );
926 return rc;
927 }
928
929 /* Record bound peer identity as confirmed peer identity */
930 channel->props.confirmed = x509_get ( identity );
931 DBGC ( channel, "CHANNEL %p key material confirmed for \"%s\"\n",
932 channel, x509_name ( identity ) );
933
934 return 0;
935}
#define EPERM_NOT_CONFIDENTIAL
Definition channel.c:117

References assert, channel, channel_unconfirm(), DBGC, EPERM_NOT_CONFIDENTIAL, EPROTO_NOT_BOUND, len, rc, strerror(), x509_get(), and x509_name().

Referenced by tls_new_finished().

◆ channel_establish()

int channel_establish ( struct secure_channel * channel,
const char * name,
struct x509_root * root )

Establish channel as trusted for application data.

Parameters
channelSecure channel
nameRequired peer identity name
rootRoot certificate list, or NULL to use default
Return values
rcReturn status code

Definition at line 986 of file channel.c.

987 {
988 struct x509_certificate *identity;
989 int rc;
990
991 /* Clear any existing established peer identity */
993
994 /* Fail if there is no confirmed peer identity to establish */
995 identity = channel->props.confirmed;
996 if ( ! identity ) {
997 DBGC ( channel, "CHANNEL %p cannot establish unconfirmed "
998 "peer\n", channel );
999 return -EPROTO_NOT_CONFIRMED;
1000 }
1001
1002 /* Sanity check: confirmation is not possible without binding */
1003 assert ( channel->props.bound == identity );
1004 assert ( channel->props.keyed );
1005
1006 /* Fail if ciphers are still operating in plaintext mode */
1007 if ( ! ( channel->tx.cipher->confidential &&
1008 channel->rx.cipher->confidential ) ) {
1009 DBGC ( channel, "CHANNEL %p cannot establish channel with a "
1010 "non-confidential cipher\n", channel );
1011 return -EPERM_NOT_CONFIDENTIAL;
1012 }
1013
1014 /* Fail if confirmed peer identity name is incorrect */
1015 if ( ( rc = x509_check_name ( identity, name ) ) != 0 ) {
1016 DBGC ( channel, "CHANNEL %p identity \"%s\" does not match "
1017 "\"%s\": %s\n", channel, x509_name ( identity ),
1018 name, strerror ( rc ) );
1019 return rc;
1020 }
1021
1022 /* Fail if confirmed peer identity has not been validated */
1023 if ( ! x509_is_valid ( identity, root ) ) {
1024 DBGC ( channel, "CHANNEL %p identity \"%s\" has not been "
1025 "validated\n", channel, x509_name ( identity ) );
1026 return -EPERM_NOT_VALID;
1027 }
1028
1029 /* Record confirmed peer identity as established peer identity */
1030 channel->props.established = x509_get ( identity );
1031 DBGC ( channel, "CHANNEL %p established for \"%s\"\n",
1032 channel, x509_name ( identity ) );
1033
1034 return 0;
1035}
const char * name
Definition ath9k_hw.c:1986
#define EPROTO_NOT_CONFIRMED
Definition channel.c:129
#define EPERM_NOT_VALID
Definition channel.c:120
struct stp_switch root
Root switch.
Definition stp.h:15
int x509_is_valid(struct x509_certificate *cert, struct x509_root *root)
Check if X.509 certificate is valid.
Definition x509.c:1313
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition x509.c:1564

References assert, channel, channel_unestablish(), DBGC, EPERM_NOT_CONFIDENTIAL, EPERM_NOT_VALID, EPROTO_NOT_CONFIRMED, name, rc, root, strerror(), x509_check_name(), x509_get(), x509_is_valid(), and x509_name().

Referenced by tls_establish().

◆ channel_dead_crypt()

void channel_dead_crypt ( struct cipher_algorithm *cipher __unused,
void *ctx __unused,
const void *src __unused,
void * dst,
size_t len )
static

Encrypt or decrypt data via dead cipher.

Parameters
cipherCipher algorithm
ctxContext
srcData to encrypt or decrypt
dstBuffer for encrypted or decrypted data
lenLength of data

Definition at line 1054 of file channel.c.

1056 {
1057 static const uint8_t pattern[] = { 0xde, 0xad, 0xc1, 0xfa };
1058 uint8_t *bytes = dst;
1059 unsigned int i;
1060
1061 /* Fill destination with fixed and easily spotted pattern */
1062 for ( i = 0 ; i < len ; i++ )
1063 bytes[i] = pattern[ i % sizeof ( pattern ) ];
1064}
uint8_t bytes[64]
Definition ib_mad.h:5

References __unused, bytes, ctx, len, and src.

◆ channel_pipe_name()

const char * channel_pipe_name ( struct secure_channel * channel,
struct secure_pipe * pipe )
inlinestatic

Get pipe name (for debugging).

Parameters
channelSecure channel
pipeSecure channel pipe
Return values
namePipe name

Definition at line 1094 of file channel.c.

1095 {
1096
1097 return ( ( pipe == &channel->tx ) ? "TX" :
1098 ( pipe == &channel->rx ) ? "RX" : "INVALID" );
1099}

References channel.

Referenced by channel_set_cipher().

◆ channel_clear_cipher()

void channel_clear_cipher ( struct secure_pipe * pipe)
static

Clear cipher algorithm.

Parameters
pipeSecure channel pipe

Definition at line 1106 of file channel.c.

1106 {
1107
1108 /* Zero and free any existing cipher context */
1109 zfree ( pipe->ctx );
1110 pipe->ctx = NULL;
1111
1112 /* Default to the dead cipher until set */
1113 pipe->cipher = &channel_dead_cipher;
1114}
struct cipher_algorithm channel_dead_cipher
Dead cipher.
Definition channel.c:1073
void * ctx
Cipher context.
Definition channel.h:60
struct cipher_algorithm * cipher
Cipher algorithm.
Definition channel.h:58

References channel_dead_cipher, secure_pipe::cipher, secure_pipe::ctx, NULL, and zfree().

Referenced by channel_close(), channel_open(), and channel_set_cipher().

◆ channel_set_cipher()

int channel_set_cipher ( struct secure_channel * channel,
struct secure_pipe * pipe,
struct cipher_algorithm * cipher,
const void * key,
size_t len )

Set cipher algorithm and key.

Parameters
channelSecure channel
pipeSecure channel pipe
cipherCipher algorithm
keyKey
lenLength of key
Return values
rcReturn status code

The consumer asserts to the secure channel that the key is ultimately derived from the shared secret that was previously provided to the consumer by the secure channel, i.e. that possession of the cipher key implies possession of the shared secret.

This assertion is an unverifiable promise made by the consumer: we can check that a shared secret exists, but there is no way for the secure channel itself to determine how the cipher key is derived.

Definition at line 1136 of file channel.c.

1139 {
1140 int rc;
1141
1142 /* Zero and free any existing cipher context */
1143 channel_clear_cipher ( pipe );
1144
1145 /* Fail if there is no shared secret from which a key could derive */
1146 if ( ! channel->props.keyed ) {
1147 DBGC ( channel, "CHANNEL %p refusing to use definitely "
1148 "non-derived shared secret\n", channel );
1150 goto err_keyed;
1151 }
1152
1153 /* Refuse to explicitly set a non-confidential cipher */
1154 if ( ! cipher->confidential ) {
1155 DBGC ( channel, "CHANNEL %p %s refusing to use "
1156 "non-confidential cipher \"%s\"\n", channel,
1157 channel_pipe_name ( channel, pipe ), cipher->name );
1159 goto err_confidential;
1160 }
1161 pipe->cipher = cipher;
1162
1163 /* Allocate new context */
1164 pipe->ctx = zalloc ( cipher->ctxsize );
1165 if ( ! pipe->ctx ) {
1166 rc = -ENOMEM;
1167 goto err_alloc;
1168 }
1169
1170 /* Set cipher key */
1171 if ( ( rc = cipher_setkey ( cipher, pipe->ctx, key, len ) ) != 0 ) {
1172 DBGC ( channel, "CHANNEL %p %s could not set \"%s\" key: %s\n",
1174 cipher->name, strerror ( rc ) );
1175 goto err_setkey;
1176 }
1177
1178 DBGC ( channel, "CHANNEL %p %s using \"%s\" with %zd-bit key\n",
1180 cipher->name, ( 8 * len ) );
1181 return 0;
1182
1183 err_setkey:
1184 err_alloc:
1185 err_confidential:
1186 err_keyed:
1187 channel_clear_cipher ( pipe );
1188 return rc;
1189}
static const char * channel_pipe_name(struct secure_channel *channel, struct secure_pipe *pipe)
Get pipe name (for debugging).
Definition channel.c:1094
static void channel_clear_cipher(struct secure_pipe *pipe)
Clear cipher algorithm.
Definition channel.c:1106
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition crypto.h:310
const char * name
Algorithm name.
Definition crypto.h:60
int confidential
Cipher is capable of providing confidentiality.
Definition crypto.h:84
size_t ctxsize
Context size.
Definition crypto.h:62

References channel, channel_clear_cipher(), channel_pipe_name(), secure_pipe::cipher, cipher_setkey(), cipher_algorithm::confidential, secure_pipe::ctx, cipher_algorithm::ctxsize, DBGC, ENOMEM, EPERM_NOT_CONFIDENTIAL, EPROTO_NOT_KEYED, key, len, cipher_algorithm::name, rc, strerror(), and zalloc().

Referenced by tls_change_cipher().

◆ channel_open()

int channel_open ( struct secure_channel * channel)

Open secure channel.

Parameters
channelSecure channel
Return values
rcReturn status code

Definition at line 1205 of file channel.c.

1205 {
1206 int rc;
1207
1208 /* Sanity checks */
1209 assert ( channel != NULL );
1210 assert ( channel->op != NULL );
1211 assert ( channel->op->reset != NULL );
1212 assert ( channel->op->apply != NULL );
1213 assert ( channel->op->verify != NULL );
1214
1215 /* Clear security properties (which should already be clear) */
1216 assert ( channel->props.keyed == 0 );
1217 assert ( channel->props.bound == NULL );
1218 assert ( channel->props.confirmed == NULL );
1219 assert ( channel->props.established == NULL );
1221 assert ( channel->props.keyed == 0 );
1222 assert ( channel->props.bound == NULL );
1223 assert ( channel->props.confirmed == NULL );
1224 assert ( channel->props.established == NULL );
1225
1226 /* Reset ciphers (which should already have no contexts) */
1227 assert ( channel->tx.ctx == NULL );
1228 assert ( channel->rx.ctx == NULL );
1231 assert ( channel->tx.ctx == NULL );
1232 assert ( channel->rx.ctx == NULL );
1233
1234 /* Initialise ephemeral master secret */
1235 if ( ( rc = channel_ephemeral_init ( channel ) ) != 0 )
1236 return rc;
1237
1238 /* Enable initial plaintext ciphers */
1239 channel->tx.cipher = &cipher_null;
1240 channel->rx.cipher = &cipher_null;
1241
1242 DBGC ( channel, "CHANNEL %p opened\n", channel );
1243 return 0;
1244}
static int channel_ephemeral_init(struct secure_channel *channel)
Initialise ephemeral master secret.
Definition channel.c:164
struct cipher_algorithm cipher_null
Definition crypto_null.c:94

References assert, channel, channel_clear_cipher(), channel_ephemeral_init(), channel_unkey(), cipher_null, DBGC, NULL, and rc.

Referenced by add_tls().

◆ channel_reopen()

void channel_reopen ( struct secure_channel * channel)

Reopen secure channel.

Parameters
channelSecure channel

The channel will be returned to a freshly opened state (including a new ephemeral master secret), but with any existing cipher state retained. All security properties will be cleared.

This allows a new secure channel to be established with either or both of the transmit and receive pipes having already transitioned to a cipher capable of providing confidentiality.

The consumer may choose to reopen a fully established channel while leaving the cipher keys intact (as is done in TLS renegotiation), in which case it may choose to treat the channel as remaining established (to the old peer identity) at least until the point that the cipher keys are next changed (and possibly further, depending upon the protocol design). The secure channel itself does not attempt to model any such choice by the consumer: reopening will clear all security properties including the established peer identity.

Definition at line 1269 of file channel.c.

1269 {
1270
1271 /* Clear security properties */
1273 assert ( channel->props.keyed == 0 );
1274 assert ( channel->props.bound == NULL );
1275 assert ( channel->props.confirmed == NULL );
1276 assert ( channel->props.established == NULL );
1277
1278 /* Replace ephemeral master secret
1279 *
1280 * We choose to replace rather than reinitialise the ephemeral
1281 * master secret so that this function may be used from code
1282 * paths that cannot allow for failure (such as when closing
1283 * the channel).
1284 */
1286
1287 DBGC ( channel, "CHANNEL %p reopened\n", channel );
1288}
static void channel_ephemeral_replace(struct secure_channel *channel)
Replace ephemeral master secret.
Definition channel.c:229

References assert, channel, channel_ephemeral_replace(), channel_unkey(), DBGC, and NULL.

Referenced by tls_restart().

◆ channel_close()

void channel_close ( struct secure_channel * channel)

Close secure channel.

Parameters
channelSecure channel

All secret values held by the secure channel will be destroyed, including the ephemeral master secret.

This function may safely be called on a channel that has already been closed.

Definition at line 1301 of file channel.c.

1301 {
1302
1303 /* Clear security properties */
1305 assert ( channel->props.keyed == 0 );
1306 assert ( channel->props.bound == NULL );
1307 assert ( channel->props.confirmed == NULL );
1308 assert ( channel->props.established == NULL );
1309
1310 /* Reset ciphers */
1313 assert ( channel->tx.ctx == NULL );
1314 assert ( channel->rx.ctx == NULL );
1315
1316 /* Replace ephemeral master secret
1317 *
1318 * We choose to replace rather than zero the ephemeral master
1319 * secret. For any channel that has been successfully opened,
1320 * this ensures that an erroneous reuse of the channel after
1321 * it has been closed cannot lead to the use of predictable
1322 * ephemeral secrets (derived from an all-zero value), or to
1323 * reuse of its previous ephemeral secrets.
1324 */
1326
1327 DBGC ( channel, "CHANNEL %p closed\n", channel );
1328}

References assert, channel, channel_clear_cipher(), channel_ephemeral_replace(), channel_unkey(), DBGC, and NULL.

Referenced by add_tls(), and tls_close().

Variable Documentation

◆ channel_dead_cipher

struct cipher_algorithm channel_dead_cipher
Initial value:
= {
.name = "dead",
.ctxsize = 0,
.blocksize = 1,
.alignsize = 1,
.authsize = 0,
.confidential = 0,
.setkey = cipher_null_setkey,
.encrypt = channel_dead_crypt,
.decrypt = channel_dead_crypt,
}
static void channel_dead_crypt(struct cipher_algorithm *cipher __unused, void *ctx __unused, const void *src __unused, void *dst, size_t len)
Encrypt or decrypt data via dead cipher.
Definition channel.c:1054
int cipher_null_setiv(struct cipher_algorithm *cipher __unused, void *ctx __unused, const void *iv __unused, size_t ivlen __unused)
Definition crypto_null.c:70
void cipher_null_auth(struct cipher_algorithm *cipher __unused, void *ctx __unused, void *auth __unused)
Definition crypto_null.c:89
int cipher_null_setkey(struct cipher_algorithm *cipher __unused, void *ctx __unused, const void *key __unused, size_t keylen __unused)
Definition crypto_null.c:63

Dead cipher.

We activate this cipher (rather than the null cipher) upon any cipher-related failure, to guard against code paths that may fail to check for cipher errors.

Definition at line 1073 of file channel.c.

1073 {
1074 .name = "dead",
1075 .ctxsize = 0,
1076 .blocksize = 1,
1077 .alignsize = 1,
1078 .authsize = 0,
1079 .confidential = 0,
1080 .setkey = cipher_null_setkey,
1081 .setiv = cipher_null_setiv,
1082 .encrypt = channel_dead_crypt,
1083 .decrypt = channel_dead_crypt,
1084 .auth = cipher_null_auth,
1085};

Referenced by channel_clear_cipher(), and channel_init().