|
iPXE
|
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.
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. | |
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:
The channel maintains the following security properties:
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.
| #define ENOTTY_TRANSPORT __einfo_error ( EINFO_ENOTTY_TRANSPORT ) |
Definition at line 114 of file channel.c.
Referenced by channel_key_transport().
| #define EINFO_ENOTTY_TRANSPORT __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Untransportable key" ) |
| #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().
| #define EINFO_EPERM_NOT_CONFIDENTIAL __einfo_uniqify ( EINFO_EPERM, 0x01, "Not confidential" ) |
| #define EPERM_NOT_VALID __einfo_error ( EINFO_EPERM_NOT_VALID ) |
Definition at line 120 of file channel.c.
Referenced by channel_establish().
| #define EINFO_EPERM_NOT_VALID __einfo_uniqify ( EINFO_EPERM, 0x02, "Peer certificate not valid" ) |
| #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().
| #define EINFO_EPROTO_NOT_KEYED __einfo_uniqify ( EINFO_EPROTO, 0x01, "No shared key material" ) |
| #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().
| #define EINFO_EPROTO_NOT_BOUND __einfo_uniqify ( EINFO_EPROTO, 0x02, "No bound peer identity" ) |
| #define EPROTO_NOT_CONFIRMED __einfo_error ( EINFO_EPROTO_NOT_CONFIRMED ) |
Definition at line 129 of file channel.c.
Referenced by channel_establish().
| #define EINFO_EPROTO_NOT_CONFIRMED __einfo_uniqify ( EINFO_EPROTO, 0x03, "No confirmed peer identity" ) |
| FILE_LICENCE | ( | GPL2_OR_LATER_OR_UBDL | ) |
| FILE_SECBOOT | ( | PERMITTED | ) |
|
static |
Clear bound peer identity.
| channel | Secure channel |
Definition at line 545 of file channel.c.
References channel, channel_unconfirm(), NULL, and x509_put().
Referenced by channel_bind(), channel_key(), and channel_unkey().
|
static |
Clear confirmed peer identity.
| channel | Secure channel |
Definition at line 867 of file channel.c.
References channel, channel_unestablish(), NULL, and x509_put().
Referenced by channel_confirm(), and channel_unbind().
|
static |
Clear established peer identity.
| channel | Secure channel |
Definition at line 971 of file channel.c.
References channel, NULL, and x509_put().
Referenced by channel_establish(), and channel_unconfirm().
|
static |
Initialise ephemeral master secret.
| channel | Secure channel |
| rc | Return status code |
Definition at line 164 of file channel.c.
References channel, channel_ephemeral_algorithm, DBGC, hkdf_extract(), NULL, rbg_generate(), rc, and strerror().
Referenced by channel_open().
| void channel_ephemeral | ( | struct secure_channel * | channel, |
| const void * | info, | ||
| size_t | info_len, | ||
| void * | out, | ||
| size_t | len ) |
Generate ephemeral secret.
| channel | Secure channel |
| info | Additional information |
| info_len | Length of additional information |
| out | Ephemeral secret to fill in |
| len | Length of ephemeral secret |
Definition at line 195 of file channel.c.
References assert, channel, channel_ephemeral_algorithm, hkdf_expand(), info, info_len, len, NULL, and out.
Referenced by channel_ephemeral_label(), and tls_send_record().
| void channel_ephemeral_label | ( | struct secure_channel * | channel, |
| const char * | label, | ||
| void * | out, | ||
| size_t | len ) |
Generate labelled ephemeral secret.
| channel | Secure channel |
| label | Additional information string |
| out | Ephemeral secret to fill in |
| len | Length of ephemeral secret |
Definition at line 215 of file channel.c.
References channel, channel_ephemeral(), DBGC2, DBGC2_HDA, len, out, and strlen().
Referenced by channel_ephemeral_replace(), channel_key_private(), tls_nonce(), and tls_session().
|
static |
Replace ephemeral master secret.
| channel | Secure channel |
Definition at line 229 of file channel.c.
References channel, and channel_ephemeral_label().
Referenced by channel_close(), and channel_reopen().
| void channel_unkey | ( | struct secure_channel * | channel | ) |
Clear shared secret.
| channel | Secure channel |
Definition at line 273 of file channel.c.
References channel, and channel_unbind().
Referenced by channel_bind_encrypt(), channel_close(), channel_key(), channel_load(), channel_open(), channel_reopen(), and tls_clear_digest().
|
static |
Generate private key.
| channel | Secure channel |
| exchange | Key exchange algorithm |
| private | Private key to fill in |
Definition at line 294 of file channel.c.
References channel, channel_ephemeral_label(), exchange_algorithm::name, and exchange_algorithm::privsize.
Referenced by channel_key(), and channel_key_share().
| int channel_key_share | ( | struct secure_channel * | channel, |
| struct exchange_algorithm * | exchange, | ||
| void * | public ) |
Share public key.
| channel | Secure channel |
| exchange | Key exchange algorithm |
| public | Public key to fill in |
| rc | Return status code |
Definition at line 320 of file channel.c.
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().
|
static |
Generate and apply shared secret.
| channel | Secure channel |
| exchange | Key exchange algorithm |
| partner | Partner public key |
| shared | Shared secret to fill in |
| rc | Return status code |
Definition at line 357 of file channel.c.
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().
| int channel_key_agree | ( | struct secure_channel * | channel, |
| struct exchange_algorithm * | exchange, | ||
| const void * | partner ) |
Agree shared secret.
| rc | Return status code |
Definition at line 424 of file channel.c.
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().
|
static |
Transport shared secret.
| channel | Secure channel |
| exchange | Key exchange algorithm |
| shared | Shared secret to fill in |
| rc | Return 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.
References channel, channel_key(), DBGC, ENOTTY_TRANSPORT, is_key_transport(), exchange_algorithm::name, NULL, and rc.
Referenced by channel_bind_encrypt().
|
static |
Set bound peer identity.
| channel | Secure channel |
| identity | Identity to be bound |
| rc | Return status code |
Definition at line 565 of file channel.c.
References channel, channel_unbind(), DBGC, EPROTO_NOT_KEYED, x509_get(), and x509_name().
Referenced by channel_bind_encrypt(), channel_bind_verify(), and channel_load().
| 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.
| channel | Secure channel |
| identity | Identity to be bound |
| pubkey | Public-key algorithm |
| digest | Digest algorithm |
| value | Digest value (must cover peer's ephemeral public key) |
| signature | Signature |
| rc | Return 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.
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().
| 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.
| channel | Secure channel |
| identity | Identity to be bound |
| exchange | Key exchange algorithm |
| pubkey | Public-key algorithm |
| ciphertext | Encrypted shared secret |
| rc | Return 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.
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().
| int channel_save | ( | struct secure_channel * | channel, |
| struct secure_preshared_identity * | psid ) |
Save a pre-shared key.
| channel | Secure channel |
| psid | Pre-shared bound peer identity |
| rc | Return status code |
Definition at line 738 of file channel.c.
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().
| int channel_load | ( | struct secure_channel * | channel, |
| struct secure_preshared_identity * | psid ) |
Load a pre-shared key.
| channel | Secure channel |
| psid | Pre-shared bound peer identity |
| rc | Return status code |
Definition at line 783 of file channel.c.
References secure_preshared_identity::bound, channel, channel_bind(), channel_unkey(), DBGC, ENOTSUP, EPROTO_NOT_BOUND, rc, and strerror().
Referenced by tls_resume().
| int channel_confirm | ( | struct secure_channel * | channel, |
| const void * | auth, | ||
| size_t | len ) |
Confirm peer identity.
| rc | Return 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.
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().
| int channel_establish | ( | struct secure_channel * | channel, |
| const char * | name, | ||
| struct x509_root * | root ) |
Establish channel as trusted for application data.
| channel | Secure channel |
| name | Required peer identity name |
| root | Root certificate list, or NULL to use default |
| rc | Return status code |
Definition at line 986 of file channel.c.
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().
|
static |
Encrypt or decrypt data via dead cipher.
| cipher | Cipher algorithm |
| ctx | Context |
| src | Data to encrypt or decrypt |
| dst | Buffer for encrypted or decrypted data |
| len | Length of data |
Definition at line 1054 of file channel.c.
|
inlinestatic |
|
static |
Clear cipher algorithm.
| pipe | Secure channel pipe |
Definition at line 1106 of file channel.c.
References channel_dead_cipher, secure_pipe::cipher, secure_pipe::ctx, NULL, and zfree().
Referenced by channel_close(), channel_open(), and 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.
| channel | Secure channel |
| pipe | Secure channel pipe |
| cipher | Cipher algorithm |
| key | Key |
| len | Length of key |
| rc | Return 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.
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().
| int channel_open | ( | struct secure_channel * | channel | ) |
Open secure channel.
| channel | Secure channel |
| rc | Return status code |
Definition at line 1205 of file channel.c.
References assert, channel, channel_clear_cipher(), channel_ephemeral_init(), channel_unkey(), cipher_null, DBGC, NULL, and rc.
Referenced by add_tls().
| void channel_reopen | ( | struct secure_channel * | channel | ) |
Reopen secure channel.
| channel | Secure 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.
References assert, channel, channel_ephemeral_replace(), channel_unkey(), DBGC, and NULL.
Referenced by tls_restart().
| void channel_close | ( | struct secure_channel * | channel | ) |
Close secure channel.
| channel | Secure 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.
References assert, channel, channel_clear_cipher(), channel_ephemeral_replace(), channel_unkey(), DBGC, and NULL.
Referenced by add_tls(), and tls_close().
| struct cipher_algorithm channel_dead_cipher |
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.
Referenced by channel_clear_cipher(), and channel_init().