114#define ENOTTY_TRANSPORT __einfo_error ( EINFO_ENOTTY_TRANSPORT )
115#define EINFO_ENOTTY_TRANSPORT \
116 __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Untransportable key" )
117#define EPERM_NOT_CONFIDENTIAL __einfo_error ( EINFO_EPERM_NOT_CONFIDENTIAL )
118#define EINFO_EPERM_NOT_CONFIDENTIAL \
119 __einfo_uniqify ( EINFO_EPERM, 0x01, "Not confidential" )
120#define EPERM_NOT_VALID __einfo_error ( EINFO_EPERM_NOT_VALID )
121#define EINFO_EPERM_NOT_VALID \
122 __einfo_uniqify ( EINFO_EPERM, 0x02, "Peer certificate not valid" )
123#define EPROTO_NOT_KEYED __einfo_error ( EINFO_EPROTO_NOT_KEYED )
124#define EINFO_EPROTO_NOT_KEYED \
125 __einfo_uniqify ( EINFO_EPROTO, 0x01, "No shared key material" )
126#define EPROTO_NOT_BOUND __einfo_error ( EINFO_EPROTO_NOT_BOUND )
127#define EINFO_EPROTO_NOT_BOUND \
128 __einfo_uniqify ( EINFO_EPROTO, 0x02, "No bound peer identity" )
129#define EPROTO_NOT_CONFIRMED __einfo_error ( EINFO_EPROTO_NOT_CONFIRMED )
130#define EINFO_EPROTO_NOT_CONFIRMED \
131 __einfo_uniqify ( EINFO_EPROTO, 0x03, "No confirmed peer identity" )
166 static const char salt[16] =
"channel master";
173 sizeof (
channel->ephemeral ) ) ) != 0 ) {
174 DBGC (
channel,
"CHANNEL %p could not generate random data: "
234 sizeof (
channel->ephemeral ) );
297 size_t privsize = exchange->
privsize;
322 size_t privsize = exchange->
privsize;
323 size_t pubsize = exchange->
pubsize;
332 DBGC (
channel,
"CHANNEL %p could not share \"%s\": %s\n",
344 memset (
private, 0,
sizeof (
private ) );
359 const void *
partner,
void *shared ) {
361 size_t privsize = exchange->
privsize;
372 DBGC (
channel,
"CHANNEL %p could not agree \"%s\": %s\n",
385 &accumulated ) ) != 0 ) {
386 DBGC (
channel,
"CHANNEL %p could not apply \"%s\": %s\n",
403 DBGC (
channel,
"CHANNEL %p key material obtained via \"%s\"\n",
412 memset (
private, 0,
sizeof (
private ) );
428 size_t pubsize = exchange->
pubsize;
474 DBGC (
channel,
"CHANNEL %p cannot transport \"%s\"\n",
572 if ( !
channel->props.keyed ) {
573 DBGC (
channel,
"CHANNEL %p cannot bind to empty key\n",
580 DBGC (
channel,
"CHANNEL %p key material bound to \"%s\"\n",
622 DBGC (
channel,
"CHANNEL %p could not verify binding: %s\n",
666 plaintext.
len = sharedsize;
674 ciphertext ) ) != 0 ) {
675 DBGC (
channel,
"CHANNEL %p could not encrypt \"%s\": %s\n",
747 identity =
channel->props.bound;
749 DBGC (
channel,
"CHANNEL %p cannot create pre-shared key "
750 "for unbound peer\n",
channel );
756 DBGC (
channel,
"CHANNEL %p does not support pre-shared "
763 DBGC (
channel,
"CHANNEL %p could not save pre-shared "
770 DBGC (
channel,
"CHANNEL %p key material saved for \"%s\"\n",
792 identity = psid->
bound;
794 DBGC (
channel,
"CHANNEL %p cannot resume from empty "
802 DBGC (
channel,
"CHANNEL %p does not support pre-shared "
805 goto err_unsupported;
810 DBGC (
channel,
"CHANNEL %p could not load pre-shared key: "
817 DBGC (
channel,
"CHANNEL %p key material obtained from pre-shared "
897 const void *auth,
size_t len ) {
905 identity =
channel->props.bound;
907 DBGC (
channel,
"CHANNEL %p cannot authenticate unbound "
916 if ( !
channel->rx.cipher->confidential ) {
917 DBGC (
channel,
"CHANNEL %p cannot confirm key with a "
918 "non-confidential cipher\n",
channel );
924 DBGC (
channel,
"CHANNEL %p failed to authenticate: %s\n",
931 DBGC (
channel,
"CHANNEL %p key material confirmed for \"%s\"\n",
995 identity =
channel->props.confirmed;
997 DBGC (
channel,
"CHANNEL %p cannot establish unconfirmed "
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 );
1016 DBGC (
channel,
"CHANNEL %p identity \"%s\" does not match "
1024 DBGC (
channel,
"CHANNEL %p identity \"%s\" has not been "
1031 DBGC (
channel,
"CHANNEL %p established for \"%s\"\n",
1056 void *dst,
size_t len ) {
1057 static const uint8_t pattern[] = { 0xde, 0xad, 0xc1, 0xfa };
1062 for ( i = 0 ; i <
len ; i++ )
1063 bytes[i] = pattern[ i %
sizeof ( pattern ) ];
1097 return ( ( pipe == &
channel->tx ) ?
"TX" :
1098 ( pipe == &
channel->rx ) ?
"RX" :
"INVALID" );
1139 const void *
key,
size_t len ) {
1146 if ( !
channel->props.keyed ) {
1147 DBGC (
channel,
"CHANNEL %p refusing to use definitely "
1148 "non-derived shared secret\n",
channel );
1156 "non-confidential cipher \"%s\"\n",
channel,
1159 goto err_confidential;
1165 if ( ! pipe->
ctx ) {
1172 DBGC (
channel,
"CHANNEL %p %s could not set \"%s\" key: %s\n",
1178 DBGC (
channel,
"CHANNEL %p %s using \"%s\" with %zd-bit key\n",
#define NULL
NULL pointer (VOID *).
struct golan_eq_context ctx
u8 signature
CPU signature.
union @162305117151260234136356364136041353210355154177 key
struct arbelprm_rc_send_wqe rc
pseudo_bit_t value[0x00020]
#define assert(condition)
Assert a condition at run-time.
static int channel_ephemeral_init(struct secure_channel *channel)
Initialise ephemeral master secret.
#define EPROTO_NOT_CONFIRMED
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.
struct cipher_algorithm channel_dead_cipher
Dead cipher.
#define EPERM_NOT_CONFIDENTIAL
static int channel_bind(struct secure_channel *channel, struct x509_certificate *identity)
Set bound peer identity.
static const char * channel_pipe_name(struct secure_channel *channel, struct secure_pipe *pipe)
Get pipe name (for debugging).
static void channel_unbind(struct secure_channel *channel)
Clear bound peer identity.
static int channel_key_transport(struct secure_channel *channel, struct exchange_algorithm *exchange, void *shared)
Transport shared secret.
void channel_reopen(struct secure_channel *channel)
Reopen secure channel.
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.
static void channel_unconfirm(struct secure_channel *channel)
Clear confirmed peer identity.
void channel_ephemeral(struct secure_channel *channel, const void *info, size_t info_len, void *out, size_t len)
Generate ephemeral secret.
void channel_unkey(struct secure_channel *channel)
Clear shared secret.
int channel_key_agree(struct secure_channel *channel, struct exchange_algorithm *exchange, const void *partner)
Agree shared secret.
static int channel_key(struct secure_channel *channel, struct exchange_algorithm *exchange, const void *partner, void *shared)
Generate and apply shared secret.
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.
int channel_open(struct secure_channel *channel)
Open secure channel.
static void channel_clear_cipher(struct secure_pipe *pipe)
Clear cipher algorithm.
static void channel_ephemeral_replace(struct secure_channel *channel)
Replace ephemeral master secret.
void channel_close(struct secure_channel *channel)
Close secure channel.
static void channel_key_private(struct secure_channel *channel, struct exchange_algorithm *exchange, void *private)
Generate private key.
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_establish(struct secure_channel *channel, const char *name, struct x509_root *root)
Establish channel as trusted for application data.
int channel_save(struct secure_channel *channel, struct secure_preshared_identity *psid)
Save a pre-shared key.
int channel_confirm(struct secure_channel *channel, const void *auth, size_t len)
Confirm peer identity.
static void channel_unestablish(struct secure_channel *channel)
Clear established peer identity.
int channel_key_share(struct secure_channel *channel, struct exchange_algorithm *exchange, void *public)
Share public key.
void channel_ephemeral_label(struct secure_channel *channel, const char *label, void *out, size_t len)
Generate labelled ephemeral secret.
int channel_load(struct secure_channel *channel, struct secure_preshared_identity *psid)
Load a pre-shared key.
Secure channel abstraction.
#define channel_ephemeral_algorithm
Ephemeral master secret digest algorithm.
static void channel_clear_preshared(struct secure_preshared_identity *psid)
Clear pre-shared bound peer identity.
struct cipher_algorithm cipher_null
int cipher_null_setiv(struct cipher_algorithm *cipher __unused, void *ctx __unused, const void *iv __unused, size_t ivlen __unused)
void cipher_null_auth(struct cipher_algorithm *cipher __unused, void *ctx __unused, void *auth __unused)
int cipher_null_setkey(struct cipher_algorithm *cipher __unused, void *ctx __unused, const void *key __unused, size_t keylen __unused)
struct eth_slow_lacp_entity_tlv partner
Partner information.
#define __unused
Declare a variable or data structure as unused.
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
#define ENOMEM
Not enough space.
#define ENOTSUP
Operation not supported.
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
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.
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.
HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
uint8_t info_len
Reject information length.
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
static int pubkey_encrypt(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext)
static int exchange_share(struct exchange_algorithm *exchange, const void *private, void *public)
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)
static int exchange_agree(struct exchange_algorithm *exchange, const void *private, const void *partner, void *shared)
static int is_key_transport(struct exchange_algorithm *exchange)
void * memset(void *dest, int character, size_t len) __nonnull
void * zalloc(size_t size)
Allocate cleared memory.
void zfree(void *ptr)
Clear and free memory.
Dynamic memory allocation.
uint32_t channel
RNDIS channel.
int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
struct stp_switch root
Root switch.
char * strerror(int errno)
Retrieve string representation of error number.
size_t strlen(const char *src)
Get length of string.
const void * data
Start of data.
size_t len
Length of data.
const char * name
Algorithm name.
int confidential
Cipher is capable of providing confidentiality.
size_t ctxsize
Context size.
A message digest algorithm.
A key exchange algorithm.
size_t sharedsize
Shared secret size.
size_t privsize
Private key size.
size_t pubsize
Public key size.
const char * name
Algorithm name.
A secure channel transmit or receive pipe.
void * ctx
Cipher context.
struct cipher_algorithm * cipher
Cipher algorithm.
A pre-shared bound peer identity.
struct x509_certificate * bound
Bound peer identity.
struct x509_subject subject
Subject.
struct asn1_cursor raw
Raw public key information.
An X.509 root certificate list.
struct x509_public_key public_key
Public key information.
int x509_is_valid(struct x509_certificate *cert, struct x509_root *root)
Check if X.509 certificate is valid.
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.