iPXE
tls.c File Reference

Transport Layer Security Protocol. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/pending.h>
#include <ipxe/hmac.h>
#include <ipxe/md5.h>
#include <ipxe/sha1.h>
#include <ipxe/sha256.h>
#include <ipxe/md5_sha1.h>
#include <ipxe/aes.h>
#include <ipxe/rsa.h>
#include <ipxe/hkdf.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/x509.h>
#include <ipxe/privkey.h>
#include <ipxe/certstore.h>
#include <ipxe/rootcert.h>
#include <ipxe/rbg.h>
#include <ipxe/validator.h>
#include <ipxe/job.h>
#include <ipxe/ffdhe.h>
#include <ipxe/tls.h>
#include <config/crypto.h>

Go to the source code of this file.

Data Structures

struct  tls24_t
 A TLS 24-bit integer. More...

Macros

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )
#define EINFO_EINVAL_CHANGE_CIPHER
#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )
#define EINFO_EINVAL_ALERT
#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )
#define EINFO_EINVAL_HELLO
#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )
#define EINFO_EINVAL_CERTIFICATE
#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )
#define EINFO_EINVAL_CERTIFICATES
#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )
#define EINFO_EINVAL_HELLO_DONE
#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )
#define EINFO_EINVAL_FINISHED
#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )
#define EINFO_EINVAL_HANDSHAKE
#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )
#define EINFO_EINVAL_IV
#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )
#define EINFO_EINVAL_PADDING
#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )
#define EINFO_EINVAL_RX_STATE
#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )
#define EINFO_EINVAL_MAC
#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )
#define EINFO_EINVAL_TICKET
#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )
#define EINFO_EINVAL_KEY_EXCHANGE
#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )
#define EINFO_EIO_ALERT
#define ENOENT_CERT   __einfo_error ( EINFO_ENOENT_CERT )
#define EINFO_ENOENT_CERT
#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )
#define EINFO_ENOMEM_CONTEXT
#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )
#define EINFO_ENOMEM_CERTIFICATE
#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )
#define EINFO_ENOMEM_CHAIN
#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )
#define EINFO_ENOMEM_TX_PLAINTEXT
#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )
#define EINFO_ENOMEM_TX_CIPHERTEXT
#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )
#define EINFO_ENOMEM_RX_DATA
#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )
#define EINFO_ENOMEM_RX_CONCAT
#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )
#define EINFO_ENOTSUP_CIPHER
#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )
#define EINFO_ENOTSUP_NULL
#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )
#define EINFO_ENOTSUP_SIG_HASH
#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )
#define EINFO_ENOTSUP_VERSION
#define ENOTSUP_GROUP   __einfo_error ( EINFO_ENOTSUP_GROUP )
#define EINFO_ENOTSUP_GROUP
#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )
#define EINFO_EPERM_ALERT
#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )
#define EINFO_EPERM_VERIFY
#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )
#define EINFO_EPERM_RENEG_INSECURE
#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )
#define EINFO_EPERM_RENEG_VERIFY
#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )
#define EINFO_EPERM_KEY_EXCHANGE
#define EPERM_EMS   __einfo_error ( EINFO_EPERM_EMS )
#define EINFO_EPERM_EMS
#define EPERM_BOUND   __einfo_error ( EINFO_EPERM_BOUND )
#define EINFO_EPERM_BOUND
#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )
#define EINFO_EPROTO_VERSION
#define tls_prf_label(tls, out, out_len, label, ...)
 Generate secure pseudo-random data.
#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )
 Number of supported cipher suites.
#define TLS_NUM_SIG_HASH_ALGORITHMS   table_num_entries ( TLS_SIG_HASH_ALGORITHMS )
 Number of supported signature and hash algorithms.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 FILE_SECBOOT (PERMITTED)
static LIST_HEAD (tls_sessions)
 List of TLS session.
static void tls_regenerate_ephemeral_master (struct tls_connection *tls)
 Regenerate ephemeral master secret.
static void tls_tx_resume_all (struct tls_session *session)
 Resume TX state machine for all connections within a session.
static struct io_buffertls_alloc_iob (struct tls_connection *tls, size_t len)
 Allocate I/O buffer for transmitted record(s).
static int tls_send_handshake (struct tls_connection *tls, const void *data, size_t len)
 Transmit Handshake record.
static int tls_send_alert (struct tls_connection *tls, unsigned int level, unsigned int description)
 Transmit Alert record.
static int tls_send_record (struct tls_connection *tls, unsigned int type, struct io_buffer *iobuf)
 Send plaintext record(s).
static int tls_send_plaintext (struct tls_connection *tls, unsigned int type, const void *data, size_t len)
 Send plaintext record.
static void tls_clear_cipher (struct tls_connection *tls, struct tls_cipherspec *cipherspec)
static void tls_clear_digest (struct tls_connection *tls)
 Clear key schedule digest algorithm.
static void tls_verify_handshake (struct tls_connection *tls, void *out)
 Calculate handshake verification hash.
static unsigned long tls_uint24 (const tls24_t *field24)
 Extract 24-bit field value.
static void tls_set_uint24 (tls24_t *field24, unsigned long value)
 Set 24-bit field value.
static int tls_ready (struct tls_connection *tls)
 Determine if TLS connection is ready for application data.
static int tls_version (struct tls_connection *tls, unsigned int version)
 Check for TLS version.
static void free_tls_session (struct refcnt *refcnt)
 Free TLS session.
static void free_tls (struct refcnt *refcnt)
 Free TLS connection.
static void tls_close (struct tls_connection *tls, int rc)
 Finish with TLS connection.
static void tls_close_alert (struct tls_connection *tls, int rc)
 Send closure alert and finish with TLS connection.
static int tls_generate_ephemeral_master (struct tls_connection *tls)
 Generate ephemeral master secret.
static void tls_ephemeral (struct tls_connection *tls, const void *info, size_t info_len, void *out, size_t len)
 Generate ephemeral secret.
static void tls_ephemeral_label (struct tls_connection *tls, const char *label, void *out, size_t len)
 Generate ephemeral secret from label.
static void tls_clear_binding (struct tls_connection *tls)
 Clear key schedule binding.
static void tls_set_binding (struct tls_connection *tls, struct x509_certificate *cert)
 Bind key schedule to a server identity.
static int tls_set_digest (struct tls_connection *tls, struct digest_algorithm *digest)
 Set key schedule digest algorithm.
static void tls_hmac_update_va (struct digest_algorithm *digest, void *ctx, va_list args)
 Update HMAC with a list of ( data, len ) pairs.
static void tls_p_hash_va (struct tls_connection *tls, struct digest_algorithm *digest, const void *hkey, void *out, size_t out_len, va_list seeds)
 Generate secure pseudo-random data using a single hash function.
static void tls_prf (struct tls_connection *tls, void *out, size_t out_len,...)
 Generate secure pseudo-random data.
static void tls_set_kdf_master (struct tls_connection *tls, const void *secret, size_t secret_len)
 Set key derivation function master secret.
static int tls_share_ephemeral (struct tls_connection *tls, void *public)
 Share ephemeral public key.
static int tls_agree_ephemeral (struct tls_connection *tls, const void *partner, size_t partner_len, int strip)
 Agree ephemeral shared secret (i.e.
static void tls_generate_master_secret (struct tls_connection *tls)
 Generate master secret.
static int tls_generate_keys (struct tls_connection *tls)
 Generate key material.
static void tls_generate_resumption_master (struct tls_connection *tls)
 Generate resumption master secret.
static void tls_resume_secret (struct tls_connection *tls)
 Resume from resumption master secret.
static int tls_add_handshake (struct tls_connection *tls, const void *data, size_t len)
 Add handshake record to verification hash.
static struct tls_cipher_suitetls_find_cipher_suite (unsigned int cipher_suite)
 Identify cipher suite.
static void tls_clear_cipher (struct tls_connection *tls __unused, struct tls_cipherspec *cipherspec)
 Clear cipher suite.
static int tls_set_cipher (struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
 Set cipher suite.
static int tls_select_cipher (struct tls_connection *tls, unsigned int cipher_suite)
 Select next cipher suite.
static int tls_change_cipher (struct tls_connection *tls, struct tls_cipherspec_pair *pair)
 Activate next cipher suite.
static struct tls_signature_hash_algorithm * tls_signature_hash_algorithm (struct pubkey_algorithm *pubkey, struct digest_algorithm *digest)
 Find TLS signature and hash algorithm.
static struct tls_signature_hash_algorithmtls_find_signature_hash (unsigned int code)
 Find TLS signature and hash algorithm.
static struct tls_named_grouptls_find_named_group (unsigned int named_group)
 Identify named key exchange group.
static struct tls_named_grouptls_find_param_group (const void *dh_p, size_t dh_p_len, const void *dh_g, size_t dh_g_len)
 Identify named key exchange group by Diffie-Hellman parameters.
static int tls_verify_dh_params (struct tls_connection *tls, const void *data, size_t len, size_t param_len)
 Verify Diffie-Hellman parameter signature.
static int tls_new_server_key_exchange_pubkey (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Key Exchange record using public key transport.
static int tls_send_client_key_exchange_pubkey (struct tls_connection *tls)
 Transmit Client Key Exchange record using public key exchange.
static int tls_new_server_key_exchange_dhe (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Key Exchange record using DHE key exchange.
static int tls_send_client_key_exchange_dhe (struct tls_connection *tls)
 Transmit Client Key Exchange record using DHE key exchange.
static int tls_new_server_key_exchange_ecdhe (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Key Exchange record using ECDHE key exchange.
static int tls_send_client_key_exchange_ecdhe (struct tls_connection *tls)
 Transmit Client Key Exchange record using ECDHE key exchange.
static void tls_tx_resume (struct tls_connection *tls)
 Resume TX state machine.
static void tls_restart (struct tls_connection *tls)
 Restart negotiation.
static int tls_client_hello (struct tls_connection *tls, int(*action)(struct tls_connection *tls, const void *data, size_t len))
 Digest or transmit Client Hello record.
static int tls_send_client_hello (struct tls_connection *tls)
 Transmit Client Hello record.
static int tls_send_certificate (struct tls_connection *tls)
 Transmit Certificate record.
static int tls_send_client_key_exchange (struct tls_connection *tls)
 Transmit Client Key Exchange record.
static int tls_send_certificate_verify (struct tls_connection *tls)
 Transmit Certificate Verify record.
static int tls_send_change_cipher (struct tls_connection *tls)
 Transmit Change Cipher record.
static int tls_send_finished (struct tls_connection *tls)
 Transmit Finished record.
static int tls_new_change_cipher (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Change Cipher record.
static int tls_new_alert (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Alert record.
static int tls_new_hello_request (struct tls_connection *tls, const void *data __unused, size_t len __unused)
 Receive new Hello Request handshake record.
static int tls_new_server_hello (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Hello handshake record.
static int tls_new_session_ticket (struct tls_connection *tls, const void *data, size_t len)
 Receive New Session Ticket handshake record.
static int tls_parse_chain (struct tls_connection *tls, const void *data, size_t len)
 Parse certificate chain.
static int tls_new_certificate (struct tls_connection *tls, const void *data, size_t len)
 Receive new Certificate handshake record.
static int tls_new_server_key_exchange (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Key Exchange handshake record.
static int tls_new_certificate_request (struct tls_connection *tls, const void *data __unused, size_t len __unused)
 Receive new Certificate Request handshake record.
static int tls_new_server_hello_done (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Hello Done handshake record.
static int tls_new_finished (struct tls_connection *tls, const void *data, size_t len)
 Receive new Finished handshake record.
static int tls_new_handshake (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Handshake record.
static int tls_new_unknown (struct tls_connection *tls __unused, struct io_buffer *iobuf)
 Receive new unknown record.
static int tls_new_data (struct tls_connection *tls, struct list_head *rx_data)
 Receive new data record.
static int tls_new_record (struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
 Receive new record.
static void tls_hmac_init (struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
 Initialise HMAC.
static void tls_hmac_update (struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
 Update HMAC.
static void tls_hmac_final (struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
 Finalise HMAC.
static void tls_hmac (struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, const void *data, size_t len, void *hmac)
 Calculate HMAC.
static void tls_hmac_list (struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, struct list_head *list, void *hmac)
 Calculate HMAC over list of I/O buffers.
static size_t tls_iob_reserved (struct tls_connection *tls, size_t len)
 Calculate maximum additional length required for transmitted record(s).
static int tls_verify_padding (struct tls_connection *tls, struct io_buffer *iobuf)
 Verify block padding.
static int tls_new_ciphertext (struct tls_connection *tls, struct tls_header *tlshdr, struct list_head *rx_data)
 Receive new ciphertext record.
static size_t tls_plainstream_window (struct tls_connection *tls)
 Check flow control window.
static int tls_plainstream_deliver (struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Deliver datagram as raw data.
static int tls_progress (struct tls_connection *tls, struct job_progress *progress)
 Report job progress.
static int tls_newdata_process_header (struct tls_connection *tls)
 Handle received TLS header.
static int tls_newdata_process_data (struct tls_connection *tls)
 Handle received TLS data payload.
static size_t tls_cipherstream_window (struct tls_connection *tls)
 Check flow control window.
static int tls_cipherstream_deliver (struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *xfer __unused)
 Receive new ciphertext.
static void tls_validator_done (struct tls_connection *tls, int rc)
 Handle certificate validation completion.
static void tls_tx_step (struct tls_connection *tls)
 TLS TX state machine.
static int tls_session (struct tls_connection *tls, const char *name)
 Find or create session for TLS connection.
int add_tls (struct interface *xfer, const char *name, struct x509_root *root, struct private_key *key)
 Add TLS on an interface.
 REQUIRING_SYMBOL (add_tls)
 REQUIRE_OBJECT (config_crypto)

Variables

struct tls_cipher_suite tls_cipher_suite_null
 Null cipher suite.
struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm
 Public key exchange algorithm.
struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm
 Ephemeral Diffie-Hellman key exchange algorithm.
struct tls_key_exchange_algorithm tls_ecdhe_exchange_algorithm
 Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm.
static struct interface_operation tls_plainstream_ops []
 TLS plaintext stream interface operations.
static struct interface_descriptor tls_plainstream_desc
 TLS plaintext stream interface descriptor.
static struct interface_operation tls_cipherstream_ops []
 TLS ciphertext stream interface operations.
static struct interface_descriptor tls_cipherstream_desc
 TLS ciphertext stream interface descriptor.
static struct interface_operation tls_validator_ops []
 TLS certificate validator interface operations.
static struct interface_descriptor tls_validator_desc
 TLS certificate validator interface descriptor.
static struct process_descriptor tls_process_desc
 TLS TX process descriptor.

Detailed Description

Transport Layer Security Protocol.

Definition in file tls.c.

Macro Definition Documentation

◆ EINVAL_CHANGE_CIPHER

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )

Definition at line 59 of file tls.c.

Referenced by tls_new_change_cipher().

◆ EINFO_EINVAL_CHANGE_CIPHER

#define EINFO_EINVAL_CHANGE_CIPHER
Value:
"Invalid Change Cipher record" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition errno.h:224
#define EINFO_EINVAL
Definition errno.h:473

Definition at line 60 of file tls.c.

60#define EINFO_EINVAL_CHANGE_CIPHER \
61 __einfo_uniqify ( EINFO_EINVAL, 0x01, \
62 "Invalid Change Cipher record" )

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

Definition at line 63 of file tls.c.

Referenced by tls_new_alert().

◆ EINFO_EINVAL_ALERT

#define EINFO_EINVAL_ALERT
Value:
"Invalid Alert record" )

Definition at line 64 of file tls.c.

64#define EINFO_EINVAL_ALERT \
65 __einfo_uniqify ( EINFO_EINVAL, 0x02, \
66 "Invalid Alert record" )

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

Definition at line 67 of file tls.c.

Referenced by tls_new_server_hello().

◆ EINFO_EINVAL_HELLO

#define EINFO_EINVAL_HELLO
Value:
"Invalid Server Hello record" )

Definition at line 68 of file tls.c.

68#define EINFO_EINVAL_HELLO \
69 __einfo_uniqify ( EINFO_EINVAL, 0x03, \
70 "Invalid Server Hello record" )

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

Definition at line 71 of file tls.c.

Referenced by tls_parse_chain().

◆ EINFO_EINVAL_CERTIFICATE

#define EINFO_EINVAL_CERTIFICATE
Value:
"Invalid Certificate" )

Definition at line 72 of file tls.c.

72#define EINFO_EINVAL_CERTIFICATE \
73 __einfo_uniqify ( EINFO_EINVAL, 0x04, \
74 "Invalid Certificate" )

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

Definition at line 75 of file tls.c.

Referenced by tls_new_certificate().

◆ EINFO_EINVAL_CERTIFICATES

#define EINFO_EINVAL_CERTIFICATES
Value:
"Invalid Server Certificate record" )

Definition at line 76 of file tls.c.

76#define EINFO_EINVAL_CERTIFICATES \
77 __einfo_uniqify ( EINFO_EINVAL, 0x05, \
78 "Invalid Server Certificate record" )

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

Definition at line 79 of file tls.c.

Referenced by tls_new_server_hello_done().

◆ EINFO_EINVAL_HELLO_DONE

#define EINFO_EINVAL_HELLO_DONE
Value:
"Invalid Server Hello Done record" )

Definition at line 80 of file tls.c.

80#define EINFO_EINVAL_HELLO_DONE \
81 __einfo_uniqify ( EINFO_EINVAL, 0x06, \
82 "Invalid Server Hello Done record" )

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

Definition at line 83 of file tls.c.

Referenced by tls_new_finished().

◆ EINFO_EINVAL_FINISHED

#define EINFO_EINVAL_FINISHED
Value:
"Invalid Server Finished record" )

Definition at line 84 of file tls.c.

84#define EINFO_EINVAL_FINISHED \
85 __einfo_uniqify ( EINFO_EINVAL, 0x07, \
86 "Invalid Server Finished record" )

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

Definition at line 87 of file tls.c.

◆ EINFO_EINVAL_HANDSHAKE

#define EINFO_EINVAL_HANDSHAKE
Value:
"Invalid Handshake record" )

Definition at line 88 of file tls.c.

88#define EINFO_EINVAL_HANDSHAKE \
89 __einfo_uniqify ( EINFO_EINVAL, 0x08, \
90 "Invalid Handshake record" )

◆ EINVAL_IV

#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )

Definition at line 91 of file tls.c.

Referenced by tls_new_ciphertext().

◆ EINFO_EINVAL_IV

#define EINFO_EINVAL_IV
Value:
"Invalid initialisation vector" )

Definition at line 92 of file tls.c.

92#define EINFO_EINVAL_IV \
93 __einfo_uniqify ( EINFO_EINVAL, 0x0a, \
94 "Invalid initialisation vector" )

◆ EINVAL_PADDING

#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )

Definition at line 95 of file tls.c.

Referenced by tls_verify_padding().

◆ EINFO_EINVAL_PADDING

#define EINFO_EINVAL_PADDING
Value:
"Invalid block padding" )

Definition at line 96 of file tls.c.

96#define EINFO_EINVAL_PADDING \
97 __einfo_uniqify ( EINFO_EINVAL, 0x0b, \
98 "Invalid block padding" )

◆ EINVAL_RX_STATE

#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )

Definition at line 99 of file tls.c.

Referenced by tls_cipherstream_deliver().

◆ EINFO_EINVAL_RX_STATE

#define EINFO_EINVAL_RX_STATE
Value:
"Invalid receive state" )

Definition at line 100 of file tls.c.

100#define EINFO_EINVAL_RX_STATE \
101 __einfo_uniqify ( EINFO_EINVAL, 0x0c, \
102 "Invalid receive state" )

◆ EINVAL_MAC

#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )

Definition at line 103 of file tls.c.

Referenced by tls_new_ciphertext().

◆ EINFO_EINVAL_MAC

#define EINFO_EINVAL_MAC
Value:
"Invalid MAC or authentication tag" )

Definition at line 104 of file tls.c.

104#define EINFO_EINVAL_MAC \
105 __einfo_uniqify ( EINFO_EINVAL, 0x0d, \
106 "Invalid MAC or authentication tag" )

◆ EINVAL_TICKET

#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )

Definition at line 107 of file tls.c.

Referenced by tls_new_session_ticket().

◆ EINFO_EINVAL_TICKET

#define EINFO_EINVAL_TICKET
Value:
"Invalid New Session Ticket record")

Definition at line 108 of file tls.c.

108#define EINFO_EINVAL_TICKET \
109 __einfo_uniqify ( EINFO_EINVAL, 0x0e, \
110 "Invalid New Session Ticket record")

◆ EINVAL_KEY_EXCHANGE

◆ EINFO_EINVAL_KEY_EXCHANGE

#define EINFO_EINVAL_KEY_EXCHANGE
Value:
"Invalid Server Key Exchange record" )

Definition at line 112 of file tls.c.

112#define EINFO_EINVAL_KEY_EXCHANGE \
113 __einfo_uniqify ( EINFO_EINVAL, 0x0f, \
114 "Invalid Server Key Exchange record" )

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

Definition at line 115 of file tls.c.

Referenced by tls_new_alert().

◆ EINFO_EIO_ALERT

#define EINFO_EIO_ALERT
Value:
"Unknown alert level" )
#define EINFO_EIO
Definition errno.h:478

Definition at line 116 of file tls.c.

116#define EINFO_EIO_ALERT \
117 __einfo_uniqify ( EINFO_EIO, 0x01, \
118 "Unknown alert level" )

◆ ENOENT_CERT

#define ENOENT_CERT   __einfo_error ( EINFO_ENOENT_CERT )

◆ EINFO_ENOENT_CERT

#define EINFO_ENOENT_CERT
Value:
"Missing server certificate" )
#define EINFO_ENOENT
Definition errno.h:559

Definition at line 120 of file tls.c.

120#define EINFO_ENOENT_CERT \
121 __einfo_uniqify ( EINFO_ENOENT, 0x01, \
122 "Missing server certificate" )

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

Definition at line 123 of file tls.c.

Referenced by tls_set_cipher().

◆ EINFO_ENOMEM_CONTEXT

#define EINFO_ENOMEM_CONTEXT
Value:
"Not enough space for crypto context" )
#define EINFO_ENOMEM
Definition errno.h:579

Definition at line 124 of file tls.c.

124#define EINFO_ENOMEM_CONTEXT \
125 __einfo_uniqify ( EINFO_ENOMEM, 0x01, \
126 "Not enough space for crypto context" )

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

Definition at line 127 of file tls.c.

Referenced by tls_send_certificate().

◆ EINFO_ENOMEM_CERTIFICATE

#define EINFO_ENOMEM_CERTIFICATE
Value:
"Not enough space for certificate" )

Definition at line 128 of file tls.c.

128#define EINFO_ENOMEM_CERTIFICATE \
129 __einfo_uniqify ( EINFO_ENOMEM, 0x02, \
130 "Not enough space for certificate" )

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

Definition at line 131 of file tls.c.

Referenced by tls_parse_chain().

◆ EINFO_ENOMEM_CHAIN

#define EINFO_ENOMEM_CHAIN
Value:
"Not enough space for certificate chain" )

Definition at line 132 of file tls.c.

132#define EINFO_ENOMEM_CHAIN \
133 __einfo_uniqify ( EINFO_ENOMEM, 0x03, \
134 "Not enough space for certificate chain" )

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

Definition at line 135 of file tls.c.

Referenced by tls_send_plaintext().

◆ EINFO_ENOMEM_TX_PLAINTEXT

#define EINFO_ENOMEM_TX_PLAINTEXT
Value:
"Not enough space for transmitted plaintext" )

Definition at line 136 of file tls.c.

136#define EINFO_ENOMEM_TX_PLAINTEXT \
137 __einfo_uniqify ( EINFO_ENOMEM, 0x04, \
138 "Not enough space for transmitted plaintext" )

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

Definition at line 139 of file tls.c.

◆ EINFO_ENOMEM_TX_CIPHERTEXT

#define EINFO_ENOMEM_TX_CIPHERTEXT
Value:
"Not enough space for transmitted ciphertext" )

Definition at line 140 of file tls.c.

140#define EINFO_ENOMEM_TX_CIPHERTEXT \
141 __einfo_uniqify ( EINFO_ENOMEM, 0x05, \
142 "Not enough space for transmitted ciphertext" )

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

Definition at line 143 of file tls.c.

Referenced by tls_newdata_process_header().

◆ EINFO_ENOMEM_RX_DATA

#define EINFO_ENOMEM_RX_DATA
Value:
"Not enough space for received data" )

Definition at line 144 of file tls.c.

144#define EINFO_ENOMEM_RX_DATA \
145 __einfo_uniqify ( EINFO_ENOMEM, 0x07, \
146 "Not enough space for received data" )

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

Definition at line 147 of file tls.c.

Referenced by tls_new_record().

◆ EINFO_ENOMEM_RX_CONCAT

#define EINFO_ENOMEM_RX_CONCAT
Value:
"Not enough space to concatenate received data" )

Definition at line 148 of file tls.c.

148#define EINFO_ENOMEM_RX_CONCAT \
149 __einfo_uniqify ( EINFO_ENOMEM, 0x08, \
150 "Not enough space to concatenate received data" )

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

Definition at line 151 of file tls.c.

Referenced by tls_select_cipher().

◆ EINFO_ENOTSUP_CIPHER

#define EINFO_ENOTSUP_CIPHER
Value:
"Unsupported cipher" )
#define EINFO_ENOTSUP
Definition errno.h:634

Definition at line 152 of file tls.c.

152#define EINFO_ENOTSUP_CIPHER \
153 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, \
154 "Unsupported cipher" )

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

Definition at line 155 of file tls.c.

Referenced by tls_change_cipher().

◆ EINFO_ENOTSUP_NULL

#define EINFO_ENOTSUP_NULL
Value:
"Refusing to use null cipher" )

Definition at line 156 of file tls.c.

156#define EINFO_ENOTSUP_NULL \
157 __einfo_uniqify ( EINFO_ENOTSUP, 0x02, \
158 "Refusing to use null cipher" )

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

Definition at line 159 of file tls.c.

Referenced by tls_send_certificate_verify(), and tls_verify_dh_params().

◆ EINFO_ENOTSUP_SIG_HASH

#define EINFO_ENOTSUP_SIG_HASH
Value:
"Unsupported signature and hash algorithm" )

Definition at line 160 of file tls.c.

160#define EINFO_ENOTSUP_SIG_HASH \
161 __einfo_uniqify ( EINFO_ENOTSUP, 0x03, \
162 "Unsupported signature and hash algorithm" )

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

Definition at line 163 of file tls.c.

◆ EINFO_ENOTSUP_VERSION

#define EINFO_ENOTSUP_VERSION
Value:
"Unsupported protocol version" )

Definition at line 164 of file tls.c.

164#define EINFO_ENOTSUP_VERSION \
165 __einfo_uniqify ( EINFO_ENOTSUP, 0x04, \
166 "Unsupported protocol version" )

◆ ENOTSUP_GROUP

#define ENOTSUP_GROUP   __einfo_error ( EINFO_ENOTSUP_GROUP )

Definition at line 167 of file tls.c.

Referenced by tls_new_server_key_exchange_dhe(), and tls_new_server_key_exchange_ecdhe().

◆ EINFO_ENOTSUP_GROUP

#define EINFO_ENOTSUP_GROUP
Value:
"Unsupported key exchange group" )

Definition at line 168 of file tls.c.

168#define EINFO_ENOTSUP_GROUP \
169 __einfo_uniqify ( EINFO_ENOTSUP, 0x05, \
170 "Unsupported key exchange group" )

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

Definition at line 171 of file tls.c.

Referenced by tls_new_alert().

◆ EINFO_EPERM_ALERT

#define EINFO_EPERM_ALERT
Value:
"Received fatal alert" )
#define EINFO_EPERM
Definition errno.h:659

Definition at line 172 of file tls.c.

172#define EINFO_EPERM_ALERT \
173 __einfo_uniqify ( EINFO_EPERM, 0x01, \
174 "Received fatal alert" )

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

Definition at line 175 of file tls.c.

Referenced by tls_new_finished().

◆ EINFO_EPERM_VERIFY

#define EINFO_EPERM_VERIFY
Value:
"Handshake verification failed" )

Definition at line 176 of file tls.c.

176#define EINFO_EPERM_VERIFY \
177 __einfo_uniqify ( EINFO_EPERM, 0x02, \
178 "Handshake verification failed" )

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

Definition at line 179 of file tls.c.

Referenced by tls_new_hello_request().

◆ EINFO_EPERM_RENEG_INSECURE

#define EINFO_EPERM_RENEG_INSECURE
Value:
"Secure renegotiation not supported" )

Definition at line 180 of file tls.c.

180#define EINFO_EPERM_RENEG_INSECURE \
181 __einfo_uniqify ( EINFO_EPERM, 0x04, \
182 "Secure renegotiation not supported" )

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

Definition at line 183 of file tls.c.

Referenced by tls_new_server_hello().

◆ EINFO_EPERM_RENEG_VERIFY

#define EINFO_EPERM_RENEG_VERIFY
Value:
"Secure renegotiation verification failed" )

Definition at line 184 of file tls.c.

184#define EINFO_EPERM_RENEG_VERIFY \
185 __einfo_uniqify ( EINFO_EPERM, 0x05, \
186 "Secure renegotiation verification failed" )

◆ EPERM_KEY_EXCHANGE

#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )

Definition at line 187 of file tls.c.

Referenced by tls_verify_dh_params().

◆ EINFO_EPERM_KEY_EXCHANGE

#define EINFO_EPERM_KEY_EXCHANGE
Value:
"ServerKeyExchange verification failed" )

Definition at line 188 of file tls.c.

188#define EINFO_EPERM_KEY_EXCHANGE \
189 __einfo_uniqify ( EINFO_EPERM, 0x06, \
190 "ServerKeyExchange verification failed" )

◆ EPERM_EMS

#define EPERM_EMS   __einfo_error ( EINFO_EPERM_EMS )

Definition at line 191 of file tls.c.

Referenced by tls_new_server_hello().

◆ EINFO_EPERM_EMS

#define EINFO_EPERM_EMS
Value:
"Extended master secret extension mismatch" )

Definition at line 192 of file tls.c.

192#define EINFO_EPERM_EMS \
193 __einfo_uniqify ( EINFO_EPERM, 0x07, \
194 "Extended master secret extension mismatch" )

◆ EPERM_BOUND

#define EPERM_BOUND   __einfo_error ( EINFO_EPERM_BOUND )

Definition at line 195 of file tls.c.

Referenced by tls_send_finished().

◆ EINFO_EPERM_BOUND

#define EINFO_EPERM_BOUND
Value:
"Bound identity not validated" )

Definition at line 196 of file tls.c.

196#define EINFO_EPERM_BOUND \
197 __einfo_uniqify ( EINFO_EPERM, 0x08, \
198 "Bound identity not validated" )

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

Definition at line 199 of file tls.c.

Referenced by tls_new_server_hello().

◆ EINFO_EPROTO_VERSION

#define EINFO_EPROTO_VERSION
Value:
"Illegal protocol version upgrade" )
#define EINFO_EPROTO
Definition errno.h:669

Definition at line 200 of file tls.c.

200#define EINFO_EPROTO_VERSION \
201 __einfo_uniqify ( EINFO_EPROTO, 0x01, \
202 "Illegal protocol version upgrade" )

◆ tls_prf_label

#define tls_prf_label ( tls,
out,
out_len,
label,
... )
Value:
tls_prf ( (tls), (out), (out_len), \
label, ( sizeof ( label ) - 1 ), __VA_ARGS__, NULL )
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
__be32 out[4]
Definition CIB_PRM.h:8
A text label widget.
Definition label.h:16
static void tls_prf(struct tls_connection *tls, void *out, size_t out_len,...)
Generate secure pseudo-random data.
Definition tls.c:695

Generate secure pseudo-random data.

Parameters
tlsTLS connection
outOutput buffer
out_lenLength of output buffer
labelString literal label
...( data, len ) pairs of seed data

Definition at line 748 of file tls.c.

748#define tls_prf_label( tls, out, out_len, label, ... ) \
749 tls_prf ( (tls), (out), (out_len), \
750 label, ( sizeof ( label ) - 1 ), __VA_ARGS__, NULL )

Referenced by tls_generate_keys(), tls_generate_master_secret(), tls_new_finished(), and tls_send_finished().

◆ TLS_NUM_CIPHER_SUITES

#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )

Number of supported cipher suites.

Definition at line 1199 of file tls.c.

Referenced by tls_client_hello().

◆ TLS_NUM_SIG_HASH_ALGORITHMS

#define TLS_NUM_SIG_HASH_ALGORITHMS   table_num_entries ( TLS_SIG_HASH_ALGORITHMS )

Number of supported signature and hash algorithms.

Definition at line 1345 of file tls.c.

1345#define TLS_NUM_SIG_HASH_ALGORITHMS \
1346 table_num_entries ( TLS_SIG_HASH_ALGORITHMS )

Referenced by tls_client_hello().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ LIST_HEAD()

LIST_HEAD ( tls_sessions )
static

List of TLS session.

References data, len, and type.

◆ tls_regenerate_ephemeral_master()

void tls_regenerate_ephemeral_master ( struct tls_connection * tls)
static

Regenerate ephemeral master secret.

Parameters
tlsTLS connection

Definition at line 488 of file tls.c.

488 {
489 struct tls_key_schedule *key = &tls->key;
490
491 /* Derive a new ephemeral master secret */
492 tls_ephemeral_label ( tls, "key reset", key->ephemeral,
493 sizeof ( key->ephemeral ) );
494
495 /* (Re)generate client random bytes */
496 tls_ephemeral_label ( tls, "client random", &tls->client.random.random,
497 sizeof ( tls->client.random.random ) );
498}
union @162305117151260234136356364136041353210355154177 key
uint8_t random[32]
Random data.
Definition tls.h:328
struct tls_client_random random
Random bytes.
Definition tls.h:501
struct tls_key_schedule key
Key schedule.
Definition tls.h:559
struct tls_client client
Client state.
Definition tls.h:565
TLS key schedule.
Definition tls.h:370
static void tls_ephemeral_label(struct tls_connection *tls, const char *label, void *out, size_t len)
Generate ephemeral secret from label.
Definition tls.c:474

References tls_connection::client, key, tls_connection::key, tls_client::random, tls_client_random::random, and tls_ephemeral_label().

Referenced by tls_close(), and tls_restart().

◆ tls_tx_resume_all()

void tls_tx_resume_all ( struct tls_session * session)
static

Resume TX state machine for all connections within a session.

Parameters
sessionTLS session

Definition at line 1911 of file tls.c.

1911 {
1912 struct tls_connection *tls;
1913
1915 tls_tx_resume ( tls );
1916}
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
A TLS connection.
Definition tls.h:527
struct tls_session * session
Session.
Definition tls.h:532
struct list_head list
List of connections within the same session.
Definition tls.h:534
struct list_head conn
List of connections.
Definition tls.h:363
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition tls.c:1902

References tls_session::conn, tls_connection::list, list_for_each_entry, tls_connection::session, and tls_tx_resume().

Referenced by tls_close(), and tls_new_finished().

◆ tls_alloc_iob()

struct io_buffer * tls_alloc_iob ( struct tls_connection * tls,
size_t len )
static

Allocate I/O buffer for transmitted record(s).

Parameters
tlsTLS connection
lenI/O buffer payload length
Return values
iobufI/O buffer

Definition at line 3458 of file tls.c.

3459 {
3460 struct io_buffer *iobuf;
3461 size_t reserve;
3462
3463 /* Calculate maximum additional length to reserve */
3464 reserve = tls_iob_reserved ( tls, len );
3465
3466 /* Allocate I/O buffer */
3467 iobuf = xfer_alloc_iob ( &tls->cipherstream, ( reserve + len ) );
3468 if ( ! iobuf )
3469 return NULL;
3470
3471 /* Reserve space */
3472 iob_reserve ( iobuf, reserve );
3473
3474 return iobuf;
3475}
ring len
Length.
Definition dwmac.h:226
#define iob_reserve(iobuf, len)
Definition iobuf.h:132
A persistent I/O buffer.
Definition iobuf.h:98
struct interface cipherstream
Ciphertext stream.
Definition tls.h:547
static size_t tls_iob_reserved(struct tls_connection *tls, size_t len)
Calculate maximum additional length required for transmitted record(s).
Definition tls.c:3431
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159

References tls_connection::cipherstream, iob_reserve, len, NULL, tls_iob_reserved(), and xfer_alloc_iob().

Referenced by tls_send_certificate(), and tls_send_plaintext().

◆ tls_send_handshake()

int tls_send_handshake ( struct tls_connection * tls,
const void * data,
size_t len )
static

Transmit Handshake record.

Parameters
tlsTLS connection
dataPlaintext record
lenLength of plaintext record
Return values
rcReturn status code

Definition at line 1949 of file tls.c.

1950 {
1951
1952 /* Send record */
1954}
uint8_t data[48]
Additional event data.
Definition ena.h:11
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition tls.c:3632
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition tls.h:61

References data, len, tls_send_plaintext(), and TLS_TYPE_HANDSHAKE.

Referenced by tls_send_certificate_verify(), tls_send_client_hello(), tls_send_client_key_exchange_dhe(), tls_send_client_key_exchange_ecdhe(), tls_send_client_key_exchange_pubkey(), and tls_send_finished().

◆ tls_send_alert()

int tls_send_alert ( struct tls_connection * tls,
unsigned int level,
unsigned int description )
static

Transmit Alert record.

Parameters
tlsTLS connection
levelAlert level
descriptionAlert description
Return values
rcReturn status code

Definition at line 2392 of file tls.c.

2393 {
2394 const struct {
2395 uint8_t level;
2396 uint8_t description;
2397 } __attribute__ (( packed )) alert = {
2398 .level = level,
2399 .description = description,
2400 };
2401
2402 /* Send record */
2403 return tls_send_plaintext ( tls, TLS_TYPE_ALERT, &alert,
2404 sizeof ( alert ) );
2405}
unsigned char uint8_t
Definition stdint.h:10
#define __attribute__(x)
Definition compiler.h:10
void alert(unsigned int row, const char *fmt,...)
Show alert message.
Definition message.c:104
#define TLS_TYPE_ALERT
Alert content type.
Definition tls.h:58

References __attribute__, alert(), tls_send_plaintext(), and TLS_TYPE_ALERT.

Referenced by tls_close_alert().

◆ tls_send_record()

int tls_send_record ( struct tls_connection * tls,
unsigned int type,
struct io_buffer * iobuf )
static

Send plaintext record(s).

Parameters
tlsTLS connection
typeRecord type
iobufI/O buffer
Return values
rcReturn status code

Definition at line 3485 of file tls.c.

3486 {
3487 struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.active;
3488 struct tls_cipher_suite *suite = cipherspec->suite;
3489 struct cipher_algorithm *cipher = suite->cipher;
3490 struct digest_algorithm *digest = suite->digest;
3491 struct {
3492 uint8_t fixed[suite->fixed_iv_len];
3493 uint8_t rec[suite->record_iv_len];
3494 } __attribute__ (( packed )) iv;
3495 struct tls_auth_header authhdr;
3496 struct tls_header *tlshdr;
3497 uint8_t mac[digest->digestsize];
3498 const void *plaintext;
3499 const void *encrypt;
3500 void *ciphertext;
3501 size_t record_len;
3502 size_t encrypt_len;
3503 size_t pad_len;
3504 size_t len;
3505 int rc;
3506
3507 /* Record plaintext pointer and length */
3508 plaintext = iobuf->data;
3509 len = iob_len ( iobuf );
3510
3511 /* Add to handshake digest if applicable */
3512 if ( type == TLS_TYPE_HANDSHAKE )
3513 tls_add_handshake ( tls, plaintext, len );
3514
3515 /* Start constructing ciphertext at start of reserved space */
3516 iob_push ( iobuf, tls_iob_reserved ( tls, len ) );
3517 iob_unput ( iobuf, iob_len ( iobuf ) );
3518
3519 /* Construct records */
3520 do {
3521 /* Limit length of this record (may be zero) */
3522 record_len = len;
3523 if ( record_len > TLS_TX_BUFSIZE )
3524 record_len = TLS_TX_BUFSIZE;
3525
3526 /* Construct authentication header */
3527 authhdr.seq = cpu_to_be64 ( tls->tx.seq );
3528 authhdr.header.type = type;
3529 authhdr.header.version = htons ( tls->version );
3530 authhdr.header.length = htons ( record_len );
3531
3532 /* Construct and set initialisation vector */
3533 memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
3534 tls_ephemeral ( tls, &authhdr, sizeof ( authhdr ), iv.rec,
3535 sizeof ( iv.rec ) );
3536 if ( ( rc = cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv,
3537 sizeof ( iv ) ) ) != 0 ) {
3538 DBGC ( tls, "TLS %p could not set TX IV: %s\n",
3539 tls, strerror ( rc ) );
3540 goto err_setiv;
3541 }
3542
3543 /* Process authentication data */
3544 if ( suite->mac_len ) {
3545 tls_hmac ( cipherspec, &authhdr, plaintext, record_len,
3546 mac );
3547 }
3548 if ( is_auth_cipher ( cipher ) ) {
3549 cipher_encrypt ( cipher, cipherspec->cipher_ctx,
3550 &authhdr, NULL, sizeof ( authhdr ) );
3551 }
3552
3553 /* Calculate encryption length */
3554 encrypt_len = ( record_len + suite->mac_len );
3555 if ( is_block_cipher ( cipher ) ) {
3556 pad_len = ( ( ( cipher->blocksize - 1 ) &
3557 -( encrypt_len + 1 ) ) + 1 );
3558 } else {
3559 pad_len = 0;
3560 }
3561 encrypt_len += pad_len;
3562
3563 /* Add record header */
3564 tlshdr = iob_put ( iobuf, sizeof ( *tlshdr ) );
3565 tlshdr->type = type;
3566 tlshdr->version = htons ( tls->version );
3567 tlshdr->length = htons ( sizeof ( iv.rec ) + encrypt_len +
3568 cipher->authsize );
3569
3570 /* Add record initialisation vector, if applicable */
3571 memcpy ( iob_put ( iobuf, sizeof ( iv.rec ) ), iv.rec,
3572 sizeof ( iv.rec ) );
3573
3574 /* Copy plaintext data if necessary */
3575 ciphertext = iob_put ( iobuf, record_len );
3576 assert ( ciphertext <= plaintext );
3577 if ( encrypt_len > record_len ) {
3578 memmove ( ciphertext, plaintext, record_len );
3579 encrypt = ciphertext;
3580 } else {
3581 encrypt = plaintext;
3582 }
3583
3584 /* Add MAC, if applicable */
3585 memcpy ( iob_put ( iobuf, suite->mac_len ), mac,
3586 suite->mac_len );
3587
3588 /* Add padding, if applicable */
3589 memset ( iob_put ( iobuf, pad_len ), ( pad_len - 1 ), pad_len );
3590
3591 /* Encrypt data and append authentication tag */
3592 DBGC2 ( tls, "Sending plaintext data:\n" );
3593 DBGC2_HDA ( tls, 0, encrypt, encrypt_len );
3594 cipher_encrypt ( cipher, cipherspec->cipher_ctx, encrypt,
3595 ciphertext, encrypt_len );
3596 cipher_auth ( cipher, cipherspec->cipher_ctx,
3597 iob_put ( iobuf, cipher->authsize ) );
3598
3599 /* Move to next record */
3600 tls->tx.seq += 1;
3601 plaintext += record_len;
3602 len -= record_len;
3603
3604 } while ( len );
3605
3606 /* Send ciphertext */
3607 if ( ( rc = xfer_deliver_iob ( &tls->cipherstream,
3608 iob_disown ( iobuf ) ) ) != 0 ) {
3609 DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
3610 tls, strerror ( rc ) );
3611 goto err_deliver;
3612 }
3613
3614 assert ( iobuf == NULL );
3615 return 0;
3616
3617 err_deliver:
3618 err_setiv:
3619 free_iob ( iobuf );
3620 return rc;
3621}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition eltorito.h:1
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13
#define DBGC2(...)
Definition compiler.h:547
#define DBGC2_HDA(...)
Definition compiler.h:548
#define DBGC(...)
Definition compiler.h:530
#define htons(value)
Definition byteswap.h:136
#define cpu_to_be64(value)
Definition byteswap.h:112
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition crypto.h:352
static int cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition crypto.h:316
static int is_auth_cipher(struct cipher_algorithm *cipher)
Definition crypto.h:357
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition crypto.h:326
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition crypto.h:342
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void * memmove(void *dest, const void *src, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_push(iobuf, len)
Definition iobuf.h:149
#define iob_put(iobuf, len)
Definition iobuf.h:185
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_unput(iobuf, len)
Definition iobuf.h:200
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A cipher algorithm.
Definition crypto.h:58
size_t blocksize
Block size.
Definition crypto.h:68
size_t authsize
Authentication tag size.
Definition crypto.h:82
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27
void * data
Start of data.
Definition iobuf.h:113
TLS authentication header.
Definition tls.h:164
A TLS cipher suite.
Definition tls.h:219
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition tls.h:235
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition tls.h:225
uint8_t mac_len
MAC length.
Definition tls.h:239
uint8_t record_iv_len
Record initialisation vector length.
Definition tls.h:237
struct digest_algorithm * digest
MAC digest algorithm.
Definition tls.h:227
struct tls_cipherspec active
Current cipher specification.
Definition tls.h:295
A TLS cipher specification.
Definition tls.h:279
void * fixed_iv
Fixed initialisation vector.
Definition tls.h:289
struct tls_cipher_suite * suite
Cipher suite.
Definition tls.h:281
void * cipher_ctx
Bulk encryption cipher context.
Definition tls.h:285
struct tls_tx tx
Transmit state.
Definition tls.h:561
uint16_t version
Protocol version.
Definition tls.h:550
A TLS header.
Definition tls.h:30
uint16_t version
Protocol version.
Definition tls.h:40
uint16_t length
Length of payload.
Definition tls.h:42
uint8_t type
Content type.
Definition tls.h:35
uint64_t seq
Sequence number.
Definition tls.h:473
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition tls.h:471
static void tls_ephemeral(struct tls_connection *tls, const void *info, size_t info_len, void *out, size_t len)
Generate ephemeral secret.
Definition tls.c:457
static void tls_hmac(struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, const void *data, size_t len, void *hmac)
Calculate HMAC.
Definition tls.c:3390
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition tls.c:1157
#define TLS_TX_BUFSIZE
TX maximum fragment length.
Definition tls.h:579
u8 iv[16]
Initialization vector.
Definition wpa.h:33
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256

References __attribute__, tls_cipherspec_pair::active, assert, cipher_algorithm::authsize, cipher_algorithm::blocksize, tls_cipher_suite::cipher, cipher_auth(), tls_cipherspec::cipher_ctx, cipher_encrypt, cipher_setiv(), tls_tx::cipherspec, tls_connection::cipherstream, cpu_to_be64, io_buffer::data, DBGC, DBGC2, DBGC2_HDA, tls_cipher_suite::digest, digest_algorithm::digestsize, fixed, tls_cipherspec::fixed_iv, tls_cipher_suite::fixed_iv_len, free_iob(), tls_auth_header::header, htons, iob_disown, iob_len(), iob_push, iob_put, iob_unput, is_auth_cipher(), is_block_cipher(), iv, len, tls_header::length, mac, tls_cipher_suite::mac_len, memcpy(), memmove(), memset(), NULL, rc, tls_cipher_suite::record_iv_len, tls_auth_header::seq, tls_tx::seq, strerror(), tls_cipherspec::suite, tls_add_handshake(), tls_ephemeral(), tls_hmac(), tls_iob_reserved(), TLS_TX_BUFSIZE, TLS_TYPE_HANDSHAKE, tls_connection::tx, tls_header::type, type, tls_connection::version, tls_header::version, and xfer_deliver_iob().

Referenced by tls_plainstream_deliver(), tls_send_certificate(), and tls_send_plaintext().

◆ tls_send_plaintext()

int tls_send_plaintext ( struct tls_connection * tls,
unsigned int type,
const void * data,
size_t len )
static

Send plaintext record.

Parameters
tlsTLS connection
typeRecord type
dataPlaintext record
lenLength of plaintext record
Return values
rcReturn status code

Definition at line 3632 of file tls.c.

3633 {
3634 struct io_buffer *iobuf;
3635 int rc;
3636
3637 /* Allocate I/O buffer */
3638 iobuf = tls_alloc_iob ( tls, len );
3639 if ( ! iobuf )
3640 return -ENOMEM_TX_PLAINTEXT;
3641 memcpy ( iob_put ( iobuf, len ), data, len );
3642
3643 /* Transmit I/O buffer */
3644 if ( ( rc = tls_send_record ( tls, type, iob_disown ( iobuf ) ) ) != 0 )
3645 return rc;
3646
3647 return 0;
3648}
static struct io_buffer * tls_alloc_iob(struct tls_connection *tls, size_t len)
Allocate I/O buffer for transmitted record(s).
Definition tls.c:3458
static int tls_send_record(struct tls_connection *tls, unsigned int type, struct io_buffer *iobuf)
Send plaintext record(s).
Definition tls.c:3485
#define ENOMEM_TX_PLAINTEXT
Definition tls.c:135

References data, ENOMEM_TX_PLAINTEXT, iob_disown, iob_put, len, memcpy(), rc, tls_alloc_iob(), tls_send_record(), and type.

Referenced by tls_send_alert(), tls_send_change_cipher(), and tls_send_handshake().

◆ tls_clear_cipher() [1/2]

void tls_clear_cipher ( struct tls_connection * tls,
struct tls_cipherspec * cipherspec )
static

References out.

Referenced by add_tls(), free_tls(), tls_change_cipher(), and tls_set_cipher().

◆ tls_clear_digest()

void tls_clear_digest ( struct tls_connection * tls)
static

Clear key schedule digest algorithm.

Parameters
tlsTLS connection

Definition at line 542 of file tls.c.

542 {
543 struct tls_key_schedule *key = &tls->key;
544
545 /* Set null digest algorithm */
546 key->digest = &digest_null;
547
548 /* Free any dynamic storage */
549 zfree ( key->dynamic );
550 key->dynamic = NULL;
551 key->handshake = NULL;
552 key->kdf = NULL;
553 key->kdfsize = 0;
554
555 /* Key schedule no longer contains any shared secret */
556 tls_clear_binding ( tls );
557 key->keyed = 0;
558}
struct digest_algorithm digest_null
Definition crypto_null.c:53
void zfree(void *ptr)
Clear and free memory.
Definition malloc.c:738
static void tls_clear_binding(struct tls_connection *tls)
Clear key schedule binding.
Definition tls.c:505

References digest_null, key, tls_connection::key, NULL, tls_clear_binding(), and zfree().

Referenced by add_tls(), free_tls(), and tls_set_digest().

◆ tls_verify_handshake()

void tls_verify_handshake ( struct tls_connection * tls,
void * out )
static

Calculate handshake verification hash.

Parameters
tlsTLS connection
outOutput buffer

Calculates the digest over all handshake messages seen so far.

Definition at line 1174 of file tls.c.

1174 {
1175 struct tls_key_schedule *key = &tls->key;
1176 struct digest_algorithm *digest = key->digest;
1177 uint8_t ctx[ digest->ctxsize ];
1178
1179 memcpy ( ctx, key->handshake, sizeof ( ctx ) );
1180 digest_final ( digest, ctx, out );
1181}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:305
size_t ctxsize
Context size.
Definition crypto.h:23

References ctx, digest_algorithm::ctxsize, digest_final(), key, tls_connection::key, memcpy(), and out.

Referenced by tls_generate_master_secret(), tls_new_finished(), tls_send_certificate_verify(), and tls_send_finished().

◆ tls_uint24()

unsigned long tls_uint24 ( const tls24_t * field24)
inlinestatic

Extract 24-bit field value.

Parameters
field2424-bit field
Return values
valueField value

Definition at line 251 of file tls.c.

251 {
252
253 return ( ( field24->high << 16 ) | be16_to_cpu ( field24->low ) );
254}
#define be16_to_cpu(value)
Definition byteswap.h:116
uint8_t high
High byte.
Definition tls.c:238
uint16_t low
Low word.
Definition tls.c:240

References be16_to_cpu, tls24_t::high, and tls24_t::low.

Referenced by tls_new_certificate(), tls_new_handshake(), and tls_parse_chain().

◆ tls_set_uint24()

void tls_set_uint24 ( tls24_t * field24,
unsigned long value )
static

Set 24-bit field value.

Parameters
field2424-bit field
valueField value

Definition at line 262 of file tls.c.

262 {
263
264 field24->high = ( value >> 16 );
265 field24->low = cpu_to_be16 ( value );
266}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
#define cpu_to_be16(value)
Definition byteswap.h:110

References cpu_to_be16, tls24_t::high, tls24_t::low, and value.

Referenced by tls_send_certificate().

◆ tls_ready()

int tls_ready ( struct tls_connection * tls)
static

Determine if TLS connection is ready for application data.

Parameters
tlsTLS connection
Return values
is_readyTLS connection is ready

Definition at line 274 of file tls.c.

274 {
275 return ( ( ! is_pending ( &tls->client.negotiation ) ) &&
276 ( ! is_pending ( &tls->server.negotiation ) ) );
277}
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition pending.h:25
struct pending_operation negotiation
Security negotiation pending operation.
Definition tls.h:507
struct tls_server server
Server state.
Definition tls.h:567
struct pending_operation negotiation
Security negotiation pending operation.
Definition tls.h:523

References tls_connection::client, is_pending(), tls_client::negotiation, tls_server::negotiation, and tls_connection::server.

Referenced by tls_cipherstream_window(), tls_new_data(), tls_new_hello_request(), tls_plainstream_deliver(), and tls_plainstream_window().

◆ tls_version()

int tls_version ( struct tls_connection * tls,
unsigned int version )
inlinestatic

Check for TLS version.

Parameters
tlsTLS connection
versionTLS version
Return values
at_leastTLS connection is using at least the specified version

Check that TLS connection uses at least the specified protocol version. Optimise down to a compile-time constant true result if this is already guaranteed by the minimum supported version check.

Definition at line 291 of file tls.c.

291 {
292 return ( ( TLS_VERSION_MIN >= version ) ||
293 ( tls->version >= version ) );
294}
u32 version
Driver version.
Definition ath9k_hw.c:1985
#define TLS_VERSION_MIN
Minimum TLS version.
Definition crypto.h:14

References TLS_VERSION_MIN, tls_connection::version, and version.

Referenced by tls_generate_resumption_master(), tls_prf(), tls_select_cipher(), tls_send_certificate_verify(), tls_set_digest(), tls_set_kdf_master(), and tls_verify_dh_params().

◆ free_tls_session()

void free_tls_session ( struct refcnt * refcnt)
static

Free TLS session.

Parameters
refcntReference counter

Definition at line 308 of file tls.c.

308 {
309 struct tls_session *session =
311
312 /* Sanity check */
313 assert ( list_empty ( &session->conn ) );
314
315 /* Remove from list of sessions */
316 list_del ( &session->list );
317
318 /* Free dynamically-allocated resources */
319 x509_root_put ( session->root );
320 privkey_put ( session->key );
321 x509_put ( session->cert );
322 zfree ( session->ticket );
323
324 /* Free session */
325 zfree ( session );
326}
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition privkey.h:42
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A reference counter.
Definition refcnt.h:27
A TLS session.
Definition tls.h:332
struct private_key * key
Private key.
Definition tls.h:343
struct x509_certificate * cert
Server certificate.
Definition tls.h:346
struct x509_root * root
Root of trust.
Definition tls.h:341
void * ticket
Session ticket.
Definition tls.h:352
struct list_head list
List of sessions.
Definition tls.h:336
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition x509.h:278
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition x509.h:404

References assert, tls_session::cert, tls_session::conn, container_of, tls_session::key, tls_session::list, list_del, list_empty, privkey_put(), tls_session::root, tls_session::ticket, x509_put(), x509_root_put(), and zfree().

Referenced by tls_session().

◆ free_tls()

void free_tls ( struct refcnt * refcnt)
static

Free TLS connection.

Parameters
refcntReference counter

Definition at line 333 of file tls.c.

333 {
334 struct tls_connection *tls =
336 struct tls_session *session = tls->session;
337 struct io_buffer *iobuf;
338 struct io_buffer *tmp;
339
340 /* Free dynamically-allocated resources */
341 zfree ( tls->new_session_ticket );
342 tls_clear_cipher ( tls, &tls->tx.cipherspec.active );
343 tls_clear_cipher ( tls, &tls->tx.cipherspec.pending );
344 tls_clear_cipher ( tls, &tls->rx.cipherspec.active );
345 tls_clear_cipher ( tls, &tls->rx.cipherspec.pending );
346 tls_clear_digest ( tls );
347 list_for_each_entry_safe ( iobuf, tmp, &tls->rx.data, list ) {
348 list_del ( &iobuf->list );
349 free_iob ( iobuf );
350 }
351 free_iob ( tls->rx.handshake );
352 privkey_put ( tls->client.key );
353 x509_chain_put ( tls->client.chain );
354 x509_chain_put ( tls->server.chain );
355 x509_root_put ( tls->server.root );
356
357 /* Drop reference to session */
358 assert ( list_empty ( &tls->list ) );
359 ref_put ( &session->refcnt );
360
361 /* Free TLS structure itself */
362 zfree ( tls );
363}
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:105
struct tls_cipherspec pending
Next cipher specification.
Definition tls.h:297
struct private_key * key
Private key (if used).
Definition tls.h:503
struct x509_chain * chain
Certificate chain (if used).
Definition tls.h:505
struct tls_rx rx
Receive state.
Definition tls.h:563
void * new_session_ticket
New session ticket.
Definition tls.h:540
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition tls.h:483
struct list_head data
List of received data buffers.
Definition tls.h:493
struct io_buffer * handshake
Received handshake fragment.
Definition tls.h:495
struct x509_root * root
Root of trust.
Definition tls.h:515
struct x509_chain * chain
Certificate chain.
Definition tls.h:517
struct refcnt refcnt
Reference counter.
Definition tls.h:334
static void tls_clear_digest(struct tls_connection *tls)
Clear key schedule digest algorithm.
Definition tls.c:542
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition x509.h:300

References tls_cipherspec_pair::active, assert, tls_client::chain, tls_server::chain, tls_rx::cipherspec, tls_tx::cipherspec, tls_connection::client, container_of, tls_rx::data, free_iob(), tls_rx::handshake, tls_client::key, io_buffer::list, tls_connection::list, list_del, list_empty, list_for_each_entry_safe, tls_connection::new_session_ticket, tls_cipherspec_pair::pending, privkey_put(), ref_put, tls_session::refcnt, tls_server::root, tls_connection::rx, tls_connection::server, tls_connection::session, tls_clear_cipher(), tls_clear_digest(), tmp, tls_connection::tx, x509_chain_put(), x509_root_put(), and zfree().

Referenced by add_tls().

◆ tls_close()

void tls_close ( struct tls_connection * tls,
int rc )
static

Finish with TLS connection.

Parameters
tlsTLS connection
rcStatus code

Definition at line 371 of file tls.c.

371 {
372
373 /* Remove pending operations, if applicable */
376 pending_put ( &tls->server.validation );
377
378 /* Remove process */
379 process_del ( &tls->tx.process );
380
381 /* Close all interfaces */
382 intf_shutdown ( &tls->cipherstream, rc );
383 intf_shutdown ( &tls->plainstream, rc );
384 intf_shutdown ( &tls->server.validator, rc );
385
386 /* Remove from session */
387 list_del ( &tls->list );
388 INIT_LIST_HEAD ( &tls->list );
389
390 /* Destroy ephemeral master secret */
392
393 /* Resume all other connections, in case we were the lead connection */
394 tls_tx_resume_all ( tls->session );
395}
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition pending.c:59
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
struct interface plainstream
Plaintext stream.
Definition tls.h:545
struct pending_operation validation
Certificate validation pending operation.
Definition tls.h:521
struct interface validator
Certificate validator.
Definition tls.h:519
struct process process
Transmit process.
Definition tls.h:477
static void tls_regenerate_ephemeral_master(struct tls_connection *tls)
Regenerate ephemeral master secret.
Definition tls.c:488
static void tls_tx_resume_all(struct tls_session *session)
Resume TX state machine for all connections within a session.
Definition tls.c:1911

References tls_connection::cipherstream, tls_connection::client, INIT_LIST_HEAD, intf_shutdown(), tls_connection::list, list_del, tls_client::negotiation, tls_server::negotiation, pending_put(), tls_connection::plainstream, tls_tx::process, process_del(), rc, tls_connection::server, tls_connection::session, tls_regenerate_ephemeral_master(), tls_tx_resume_all(), tls_connection::tx, tls_server::validation, and tls_server::validator.

Referenced by tls_close_alert(), and tls_new_alert().

◆ tls_close_alert()

void tls_close_alert ( struct tls_connection * tls,
int rc )
static

Send closure alert and finish with TLS connection.

Parameters
tlsTLS connection
rcStatus code

Definition at line 403 of file tls.c.

403 {
404
405 /* Send closure alert */
407
408 /* Close connection */
409 tls_close ( tls, rc );
410}
static int tls_send_alert(struct tls_connection *tls, unsigned int level, unsigned int description)
Transmit Alert record.
Definition tls.c:2392
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition tls.c:371
#define TLS_ALERT_CLOSE_NOTIFY
Definition tls.h:84
#define TLS_ALERT_WARNING
Definition tls.h:80

References rc, TLS_ALERT_CLOSE_NOTIFY, TLS_ALERT_WARNING, tls_close(), and tls_send_alert().

Referenced by tls_cipherstream_deliver(), tls_tx_step(), and tls_validator_done().

◆ tls_generate_ephemeral_master()

int tls_generate_ephemeral_master ( struct tls_connection * tls)
static

Generate ephemeral master secret.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 425 of file tls.c.

425 {
426 struct tls_key_schedule *key = &tls->key;
428 static const char salt[16] = "ephemeral master";
429 int rc;
430
431 /* Generate random bits with no additional input and without
432 * prediction resistance
433 */
434 if ( ( rc = rbg_generate ( NULL, 0, 0, key->ephemeral,
435 sizeof ( key->ephemeral ) ) ) != 0 ) {
436 DBGC ( tls, "TLS %p could not generate random data: %s\n",
437 tls, strerror ( rc ) );
438 return rc;
439 }
440
441 /* Generate ephemeral master secret */
442 hkdf_extract ( digest, salt, sizeof ( salt ), key->ephemeral,
443 sizeof ( key->ephemeral ), key->ephemeral );
444
445 return 0;
446}
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
#define tls_ephemeral_algorithm
HKDF algorithm for ephemeral secrets.
Definition tls.h:367

References DBGC, hkdf_extract(), key, tls_connection::key, NULL, rbg_generate(), rc, strerror(), and tls_ephemeral_algorithm.

Referenced by add_tls().

◆ tls_ephemeral()

void tls_ephemeral ( struct tls_connection * tls,
const void * info,
size_t info_len,
void * out,
size_t len )
static

Generate ephemeral secret.

Parameters
tlsTLS connection
infoAdditional information (or NULL)
info_lenLength of additional information
outEphemeral secret to fill in
lenLength of ephemeral secret

Definition at line 457 of file tls.c.

458 {
459 struct tls_key_schedule *key = &tls->key;
461
462 /* Generate from ephemeral master secret and additional information */
463 hkdf_expand ( digest, key->ephemeral, info, info_len, out, len );
464}
u32 info
Definition ar9003_mac.h:0
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 hkdf_expand(), info, info_len, key, tls_connection::key, len, out, and tls_ephemeral_algorithm.

Referenced by tls_ephemeral_label(), and tls_send_record().

◆ tls_ephemeral_label()

void tls_ephemeral_label ( struct tls_connection * tls,
const char * label,
void * out,
size_t len )
static

Generate ephemeral secret from label.

Parameters
tlsTLS connection
labelSecret label
outEphemeral secret to fill in
lenLength of ephemeral secret

Definition at line 474 of file tls.c.

475 {
476
477 /* Generate from ephemeral master secret and label */
478 tls_ephemeral ( tls, label, strlen ( label ), out, len );
479 DBGC2 ( tls, "TLS %p ephemeral %s:\n", tls, label );
480 DBGC2_HDA ( tls, 0, out, len );
481}
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

References DBGC2, DBGC2_HDA, len, out, strlen(), and tls_ephemeral().

Referenced by tls_agree_ephemeral(), tls_regenerate_ephemeral_master(), tls_session(), tls_set_digest(), and tls_share_ephemeral().

◆ tls_clear_binding()

void tls_clear_binding ( struct tls_connection * tls)
static

Clear key schedule binding.

Parameters
tlsTLS connection

Definition at line 505 of file tls.c.

505 {
506 struct tls_key_schedule *key = &tls->key;
507
508 /* Clear any existing binding */
509 x509_put ( key->bound );
510 key->bound = NULL;
511}

References key, tls_connection::key, NULL, and x509_put().

Referenced by tls_agree_ephemeral(), tls_clear_digest(), and tls_set_binding().

◆ tls_set_binding()

void tls_set_binding ( struct tls_connection * tls,
struct x509_certificate * cert )
static

Bind key schedule to a server identity.

Parameters
tlsTLS connection
certServer certificate

Definition at line 519 of file tls.c.

520 {
521 struct tls_key_schedule *key = &tls->key;
522
523 /* Clear any existing binding */
524 tls_clear_binding ( tls );
525
526 /* Refuse to bind an empty shared secret */
527 if ( ! key->keyed ) {
528 DBGC ( tls, "TLS %p refusing empty binding\n", tls );
529 return;
530 }
531
532 /* Bind to new identity */
533 key->bound = x509_get ( cert );
534 DBGC ( tls, "TLS %p bound to %s\n", tls, x509_name ( cert ) );
535}
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 DBGC, key, tls_connection::key, tls_clear_binding(), x509_get(), and x509_name().

Referenced by tls_resume_secret(), tls_send_client_key_exchange_pubkey(), and tls_verify_dh_params().

◆ tls_set_digest()

int tls_set_digest ( struct tls_connection * tls,
struct digest_algorithm * digest )
static

Set key schedule digest algorithm.

Parameters
tlsTLS connection
digestKey schedule digest algorithm
Return values
rcReturn status code

Definition at line 567 of file tls.c.

568 {
569 struct tls_key_schedule *key = &tls->key;
570 size_t kdfsize;
571 size_t total;
572 void *dynamic;
573
574 /* Clear existing key schedule digest algorithm */
575 tls_clear_digest ( tls );
576
577 /* Allocate dynamic storage */
578 if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
580 } else {
581 kdfsize = sizeof ( struct md5_sha1_hmac_keys );
582 }
583 total = ( digest->ctxsize + kdfsize );
584 dynamic = zalloc ( total );
585 if ( ! dynamic )
586 return -ENOMEM;
587
588 /* Assign storage */
589 key->dynamic = dynamic;
590 key->handshake = dynamic; dynamic += digest->ctxsize;
591 key->kdf = dynamic; dynamic += kdfsize;
592 assert ( ( key->dynamic + total ) == dynamic );
593 key->kdfsize = kdfsize;
594
595 /* Store digest algorithm */
596 key->digest = digest;
597
598 /* Initialise handshake context */
599 digest_init ( digest, key->handshake );
600
601 /* Poison key derivation function master secret */
602 tls_ephemeral_label ( tls, "kdf poison", key->kdf, kdfsize );
603
604 /* Sanity checks */
605 assert ( ! key->keyed );
606 assert ( ! key->bound );
607
608 return 0;
609}
#define ENOMEM
Not enough space.
Definition errno.h:578
static size_t hmac_keysize(struct digest_algorithm *digest)
Calculate HMAC reduced key size.
Definition hmac.h:35
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:294
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
An MD5+SHA1 HMAC key block.
Definition md5_sha1.h:57
size_t kdfsize
Length of key derivation function secret.
Definition tls.h:463
struct digest_algorithm * digest
Digest algorithm.
Definition tls.h:378
void * dynamic
Dynamically-allocated storage.
Definition tls.h:457
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition tls.c:291
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition tls.h:49

References assert, digest_algorithm::ctxsize, tls_key_schedule::digest, digest_init(), tls_key_schedule::dynamic, ENOMEM, hmac_keysize(), tls_key_schedule::kdfsize, key, tls_connection::key, tls_clear_digest(), tls_ephemeral_label(), tls_version(), TLS_VERSION_TLS_1_2, and zalloc().

Referenced by tls_select_cipher().

◆ tls_hmac_update_va()

void tls_hmac_update_va ( struct digest_algorithm * digest,
void * ctx,
va_list args )
static

Update HMAC with a list of ( data, len ) pairs.

Parameters
digestHash function to use
ctxHMAC context
args( data, len ) pairs of data, terminated by NULL

Definition at line 618 of file tls.c.

619 {
620 void *data;
621 size_t len;
622
623 while ( ( data = va_arg ( args, void * ) ) ) {
624 len = va_arg ( args, size_t );
625 hmac_update ( digest, ctx, data, len );
626 }
627}
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition hmac.h:62
#define va_arg(ap, type)
Definition stdarg.h:9

References ctx, data, hmac_update(), len, and va_arg.

Referenced by tls_p_hash_va().

◆ tls_p_hash_va()

void tls_p_hash_va ( struct tls_connection * tls,
struct digest_algorithm * digest,
const void * hkey,
void * out,
size_t out_len,
va_list seeds )
static

Generate secure pseudo-random data using a single hash function.

Parameters
tlsTLS connection
digestHash function to use
hkeyHMAC key
outOutput buffer
out_lenLength of output buffer
seeds( data, len ) pairs of seed data, terminated by NULL

Definition at line 639 of file tls.c.

641 {
642 uint8_t ctx[ hmac_ctxsize ( digest ) ];
643 uint8_t ctx_partial[ sizeof ( ctx ) ];
644 uint8_t a[digest->digestsize];
645 uint8_t out_tmp[digest->digestsize];
646 size_t frag_len = digest->digestsize;
647 va_list tmp;
648
649 /* Calculate A(1) */
650 hmac_init_key ( digest, ctx, hkey );
651 va_copy ( tmp, seeds );
652 tls_hmac_update_va ( digest, ctx, tmp );
653 va_end ( tmp );
654 hmac_final ( digest, ctx, a );
655 DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name );
656 DBGC2_HD ( tls, &a, sizeof ( a ) );
657
658 /* Generate as much data as required */
659 while ( out_len ) {
660
661 /* Calculate output portion */
662 hmac_init_key ( digest, ctx, hkey );
663 hmac_update ( digest, ctx, a, sizeof ( a ) );
664 memcpy ( ctx_partial, ctx, sizeof ( ctx_partial ) );
665 va_copy ( tmp, seeds );
666 tls_hmac_update_va ( digest, ctx, tmp );
667 va_end ( tmp );
668 hmac_final ( digest, ctx, out_tmp );
669
670 /* Copy output */
671 if ( frag_len > out_len )
672 frag_len = out_len;
673 memcpy ( out, out_tmp, frag_len );
674 DBGC2 ( tls, "TLS %p %s output:\n", tls, digest->name );
675 DBGC2_HD ( tls, out, frag_len );
676
677 /* Calculate A(i) */
678 hmac_final ( digest, ctx_partial, a );
679 DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name );
680 DBGC2_HD ( tls, &a, sizeof ( a ) );
681
682 out += frag_len;
683 out_len -= frag_len;
684 }
685}
#define DBGC2_HD(...)
Definition compiler.h:549
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition hmac.c:124
void hmac_init_key(struct digest_algorithm *digest, void *ctx, const void *key)
Initialise HMAC from reduced key.
Definition hmac.c:82
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition hmac.h:48
#define va_copy(dest, src)
Definition stdarg.h:11
#define va_end(ap)
Definition stdarg.h:10
__builtin_va_list va_list
Definition stdarg.h:7
const char * name
Algorithm name.
Definition crypto.h:21
static void tls_hmac_update_va(struct digest_algorithm *digest, void *ctx, va_list args)
Update HMAC with a list of ( data, len ) pairs.
Definition tls.c:618

References ctx, DBGC2, DBGC2_HD, digest_algorithm::digestsize, hmac_ctxsize(), hmac_final(), hmac_init_key(), hmac_update(), memcpy(), digest_algorithm::name, out, tls_hmac_update_va(), tmp, va_copy, and va_end.

Referenced by tls_prf().

◆ tls_prf()

void tls_prf ( struct tls_connection * tls,
void * out,
size_t out_len,
... )
static

Generate secure pseudo-random data.

Parameters
tlsTLS connection
outOutput buffer
out_lenLength of output buffer
...( data, len ) pairs of seed data, terminated by NULL

Definition at line 695 of file tls.c.

696 {
697 struct tls_key_schedule *key = &tls->key;
698 struct md5_sha1_hmac_keys *hkeys;
699 va_list seeds;
700 va_list tmp;
701 uint8_t buf[out_len];
702 unsigned int i;
703
704 va_start ( seeds, out_len );
705
706 if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
707
708 /* Use P_Hash for TLSv1.2 and later */
709 tls_p_hash_va ( tls, key->digest, key->kdf,
710 out, out_len, seeds );
711
712 } else {
713
714 /* Use combination of P_MD5 and P_SHA-1 for TLSv1.1
715 * and earlier
716 */
717 hkeys = key->kdf;
718
719 /* Calculate MD5 portion */
720 va_copy ( tmp, seeds );
721 tls_p_hash_va ( tls, &md5_algorithm, hkeys->md5,
722 out, out_len, seeds );
723 va_end ( tmp );
724
725 /* Calculate SHA1 portion */
726 va_copy ( tmp, seeds );
727 tls_p_hash_va ( tls, &sha1_algorithm, hkeys->sha1,
728 buf, out_len, seeds );
729 va_end ( tmp );
730
731 /* XOR the two portions together into the final output buffer */
732 for ( i = 0 ; i < out_len ; i++ )
733 *( ( uint8_t * ) out + i ) ^= buf[i];
734 }
735
736 va_end ( seeds );
737}
struct digest_algorithm md5_algorithm
struct digest_algorithm sha1_algorithm
#define va_start(ap, last)
Definition stdarg.h:8
uint8_t md5[MD5_BLOCK_SIZE]
MD5 HMAC key.
Definition md5_sha1.h:59
uint8_t sha1[SHA1_BLOCK_SIZE]
SHA-1 HMAC key.
Definition md5_sha1.h:61
static void tls_p_hash_va(struct tls_connection *tls, struct digest_algorithm *digest, const void *hkey, void *out, size_t out_len, va_list seeds)
Generate secure pseudo-random data using a single hash function.
Definition tls.c:639

References key, tls_connection::key, md5_sha1_hmac_keys::md5, md5_algorithm, out, md5_sha1_hmac_keys::sha1, sha1_algorithm, tls_p_hash_va(), tls_version(), TLS_VERSION_TLS_1_2, tmp, va_copy, va_end, and va_start.

◆ tls_set_kdf_master()

void tls_set_kdf_master ( struct tls_connection * tls,
const void * secret,
size_t secret_len )
static

Set key derivation function master secret.

Parameters
tlsTLS connection
secretSecret
secret_lenLength of secret

Definition at line 759 of file tls.c.

760 {
761 struct tls_key_schedule *key = &tls->key;
762 struct digest_algorithm *digest = key->digest;
763 uint8_t ctx[ hmac_ctxsize ( digest ) ];
764 struct md5_sha1_hmac_keys *hkeys;
765 size_t subsecret_len;
766 const void *md5_secret;
767 const void *sha1_secret;
768
769 DBGC2 ( tls, "TLS %p KDF secret:\n", tls );
770 DBGC2_HD ( tls, secret, secret_len );
771
772 if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
773
774 /* Set HMAC key for TLSv1.2 and later */
775 hmac_key ( digest, ctx, secret, secret_len, key->kdf );
776
777 } else {
778
779 /* Set MD5+SHA1 HMAC keys for TLSv1.1 and earlier */
780 hkeys = key->kdf;
781 assert ( key->digest == &md5_sha1_algorithm );
782 assert ( sizeof ( ctx ) >= hmac_ctxsize ( &md5_algorithm ) );
783 assert ( sizeof ( ctx ) >= hmac_ctxsize ( &sha1_algorithm ) );
784
785 /* Split secret into two, with an overlap of up to one byte */
786 subsecret_len = ( ( secret_len + 1 ) / 2 );
787 md5_secret = secret;
788 sha1_secret = ( secret + secret_len - subsecret_len );
789
790 /* Set MD5 and SHA-1 HMAC keys */
791 hmac_key ( &md5_algorithm, ctx, md5_secret, subsecret_len,
792 hkeys->md5 );
793 hmac_key ( &sha1_algorithm, ctx, sha1_secret, subsecret_len,
794 hkeys->sha1 );
795 }
796}
void hmac_key(struct digest_algorithm *digest, void *ctx, const void *secret, size_t len, void *key)
Construct HMAC reduced key.
Definition hmac.c:59
struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition md5_sha1.c:84

References assert, ctx, DBGC2, DBGC2_HD, hmac_ctxsize(), hmac_key(), key, tls_connection::key, md5_sha1_hmac_keys::md5, md5_algorithm, md5_sha1_algorithm, md5_sha1_hmac_keys::sha1, sha1_algorithm, tls_version(), and TLS_VERSION_TLS_1_2.

Referenced by tls_agree_ephemeral(), tls_generate_master_secret(), and tls_resume_secret().

◆ tls_share_ephemeral()

int tls_share_ephemeral ( struct tls_connection * tls,
void * public )
static

Share ephemeral public key.

Parameters
tlsTLS connection
publicPublic key to fill in
Return values
rcReturn status code

Definition at line 805 of file tls.c.

805 {
806 struct tls_key_schedule *key = &tls->key;
807 struct exchange_algorithm *exchange = key->exchange;
808 size_t privsize = exchange->privsize;
809 struct {
810 uint8_t private[privsize];
811 } tmp;
812 int rc;
813
814 /* (Re)generate ephemeral private key */
815 tls_ephemeral_label ( tls, exchange->name, tmp.private, privsize );
816
817 /* Derive public key */
818 if ( ( rc = exchange_share ( exchange, tmp.private, public ) ) != 0 ) {
819 DBGC ( tls, "TLS %p could not share ephemeral key: %s\n",
820 tls, strerror ( rc ) );
821 goto err_share;
822 }
823
824 err_share:
825 memset ( &tmp, 0, sizeof ( tmp ) );
826 return rc;
827}
static int exchange_share(struct exchange_algorithm *exchange, const void *private, void *public)
Definition crypto.h:397
A key exchange algorithm.
Definition crypto.h:210
size_t privsize
Private key size.
Definition crypto.h:214
const char * name
Algorithm name.
Definition crypto.h:212

References DBGC, exchange_share(), key, tls_connection::key, memset(), exchange_algorithm::name, exchange_algorithm::privsize, rc, strerror(), tls_ephemeral_label(), and tmp.

Referenced by tls_send_client_key_exchange_dhe(), and tls_send_client_key_exchange_ecdhe().

◆ tls_agree_ephemeral()

int tls_agree_ephemeral ( struct tls_connection * tls,
const void * partner,
size_t partner_len,
int strip )
static

Agree ephemeral shared secret (i.e.

pre-master secret)

Parameters
tlsTLS connection
partnerPartner public key
partner_lenLength of partner public key
stripStrip/pad leading zeros
Return values
rcReturn status code

Definition at line 838 of file tls.c.

840 {
841 struct tls_key_schedule *key = &tls->key;
842 struct exchange_algorithm *exchange = key->exchange;
843 size_t privsize = exchange->privsize;
844 size_t pubsize = exchange->pubsize;
845 size_t sharedsize = exchange->sharedsize;
846 struct {
847 uint8_t private[privsize];
849 uint8_t shared[sharedsize];
850 } *tmp;
851 size_t pad_len;
852 size_t shared_len;
853 uint8_t *shared;
854 int rc;
855
856 /* Allocate working space */
857 tmp = zalloc ( sizeof ( *tmp ) );
858 if ( ! tmp ) {
859 rc = -ENOMEM;
860 goto err_alloc;
861 }
862
863 /* (Re)generate ephemeral private key */
864 tls_ephemeral_label ( tls, exchange->name, tmp->private, privsize );
865
866 /* Zero-pad partner key if needed */
867 if ( partner_len > pubsize ) {
868 DBGC ( tls, "TLS %p partner key too long:\n", tls );
869 DBGC_HDA ( tls, 0, partner, partner_len );
871 goto err_partner_len;
872 }
873 pad_len = ( pubsize - partner_len );
874 if ( pad_len && ( ! strip ) ) {
875 DBGC ( tls, "TLS %p partner key too short:\n", tls );
876 DBGC_HDA ( tls, 0, partner, partner_len );
878 goto err_partner_len;
879 }
880 memcpy ( ( tmp->partner + pad_len ), partner, partner_len );
881
882 /* Agree shared secret */
883 if ( ( rc = exchange_agree ( exchange, tmp->private, tmp->partner,
884 tmp->shared ) ) != 0 ) {
885 DBGC ( tls, "TLS %p could not agree shared key: %s\n",
886 tls, strerror ( rc ) );
887 goto err_agree;
888 }
889
890 /* Strip leading zeros if needed */
891 shared = tmp->shared;
892 shared_len = sharedsize;
893 while ( strip && shared_len && ( ! *shared ) ) {
894 shared++;
895 shared_len--;
896 }
897
898 /* Set key derivation function secret to the shared secret */
899 DBGC ( tls, "TLS %p pre-master secret:\n", tls );
900 DBGC_HDA ( tls, 0, shared, shared_len );
901 tls_set_kdf_master ( tls, shared, shared_len );
902
903 /* Key derivation function secret has been overwritten with a
904 * value that was not derived from its previous value, and so
905 * is no longer bound to the server's identity.
906 */
907 tls_clear_binding ( tls );
908
909 /* Key schedule now contains shared secret key material */
910 key->keyed = 1;
911
912 err_agree:
913 err_partner_len:
914 memset ( tmp, 0, sizeof ( *tmp ) );
915 zfree ( tmp );
916 err_alloc:
917 return rc;
918}
struct eth_slow_lacp_entity_tlv partner
Partner information.
Definition eth_slow.h:5
#define DBGC_HDA(...)
Definition compiler.h:531
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
size_t pubsize
Public key size.
Definition crypto.h:216
#define EINVAL_KEY_EXCHANGE
Definition tls.c:111
static void tls_set_kdf_master(struct tls_connection *tls, const void *secret, size_t secret_len)
Set key derivation function master secret.
Definition tls.c:759

References DBGC, DBGC_HDA, EINVAL_KEY_EXCHANGE, ENOMEM, exchange_agree(), key, tls_connection::key, memcpy(), memset(), exchange_algorithm::name, partner, exchange_algorithm::privsize, exchange_algorithm::pubsize, rc, exchange_algorithm::sharedsize, strerror(), tls_clear_binding(), tls_ephemeral_label(), tls_set_kdf_master(), tmp, zalloc(), and zfree().

Referenced by tls_new_server_key_exchange_dhe(), tls_new_server_key_exchange_ecdhe(), and tls_send_client_key_exchange_pubkey().

◆ tls_generate_master_secret()

void tls_generate_master_secret ( struct tls_connection * tls)
static

Generate master secret.

Parameters
tlsTLS connection

The client and server random values must already be known.

Definition at line 927 of file tls.c.

927 {
928 struct tls_key_schedule *key = &tls->key;
929 struct digest_algorithm *digest = key->digest;
930 uint8_t digest_out[ digest->digestsize ];
931 uint8_t master_secret[48];
932
933 /* Sanity checks */
934 assert ( key->keyed );
935 assert ( key->bound );
936
937 /* Generate handshake digest */
938 tls_verify_handshake ( tls, digest_out );
939
940 /* Show inputs */
941 DBGC ( tls, "TLS %p client random bytes:\n", tls );
942 DBGC_HD ( tls, &tls->client.random, sizeof ( tls->client.random ) );
943 DBGC ( tls, "TLS %p server random bytes:\n", tls );
944 DBGC_HD ( tls, &tls->server.random, sizeof ( tls->server.random ) );
945 DBGC ( tls, "TLS %p session hash:\n", tls );
946 DBGC_HD ( tls, digest_out, sizeof ( digest_out ) );
947
948 /* Generate master secret */
949 if ( tls->extended_master_secret ) {
950 tls_prf_label ( tls, master_secret, sizeof ( master_secret ),
951 "extended master secret",
952 digest_out, sizeof ( digest_out ) );
953 } else {
954 tls_prf_label ( tls, master_secret, sizeof ( master_secret ),
955 "master secret",
956 &tls->client.random,
957 sizeof ( tls->client.random ),
958 &tls->server.random,
959 sizeof ( tls->server.random ) );
960 }
961
962 /* Show output */
963 DBGC ( tls, "TLS %p generated %smaster secret:\n", tls,
964 ( tls->extended_master_secret ? "extended ": "" ) );
965 DBGC_HD ( tls, master_secret, sizeof ( master_secret ) );
966
967 /* Set key derivation function secret to the master secret */
968 tls_set_kdf_master ( tls, master_secret, sizeof ( master_secret ) );
969}
#define DBGC_HD(...)
Definition compiler.h:532
int extended_master_secret
Extended master secret flag.
Definition tls.h:554
uint8_t random[32]
Random bytes.
Definition tls.h:513
#define tls_prf_label(tls, out, out_len, label,...)
Generate secure pseudo-random data.
Definition tls.c:748
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition tls.c:1174

References assert, tls_connection::client, DBGC, DBGC_HD, digest_algorithm::digestsize, tls_connection::extended_master_secret, key, tls_connection::key, tls_client::random, tls_server::random, tls_connection::server, tls_prf_label, tls_set_kdf_master(), and tls_verify_handshake().

Referenced by tls_send_client_key_exchange().

◆ tls_generate_keys()

int tls_generate_keys ( struct tls_connection * tls)
static

Generate key material.

Parameters
tlsTLS connection

The master secret must already be known.

Definition at line 978 of file tls.c.

978 {
979 struct tls_cipherspec *tx_cipherspec = &tls->tx.cipherspec.pending;
980 struct tls_cipherspec *rx_cipherspec = &tls->rx.cipherspec.pending;
981 size_t hash_size = tx_cipherspec->suite->mac_len;
982 size_t key_size = tx_cipherspec->suite->key_len;
983 size_t iv_size = tx_cipherspec->suite->fixed_iv_len;
984 size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
985 uint8_t key_block[total];
986 uint8_t *key;
987 int rc;
988
989 /* Sanity checks */
990 assert ( tls->key.keyed );
991 assert ( tls->key.bound );
992
993 /* Generate key block */
994 tls_prf_label ( tls, key_block, sizeof ( key_block ), "key expansion",
995 &tls->server.random, sizeof ( tls->server.random ),
996 &tls->client.random, sizeof ( tls->client.random ) );
997
998 /* Split key block into portions */
999 key = key_block;
1000
1001 /* TX MAC secret */
1002 memcpy ( tx_cipherspec->mac_secret, key, hash_size );
1003 DBGC ( tls, "TLS %p TX MAC secret:\n", tls );
1004 DBGC_HD ( tls, key, hash_size );
1005 key += hash_size;
1006
1007 /* RX MAC secret */
1008 memcpy ( rx_cipherspec->mac_secret, key, hash_size );
1009 DBGC ( tls, "TLS %p RX MAC secret:\n", tls );
1010 DBGC_HD ( tls, key, hash_size );
1011 key += hash_size;
1012
1013 /* TX key */
1014 if ( ( rc = cipher_setkey ( tx_cipherspec->suite->cipher,
1015 tx_cipherspec->cipher_ctx,
1016 key, key_size ) ) != 0 ) {
1017 DBGC ( tls, "TLS %p could not set TX key: %s\n",
1018 tls, strerror ( rc ) );
1019 return rc;
1020 }
1021 DBGC ( tls, "TLS %p TX key:\n", tls );
1022 DBGC_HD ( tls, key, key_size );
1023 key += key_size;
1024
1025 /* RX key */
1026 if ( ( rc = cipher_setkey ( rx_cipherspec->suite->cipher,
1027 rx_cipherspec->cipher_ctx,
1028 key, key_size ) ) != 0 ) {
1029 DBGC ( tls, "TLS %p could not set TX key: %s\n",
1030 tls, strerror ( rc ) );
1031 return rc;
1032 }
1033 DBGC ( tls, "TLS %p RX key:\n", tls );
1034 DBGC_HD ( tls, key, key_size );
1035 key += key_size;
1036
1037 /* TX initialisation vector */
1038 memcpy ( tx_cipherspec->fixed_iv, key, iv_size );
1039 DBGC ( tls, "TLS %p TX IV:\n", tls );
1040 DBGC_HD ( tls, key, iv_size );
1041 key += iv_size;
1042
1043 /* RX initialisation vector */
1044 memcpy ( rx_cipherspec->fixed_iv, key, iv_size );
1045 DBGC ( tls, "TLS %p RX IV:\n", tls );
1046 DBGC_HD ( tls, key, iv_size );
1047 key += iv_size;
1048
1049 assert ( ( key_block + total ) == key );
1050
1051 return 0;
1052}
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition crypto.h:310
uint8_t key_len
Key length.
Definition tls.h:233
void * mac_secret
MAC secret.
Definition tls.h:287
struct x509_certificate * bound
Server identity to which the schedule has been bound (if any).
Definition tls.h:455
int keyed
Schedule holds secret key material.
Definition tls.h:393

References assert, tls_key_schedule::bound, tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_setkey(), tls_rx::cipherspec, tls_tx::cipherspec, tls_connection::client, DBGC, DBGC_HD, tls_cipherspec::fixed_iv, tls_cipher_suite::fixed_iv_len, key, tls_connection::key, tls_cipher_suite::key_len, tls_key_schedule::keyed, tls_cipher_suite::mac_len, tls_cipherspec::mac_secret, memcpy(), tls_cipherspec_pair::pending, tls_client::random, tls_server::random, rc, tls_connection::rx, tls_connection::server, strerror(), tls_cipherspec::suite, tls_prf_label, and tls_connection::tx.

Referenced by tls_new_server_hello(), and tls_send_client_key_exchange().

◆ tls_generate_resumption_master()

void tls_generate_resumption_master ( struct tls_connection * tls)
static

Generate resumption master secret.

Parameters
tlsTLS connection

Definition at line 1059 of file tls.c.

1059 {
1060 struct tls_session *session = tls->session;
1061 struct tls_key_schedule *key = &tls->key;
1062 struct digest_algorithm *digest = key->digest;
1063 struct md5_sha1_hmac_keys *hkeys;
1064 union {
1065 uint8_t opaque[48];
1066 struct {
1067 uint8_t md5[24];
1068 uint8_t sha1[24];
1069 } __attribute__ (( packed ));
1070 } *secret;
1071
1072 /* Sanity checks */
1073 assert ( key->keyed );
1074 assert ( key->bound );
1075 assert ( x509_is_valid ( key->bound, tls->server.root ) );
1076 assert ( sizeof ( *secret ) <=
1077 sizeof ( session->resumption_master_secret ) );
1078 secret = ( ( void * ) session->resumption_master_secret );
1079
1080 if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
1081
1082 /* For TLSv1.2, the pre-master secret may be any
1083 * length but the master secret is fixed at 48 bytes.
1084 * This is smaller than the block size for all
1085 * supported digest algorithms. The HMAC key
1086 * constructed from the master secret will therefore
1087 * be just the zero-padded master secret value. We
1088 * can therefore preserve just these first 48 bytes of
1089 * the KDF master secret (ignoring the zero padding up
1090 * to the digest block size).
1091 */
1092 assert ( sizeof ( *secret ) <= hmac_keysize ( digest ) );
1093 memcpy ( secret, key->kdf, sizeof ( *secret ) );
1094 session->resumption_master_secret_len = sizeof ( *secret );
1095
1096 } else {
1097
1098 /* For TLSv1.1 and earlier, the master secret is again
1099 * fixed at 48 bytes, but will be split as 24 bytes in
1100 * each of the MD5 and SHA-1 HMAC keys.
1101 */
1102 assert ( key->digest == &md5_sha1_algorithm );
1103 assert ( sizeof ( secret->md5 ) <=
1105 assert ( sizeof ( secret->sha1 ) <=
1107 hkeys = key->kdf;
1108 memcpy ( secret->md5, hkeys->md5, sizeof ( secret->md5 ) );
1109 memcpy ( secret->sha1, hkeys->sha1, sizeof ( secret->sha1 ) );
1110 session->resumption_master_secret_len = sizeof ( *secret );
1111 }
1112}
uint8_t resumption_master_secret[48]
Resumption master secret.
Definition tls.h:356
size_t resumption_master_secret_len
Length of resumption master secret.
Definition tls.h:358
int x509_is_valid(struct x509_certificate *cert, struct x509_root *root)
Check if X.509 certificate is valid.
Definition x509.c:1313

References __attribute__, assert, hmac_keysize(), key, tls_connection::key, md5_sha1_hmac_keys::md5, md5_algorithm, md5_sha1_algorithm, memcpy(), tls_session::resumption_master_secret, tls_session::resumption_master_secret_len, tls_server::root, tls_connection::server, tls_connection::session, md5_sha1_hmac_keys::sha1, sha1_algorithm, tls_version(), TLS_VERSION_TLS_1_2, and x509_is_valid().

Referenced by tls_new_finished().

◆ tls_resume_secret()

void tls_resume_secret ( struct tls_connection * tls)
static

Resume from resumption master secret.

Parameters
tlsTLS connection

Definition at line 1119 of file tls.c.

1119 {
1120 struct tls_session *session = tls->session;
1121 struct tls_key_schedule *key = &tls->key;
1122 size_t len = session->resumption_master_secret_len;
1123
1124 /* For TLSv1.2 and earlier, the resumption master secret is
1125 * just the original master secret value.
1126 */
1128
1129 /* If the resumption master secret was non-empty, then the key
1130 * schedule now contains a shared secret that is already bound
1131 * to the server's identity.
1132 *
1133 * If the resumption master secret was empty (which should not
1134 * be possible if this function is called), then the key
1135 * schedule no longer contains any shared secret.
1136 */
1137 assert ( len );
1138 key->keyed = len;
1139 tls_set_binding ( tls, session->cert );
1140}
static void tls_set_binding(struct tls_connection *tls, struct x509_certificate *cert)
Bind key schedule to a server identity.
Definition tls.c:519

References assert, tls_session::cert, key, tls_connection::key, len, tls_session::resumption_master_secret, tls_session::resumption_master_secret_len, tls_connection::session, tls_set_binding(), and tls_set_kdf_master().

Referenced by tls_new_server_hello().

◆ tls_add_handshake()

int tls_add_handshake ( struct tls_connection * tls,
const void * data,
size_t len )
static

Add handshake record to verification hash.

Parameters
tlsTLS connection
dataHandshake record
lenLength of handshake record
Return values
rcReturn status code

Definition at line 1157 of file tls.c.

1158 {
1159 struct tls_key_schedule *key = &tls->key;
1160 struct digest_algorithm *digest = key->digest;
1161
1162 digest_update ( digest, key->handshake, data, len );
1163 return 0;
1164}
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:299

References data, digest_update(), key, tls_connection::key, and len.

Referenced by tls_new_handshake(), tls_new_server_hello(), and tls_send_record().

◆ tls_find_cipher_suite()

struct tls_cipher_suite * tls_find_cipher_suite ( unsigned int cipher_suite)
static

Identify cipher suite.

Parameters
cipher_suiteCipher suite specification
Return values
suiteCipher suite, or NULL

Definition at line 1208 of file tls.c.

1208 {
1209 struct tls_cipher_suite *suite;
1210
1211 /* Identify cipher suite */
1213 if ( suite->code == cipher_suite )
1214 return suite;
1215 }
1216
1217 return NULL;
1218}
uint16_t code
Numeric code (in network-endian order).
Definition tls.h:231
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition tls.h:243

References tls_cipher_suite::code, for_each_table_entry, NULL, and TLS_CIPHER_SUITES.

Referenced by tls_select_cipher().

◆ tls_clear_cipher() [2/2]

void tls_clear_cipher ( struct tls_connection *tls __unused,
struct tls_cipherspec * cipherspec )
static

Clear cipher suite.

Parameters
cipherspecTLS cipher specification

Definition at line 1225 of file tls.c.

1226 {
1227
1228 zfree ( cipherspec->dynamic );
1229 memset ( cipherspec, 0, sizeof ( *cipherspec ) );
1230 cipherspec->suite = &tls_cipher_suite_null;
1231}
void * dynamic
Dynamically-allocated storage.
Definition tls.h:283
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition tls.c:1191

References __unused, tls_cipherspec::dynamic, memset(), tls_cipherspec::suite, tls_cipher_suite_null, and zfree().

◆ tls_set_cipher()

int tls_set_cipher ( struct tls_connection * tls,
struct tls_cipherspec * cipherspec,
struct tls_cipher_suite * suite )
static

Set cipher suite.

Parameters
tlsTLS connection
cipherspecTLS cipher specification
suiteCipher suite
Return values
rcReturn status code

Definition at line 1241 of file tls.c.

1243 {
1244 struct cipher_algorithm *cipher = suite->cipher;
1245 size_t total;
1246 void *dynamic;
1247
1248 /* Clear out old cipher contents, if any */
1249 tls_clear_cipher ( tls, cipherspec );
1250
1251 /* Allocate dynamic storage */
1252 total = ( cipher->ctxsize + suite->mac_len + suite->fixed_iv_len );
1253 dynamic = zalloc ( total );
1254 if ( ! dynamic ) {
1255 DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto "
1256 "context\n", tls, total );
1257 return -ENOMEM_CONTEXT;
1258 }
1259
1260 /* Assign storage */
1261 cipherspec->dynamic = dynamic;
1262 cipherspec->cipher_ctx = dynamic; dynamic += cipher->ctxsize;
1263 cipherspec->mac_secret = dynamic; dynamic += suite->mac_len;
1264 cipherspec->fixed_iv = dynamic; dynamic += suite->fixed_iv_len;
1265 assert ( ( cipherspec->dynamic + total ) == dynamic );
1266
1267 /* Store parameters */
1268 cipherspec->suite = suite;
1269
1270 return 0;
1271}
size_t ctxsize
Context size.
Definition crypto.h:62
#define ENOMEM_CONTEXT
Definition tls.c:123

References assert, tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_algorithm::ctxsize, DBGC, tls_cipherspec::dynamic, ENOMEM_CONTEXT, tls_cipherspec::fixed_iv, tls_cipher_suite::fixed_iv_len, tls_cipher_suite::mac_len, tls_cipherspec::mac_secret, tls_cipherspec::suite, tls_clear_cipher(), and zalloc().

Referenced by tls_select_cipher().

◆ tls_select_cipher()

int tls_select_cipher ( struct tls_connection * tls,
unsigned int cipher_suite )
static

Select next cipher suite.

Parameters
tlsTLS connection
cipher_suiteCipher suite specification
Return values
rcReturn status code

Definition at line 1280 of file tls.c.

1281 {
1282 struct tls_cipher_suite *suite;
1283 struct digest_algorithm *digest;
1284 int rc;
1285
1286 /* Identify cipher suite */
1287 suite = tls_find_cipher_suite ( cipher_suite );
1288 if ( ! suite ) {
1289 DBGC ( tls, "TLS %p does not support cipher %04x\n",
1290 tls, ntohs ( cipher_suite ) );
1291 return -ENOTSUP_CIPHER;
1292 }
1293
1294 /* Set key schedule digest algorithm */
1295 digest = ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ?
1296 suite->handshake : &md5_sha1_algorithm );
1297 if ( ( rc = tls_set_digest ( tls, digest ) ) != 0 )
1298 return rc;
1299
1300 /* Set ciphers */
1301 if ( ( rc = tls_set_cipher ( tls, &tls->tx.cipherspec.pending,
1302 suite ) ) != 0 )
1303 return rc;
1304 if ( ( rc = tls_set_cipher ( tls, &tls->rx.cipherspec.pending,
1305 suite ) ) != 0 )
1306 return rc;
1307
1308 DBGC ( tls, "TLS %p selected %s-%s-%s-%d-%s\n", tls,
1309 suite->exchange->name, suite->pubkey->name,
1310 suite->cipher->name, ( suite->key_len * 8 ),
1311 suite->digest->name );
1312
1313 return 0;
1314}
#define ntohs(value)
Definition byteswap.h:137
const char * name
Algorithm name.
Definition crypto.h:60
const char * name
Algorithm name.
Definition crypto.h:144
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition tls.h:223
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition tls.h:221
struct digest_algorithm * handshake
Handshake digest algorithm (for TLSv1.2 and above).
Definition tls.h:229
const char * name
Algorithm name.
Definition tls.h:198
#define ENOTSUP_CIPHER
Definition tls.c:151
static int tls_set_digest(struct tls_connection *tls, struct digest_algorithm *digest)
Set key schedule digest algorithm.
Definition tls.c:567
static int tls_set_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
Set cipher suite.
Definition tls.c:1241
static struct tls_cipher_suite * tls_find_cipher_suite(unsigned int cipher_suite)
Identify cipher suite.
Definition tls.c:1208

References tls_cipher_suite::cipher, tls_rx::cipherspec, tls_tx::cipherspec, DBGC, tls_cipher_suite::digest, ENOTSUP_CIPHER, tls_cipher_suite::exchange, tls_cipher_suite::handshake, tls_cipher_suite::key_len, md5_sha1_algorithm, cipher_algorithm::name, digest_algorithm::name, pubkey_algorithm::name, tls_key_exchange_algorithm::name, ntohs, tls_cipherspec_pair::pending, tls_cipher_suite::pubkey, rc, tls_connection::rx, tls_find_cipher_suite(), tls_set_cipher(), tls_set_digest(), tls_version(), TLS_VERSION_TLS_1_2, and tls_connection::tx.

Referenced by tls_new_server_hello().

◆ tls_change_cipher()

int tls_change_cipher ( struct tls_connection * tls,
struct tls_cipherspec_pair * pair )
static

Activate next cipher suite.

Parameters
tlsTLS connection
pairCipher specification pair
Return values
rcReturn status code

Definition at line 1323 of file tls.c.

1324 {
1325
1326 /* Sanity check */
1327 if ( pair->pending.suite == &tls_cipher_suite_null ) {
1328 DBGC ( tls, "TLS %p refusing to use null cipher\n", tls );
1329 return -ENOTSUP_NULL;
1330 }
1331
1332 tls_clear_cipher ( tls, &pair->active );
1333 memswap ( &pair->active, &pair->pending, sizeof ( pair->active ) );
1334 return 0;
1335}
void * memswap(void *first, void *second, size_t len)
Swap memory regions.
Definition string.c:154
#define ENOTSUP_NULL
Definition tls.c:155

References tls_cipherspec_pair::active, DBGC, ENOTSUP_NULL, memswap(), tls_cipherspec_pair::pending, tls_cipherspec::suite, tls_cipher_suite_null, and tls_clear_cipher().

Referenced by tls_new_change_cipher(), and tls_tx_step().

◆ tls_signature_hash_algorithm()

struct tls_signature_hash_algorithm * tls_signature_hash_algorithm ( struct pubkey_algorithm * pubkey,
struct digest_algorithm * digest )
static

Find TLS signature and hash algorithm.

Parameters
pubkeyPublic-key algorithm
digestDigest algorithm
Return values
sig_hashSignature and hash algorithm, or NULL

Definition at line 1356 of file tls.c.

1357 {
1358 struct tls_signature_hash_algorithm *sig_hash;
1359
1360 /* Identify signature and hash algorithm */
1362 if ( ( sig_hash->pubkey == pubkey ) &&
1363 ( sig_hash->digest == digest ) ) {
1364 return sig_hash;
1365 }
1366 }
1367
1368 return NULL;
1369}
A TLS signature algorithm.
Definition tls.h:301
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition tls.h:305
struct digest_algorithm * digest
Digest algorithm.
Definition tls.h:303
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition tls.h:317

References tls_signature_hash_algorithm::digest, for_each_table_entry, NULL, tls_signature_hash_algorithm::pubkey, and TLS_SIG_HASH_ALGORITHMS.

Referenced by tls_send_certificate_verify().

◆ tls_find_signature_hash()

struct tls_signature_hash_algorithm * tls_find_signature_hash ( unsigned int code)
static

Find TLS signature and hash algorithm.

Parameters
codeSignature and hash algorithm identifier
Return values
sig_hashSignature and hash algorithm, or NULL

Definition at line 1378 of file tls.c.

1378 {
1379 struct tls_signature_hash_algorithm *sig_hash;
1380
1381 /* Identify signature and hash algorithm */
1383 if ( sig_hash->code == code )
1384 return sig_hash;
1385 }
1386
1387 return NULL;
1388}
static unsigned int code
Definition hyperv.h:26
uint16_t code
Numeric code (in network-endian order).
Definition tls.h:309

References code, tls_signature_hash_algorithm::code, for_each_table_entry, NULL, and TLS_SIG_HASH_ALGORITHMS.

Referenced by tls_verify_dh_params().

◆ tls_find_named_group()

struct tls_named_group * tls_find_named_group ( unsigned int named_group)
static

Identify named key exchange group.

Parameters
named_groupNamed group specification
Return values
groupNamed group, or NULL

Definition at line 1404 of file tls.c.

1404 {
1405 struct tls_named_group *group;
1406
1407 /* Identify named group */
1409 if ( group->code && ( group->code == named_group ) )
1410 return group;
1411 }
1412
1413 return NULL;
1414}
uint16_t group
Type of event.
Definition ena.h:1
A TLS named group.
Definition tls.h:254
#define TLS_NAMED_GROUPS
TLS named group table.
Definition tls.h:262

References for_each_table_entry, group, NULL, and TLS_NAMED_GROUPS.

Referenced by tls_new_server_key_exchange_ecdhe().

◆ tls_find_param_group()

struct tls_named_group * tls_find_param_group ( const void * dh_p,
size_t dh_p_len,
const void * dh_g,
size_t dh_g_len )
static

Identify named key exchange group by Diffie-Hellman parameters.

Parameters
dh_pPrime modulus
dh_p_lenLength of prime modulus
dh_gGenerator
dh_g_lenLength of generator
Return values
groupNamed group, or NULL

Definition at line 1426 of file tls.c.

1427 {
1428 struct tls_named_group *group;
1429
1430 /* Identify named group by parameters */
1432 if ( is_ffdhe ( group->exchange ) &&
1433 ffdhe_has_params ( group->exchange, dh_p, dh_p_len,
1434 dh_g, dh_g_len ) ) {
1435 return group;
1436 }
1437 }
1438
1439 return NULL;
1440}
int ffdhe_has_params(struct exchange_algorithm *exchange, const void *dh_p, size_t dh_p_len, const void *dh_g, size_t dh_g_len)
Check group parameters.
Definition ffdhe.c:310
static int is_ffdhe(struct exchange_algorithm *exchange)
Check if key exchange algorithm is a finite field DHE group.
Definition ffdhe.h:52

References ffdhe_has_params(), for_each_table_entry, group, is_ffdhe(), NULL, and TLS_NAMED_GROUPS.

Referenced by tls_new_server_key_exchange_dhe().

◆ tls_verify_dh_params()

int tls_verify_dh_params ( struct tls_connection * tls,
const void * data,
size_t len,
size_t param_len )
static

Verify Diffie-Hellman parameter signature.

Parameters
tlsTLS connection
dataServer Key Exchange handshake record
lenLength of Server Key Exchange handshake record
param_lenLength of Diffie-Hellman parameters
Return values
rcReturn status code

Definition at line 1451 of file tls.c.

1452 {
1453 struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1454 struct tls_signature_hash_algorithm *sig_hash;
1455 struct x509_certificate *cert;
1456 struct pubkey_algorithm *pubkey;
1457 struct digest_algorithm *digest;
1458 int use_sig_hash = tls_version ( tls, TLS_VERSION_TLS_1_2 );
1459 const struct {
1460 uint16_t sig_hash[use_sig_hash];
1461 uint16_t signature_len;
1462 uint8_t signature[0];
1463 } __attribute__ (( packed )) *sig;
1464 struct asn1_cursor signature;
1465 size_t remaining;
1466 int rc;
1467
1468 /* Identify server certificate */
1469 cert = x509_first ( tls->server.chain );
1470 if ( ! cert ) {
1471 DBGC ( tls, "TLS %p has no server certificate\n", tls );
1472 return -ENOENT_CERT;
1473 }
1474
1475 /* Signature follows parameters */
1476 assert ( param_len <= len );
1477 sig = ( data + param_len );
1478 remaining = ( len - param_len );
1479
1480 /* Parse signature from ServerKeyExchange */
1481 if ( ( sizeof ( *sig ) > remaining ) ||
1482 ( ntohs ( sig->signature_len ) > ( remaining -
1483 sizeof ( *sig ) ) ) ) {
1484 DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1485 tls );
1486 DBGC_HDA ( tls, 0, data, len );
1487 return -EINVAL_KEY_EXCHANGE;
1488 }
1489 signature.data = sig->signature;
1490 signature.len = ntohs ( sig->signature_len );
1491
1492 /* Identify signature and hash algorithm */
1493 if ( use_sig_hash ) {
1494 sig_hash = tls_find_signature_hash ( sig->sig_hash[0] );
1495 if ( ! sig_hash ) {
1496 DBGC ( tls, "TLS %p unsupported signature hash "
1497 "%#04x\n", tls, sig->sig_hash[0] );
1498 return -ENOTSUP_SIG_HASH;
1499 }
1500 pubkey = sig_hash->pubkey;
1501 digest = sig_hash->digest;
1502 DBGC ( tls, "TLS %p using signature hash %s-%s\n",
1503 tls, pubkey->name, digest->name );
1504 if ( sig_hash->algorithm !=
1505 cert->subject.public_key.algorithm ) {
1506 DBGC ( tls, "TLS %p cannot use %s public key\n", tls,
1508 return -EPERM_KEY_EXCHANGE;
1509 }
1510 } else {
1511 pubkey = cipherspec->suite->pubkey;
1512 digest = &md5_sha1_algorithm;
1513 }
1514
1515 /* Verify signature */
1516 {
1517 uint8_t ctx[digest->ctxsize];
1518 uint8_t hash[digest->digestsize];
1519
1520 /* Calculate digest */
1521 digest_init ( digest, ctx );
1522 digest_update ( digest, ctx, &tls->client.random,
1523 sizeof ( tls->client.random ) );
1524 digest_update ( digest, ctx, tls->server.random,
1525 sizeof ( tls->server.random ) );
1526 digest_update ( digest, ctx, data, param_len );
1527 digest_final ( digest, ctx, hash );
1528
1529 /* Verify signature */
1530 if ( ( rc = pubkey_verify ( pubkey,
1531 &cert->subject.public_key.raw,
1532 digest, hash,
1533 &signature ) ) != 0 ) {
1534 DBGC ( tls, "TLS %p ServerKeyExchange failed "
1535 "verification\n", tls );
1536 DBGC_HDA ( tls, 0, data, len );
1537 return -EPERM_KEY_EXCHANGE;
1538 }
1539 }
1540
1541 /* The verified signature indicates the server's intention to
1542 * delegate authority to the shared secret key material. The
1543 * shared secret is therefore bound to the server's identity.
1544 */
1545 tls_set_binding ( tls, cert );
1546
1547 return 0;
1548}
u8 sig
Definition CIB_PRM.h:15
u8 signature
CPU signature.
Definition CIB_PRM.h:7
pseudo_bit_t hash[0x00010]
Definition arbel.h:2
unsigned short uint16_t
Definition stdint.h:11
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
const char * name
Name.
Definition asn1.h:416
An ASN.1 object cursor.
Definition asn1.h:21
A public key algorithm.
Definition crypto.h:142
struct asn1_algorithm * algorithm
Required certificate OID-identified algorithm.
Definition tls.h:307
An X.509 certificate.
Definition x509.h:216
struct x509_subject subject
Subject.
Definition x509.h:245
struct asn1_algorithm * algorithm
Public key algorithm.
Definition x509.h:54
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
#define EPERM_KEY_EXCHANGE
Definition tls.c:187
#define ENOTSUP_SIG_HASH
Definition tls.c:159
#define ENOENT_CERT
Definition tls.c:119
static struct tls_signature_hash_algorithm * tls_find_signature_hash(unsigned int code)
Find TLS signature and hash algorithm.
Definition tls.c:1378
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition x509.h:311

References __attribute__, tls_signature_hash_algorithm::algorithm, x509_public_key::algorithm, assert, tls_server::chain, tls_tx::cipherspec, tls_connection::client, ctx, digest_algorithm::ctxsize, data, DBGC, DBGC_HDA, tls_signature_hash_algorithm::digest, digest_final(), digest_init(), digest_update(), digest_algorithm::digestsize, EINVAL_KEY_EXCHANGE, ENOENT_CERT, ENOTSUP_SIG_HASH, EPERM_KEY_EXCHANGE, hash, len, md5_sha1_algorithm, asn1_algorithm::name, digest_algorithm::name, pubkey_algorithm::name, ntohs, tls_cipherspec_pair::pending, tls_cipher_suite::pubkey, tls_signature_hash_algorithm::pubkey, pubkey_verify(), x509_subject::public_key, tls_client::random, tls_server::random, x509_public_key::raw, rc, tls_connection::server, sig, signature, x509_certificate::subject, tls_cipherspec::suite, tls_find_signature_hash(), tls_set_binding(), tls_version(), TLS_VERSION_TLS_1_2, tls_connection::tx, and x509_first().

Referenced by tls_new_server_key_exchange_dhe(), and tls_new_server_key_exchange_ecdhe().

◆ tls_new_server_key_exchange_pubkey()

int tls_new_server_key_exchange_pubkey ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive new Server Key Exchange record using public key transport.

Parameters
tlsTLS connection
dataServer Key Exchange handshake record
lenLength of Server Key Exchange handshake record
Return values
rcReturn status code

Definition at line 1558 of file tls.c.

1559 {
1560
1561 /* Should never be received */
1562 DBGC ( tls, "TLS %p received unexpected ServerKeyExchange:\n", tls );
1563 DBGC_HDA ( tls, 0, data, len );
1564 return -EPROTO;
1565}
#define EPROTO
Protocol error.
Definition errno.h:668

References data, DBGC, DBGC_HDA, EPROTO, and len.

◆ tls_send_client_key_exchange_pubkey()

int tls_send_client_key_exchange_pubkey ( struct tls_connection * tls)
static

Transmit Client Key Exchange record using public key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1573 of file tls.c.

1573 {
1574 struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1575 struct tls_key_schedule *key = &tls->key;
1576 struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1577 struct x509_certificate *cert;
1578 struct asn1_cursor cursor;
1579 struct asn1_builder builder = { NULL, 0 };
1580 int rc;
1581
1582 /* Select classic key transport algorithm */
1584 assert ( is_key_transport ( tls->key.exchange ) );
1585
1586 /* Generate pre-master secret */
1587 if ( ( rc = tls_agree_ephemeral ( tls, NULL, 0, 0 ) ) != 0 )
1588 goto err_agree;
1589
1590 /* Pre-master secret will be the current KDF secret */
1591 cursor.data = key->kdf;
1592 cursor.len = tls->key.exchange->sharedsize;
1593 assert ( cursor.len <= key->kdfsize );
1594
1595 /* Identify server certificate */
1596 cert = x509_first ( tls->server.chain );
1597 if ( ! cert ) {
1598 DBGC ( tls, "TLS %p has no server certificate\n", tls );
1599 rc = -ENOENT_CERT;
1600 goto err_cert;
1601 }
1602
1603 /* Encrypt pre-master secret using server's public key */
1604 if ( ( rc = pubkey_encrypt ( pubkey, &cert->subject.public_key.raw,
1605 &cursor, &builder ) ) != 0 ) {
1606 DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
1607 tls, strerror ( rc ) );
1608 goto err_encrypt;
1609 }
1610
1611 /* Construct Client Key Exchange record */
1612 {
1613 struct {
1614 uint32_t type_length;
1615 uint16_t encrypted_pre_master_secret_len;
1616 } __attribute__ (( packed )) header;
1617
1618 header.type_length =
1620 htonl ( builder.len + sizeof ( header ) -
1621 sizeof ( header.type_length ) ) );
1622 header.encrypted_pre_master_secret_len = htons ( builder.len );
1623
1624 if ( ( rc = asn1_prepend_raw ( &builder, &header,
1625 sizeof ( header ) ) ) != 0 ) {
1626 DBGC ( tls, "TLS %p could not construct Client Key "
1627 "Exchange: %s\n", tls, strerror ( rc ) );
1628 goto err_prepend;
1629 }
1630 }
1631
1632 /* Transmit Client Key Exchange record */
1633 if ( ( rc = tls_send_handshake ( tls, builder.data,
1634 builder.len ) ) != 0 ) {
1635 goto err_send;
1636 }
1637
1638 /* Shared secret has now been incorporated into the handshake
1639 * digest. It can be decrypted only with access to the
1640 * certificate's private key, and has thereby been bound to
1641 * the server's identity.
1642 */
1643 tls_set_binding ( tls, cert );
1644
1645 err_send:
1646 err_prepend:
1647 err_encrypt:
1648 zfree ( builder.data );
1649 err_cert:
1650 err_agree:
1651 return rc;
1652}
unsigned int uint32_t
Definition stdint.h:12
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition asn1.c:1019
struct ena_llq_option header
Header locations.
Definition ena.h:5
#define htonl(value)
Definition byteswap.h:134
#define cpu_to_le32(value)
Definition byteswap.h:108
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
static int is_key_transport(struct exchange_algorithm *exchange)
Definition crypto.h:409
An ASN.1 object builder.
Definition asn1.h:29
void * data
Data.
Definition asn1.h:36
size_t len
Length of data.
Definition asn1.h:38
struct exchange_algorithm * exchange
Key exchange algorithm.
Definition tls.h:380
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition tls.c:1949
static int tls_agree_ephemeral(struct tls_connection *tls, const void *partner, size_t partner_len, int strip)
Agree ephemeral shared secret (i.e.
Definition tls.c:838
#define TLS_CLIENT_KEY_EXCHANGE
Definition tls.h:76
struct exchange_algorithm tls_classic_pre_master_algorithm
Classic pre-master secret key exchange algorithm.
Definition tlsclassic.c:101

References __attribute__, asn1_prepend_raw(), assert, tls_server::chain, tls_tx::cipherspec, cpu_to_le32, asn1_builder::data, asn1_cursor::data, DBGC, ENOENT_CERT, tls_key_schedule::exchange, header, htonl, htons, is_key_transport(), key, tls_connection::key, asn1_builder::len, asn1_cursor::len, NULL, tls_cipherspec_pair::pending, tls_cipher_suite::pubkey, pubkey_encrypt(), x509_subject::public_key, x509_public_key::raw, rc, tls_connection::server, exchange_algorithm::sharedsize, strerror(), x509_certificate::subject, tls_cipherspec::suite, tls_agree_ephemeral(), tls_classic_pre_master_algorithm, TLS_CLIENT_KEY_EXCHANGE, tls_send_handshake(), tls_set_binding(), tls_connection::tx, x509_first(), and zfree().

◆ tls_new_server_key_exchange_dhe()

int tls_new_server_key_exchange_dhe ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive new Server Key Exchange record using DHE key exchange.

Parameters
tlsTLS connection
dataServer Key Exchange handshake record
lenLength of Server Key Exchange handshake record
Return values
rcReturn status code

Definition at line 1669 of file tls.c.

1670 {
1671 struct tls_named_group *group;
1672 const struct {
1673 uint16_t len;
1674 uint8_t data[0];
1675 } __attribute__ (( packed )) *dh_val[3];
1676 typeof ( dh_val[0] ) dh_p;
1677 typeof ( dh_val[1] ) dh_g;
1678 typeof ( dh_val[2] ) dh_ys;
1679 const void *param;
1680 size_t remaining;
1681 size_t frag_len;
1682 size_t param_len;
1683 unsigned int i;
1684 int rc;
1685
1686 /* Parse ServerKeyExchange */
1687 param = data;
1688 remaining = len;
1689 for ( i = 0 ; i < ( sizeof ( dh_val ) / sizeof ( dh_val[0] ) ) ; i++ ){
1690 dh_val[i] = param;
1691 if ( ( sizeof ( *dh_val[i] ) > remaining ) ||
1692 ( ntohs ( dh_val[i]->len ) > ( remaining -
1693 sizeof ( *dh_val[i] ) ) )){
1694 DBGC ( tls, "TLS %p received underlength "
1695 "ServerKeyExchange\n", tls );
1696 DBGC_HDA ( tls, 0, data, len );
1697 return -EINVAL_KEY_EXCHANGE;
1698 }
1699 frag_len = ( sizeof ( *dh_val[i] ) + ntohs ( dh_val[i]->len ));
1700 param += frag_len;
1701 remaining -= frag_len;
1702 }
1703 param_len = ( len - remaining );
1704
1705 /* Identify named group */
1706 dh_p = dh_val[0];
1707 dh_g = dh_val[1];
1708 dh_ys = dh_val[2];
1709 group = tls_find_param_group ( dh_p->data, ntohs ( dh_p->len ),
1710 dh_g->data, ntohs ( dh_g->len ) );
1711 if ( ! group ) {
1712 DBGC ( tls, "TLS %p unsupported %d-bit group:\n",
1713 tls, ( 8 * ntohs ( dh_p->len ) ) );
1714 DBGC_HDA ( tls, 0, data, len );
1715 return -ENOTSUP_GROUP;
1716 }
1717 tls->key.exchange = group->exchange;
1718 DBGC ( tls, "TLS %p using named group %s\n",
1719 tls, tls->key.exchange->name );
1720
1721 /* Generate pre-master secret */
1722 if ( ( rc = tls_agree_ephemeral ( tls, dh_ys->data,
1723 ntohs ( dh_ys->len ), 1 ) ) != 0 ) {
1724 return rc;
1725 }
1726
1727 /* Verify parameter signature */
1728 if ( ( rc = tls_verify_dh_params ( tls, data, len, param_len ) ) != 0 )
1729 return rc;
1730
1731 return 0;
1732}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
struct hv_monitor_parameter param[4][32]
Parameters.
Definition hyperv.h:13
static int tls_verify_dh_params(struct tls_connection *tls, const void *data, size_t len, size_t param_len)
Verify Diffie-Hellman parameter signature.
Definition tls.c:1451
#define ENOTSUP_GROUP
Definition tls.c:167
static struct tls_named_group * tls_find_param_group(const void *dh_p, size_t dh_p_len, const void *dh_g, size_t dh_g_len)
Identify named key exchange group by Diffie-Hellman parameters.
Definition tls.c:1426

References __attribute__, data, DBGC, DBGC_HDA, EINVAL_KEY_EXCHANGE, ENOTSUP_GROUP, tls_key_schedule::exchange, group, tls_connection::key, len, exchange_algorithm::name, ntohs, param, rc, tls_agree_ephemeral(), tls_find_param_group(), tls_verify_dh_params(), and typeof().

◆ tls_send_client_key_exchange_dhe()

int tls_send_client_key_exchange_dhe ( struct tls_connection * tls)
static

Transmit Client Key Exchange record using DHE key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1740 of file tls.c.

1740 {
1741 struct tls_key_schedule *key = &tls->key;
1742 struct exchange_algorithm *exchange = key->exchange;
1743 size_t pubsize = exchange->pubsize;
1744 struct {
1745 uint32_t type_length;
1746 uint16_t dh_xs_len;
1747 uint8_t dh_xs[pubsize];
1748 } __attribute__ (( packed )) *key_xchg;
1749 int rc;
1750
1751 /* Allocate space */
1752 key_xchg = malloc ( sizeof ( *key_xchg ) );
1753 if ( ! key_xchg ) {
1754 rc = -ENOMEM;
1755 goto err_alloc;
1756 }
1757
1758 /* Generate Client Key Exchange record */
1759 key_xchg->type_length =
1761 htonl ( sizeof ( *key_xchg ) -
1762 sizeof ( key_xchg->type_length ) ) );
1763 key_xchg->dh_xs_len = htons ( sizeof ( key_xchg->dh_xs ) );
1764 if ( ( rc = tls_share_ephemeral ( tls, key_xchg->dh_xs ) ) != 0 )
1765 goto err_share;
1766
1767 /* Transmit Client Key Exchange record */
1768 if ( ( rc = tls_send_handshake ( tls, key_xchg,
1769 sizeof ( *key_xchg ) ) ) !=0 ) {
1770 goto err_send_handshake;
1771 }
1772
1773 err_send_handshake:
1774 err_share:
1775 zfree ( key_xchg );
1776 err_alloc:
1777 return rc;
1778}
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:677
static int tls_share_ephemeral(struct tls_connection *tls, void *public)
Share ephemeral public key.
Definition tls.c:805

References __attribute__, cpu_to_le32, ENOMEM, htonl, htons, key, tls_connection::key, malloc(), exchange_algorithm::pubsize, rc, TLS_CLIENT_KEY_EXCHANGE, tls_send_handshake(), tls_share_ephemeral(), and zfree().

◆ tls_new_server_key_exchange_ecdhe()

int tls_new_server_key_exchange_ecdhe ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive new Server Key Exchange record using ECDHE key exchange.

Parameters
tlsTLS connection
dataServer Key Exchange handshake record
lenLength of Server Key Exchange handshake record
Return values
rcReturn status code

Definition at line 1795 of file tls.c.

1796 {
1797 struct tls_named_group *group;
1798 const struct {
1799 uint8_t curve_type;
1800 uint16_t named_group;
1801 uint8_t public_len;
1802 uint8_t public[0];
1803 } __attribute__ (( packed )) *ecdh = data;
1804 size_t param_len;
1805 int rc;
1806
1807 /* Parse ServerKeyExchange record */
1808 if ( ( sizeof ( *ecdh ) > len ) ||
1809 ( ecdh->public_len > ( len - sizeof ( *ecdh ) ) ) ) {
1810 DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1811 tls );
1812 DBGC_HDA ( tls, 0, data, len );
1813 return -EINVAL_KEY_EXCHANGE;
1814 }
1815 param_len = ( sizeof ( *ecdh ) + ecdh->public_len );
1816
1817 /* Identify named group */
1818 if ( ecdh->curve_type != TLS_NAMED_CURVE_TYPE ) {
1819 DBGC ( tls, "TLS %p unsupported curve type %d\n",
1820 tls, ecdh->curve_type );
1821 DBGC_HDA ( tls, 0, data, len );
1822 return -ENOTSUP_GROUP;
1823 }
1824 group = tls_find_named_group ( ecdh->named_group );
1825 if ( ! group ) {
1826 DBGC ( tls, "TLS %p unsupported named group %d\n",
1827 tls, ntohs ( ecdh->named_group ) );
1828 DBGC_HDA ( tls, 0, data, len );
1829 return -ENOTSUP_GROUP;
1830 }
1831 tls->key.exchange = group->exchange;
1832 DBGC ( tls, "TLS %p using named group %s\n",
1833 tls, tls->key.exchange->name );
1834
1835 /* Generate pre-master secret */
1836 if ( ( rc = tls_agree_ephemeral ( tls, ecdh->public,
1837 ecdh->public_len, 0 ) ) != 0 ) {
1838 return rc;
1839 }
1840
1841 /* Verify parameter signature */
1842 if ( ( rc = tls_verify_dh_params ( tls, data, len, param_len ) ) != 0 )
1843 return rc;
1844
1845 return 0;
1846}
static struct tls_named_group * tls_find_named_group(unsigned int named_group)
Identify named key exchange group.
Definition tls.c:1404
#define TLS_NAMED_CURVE_TYPE
TLS named curve type.
Definition tls.h:251

References __attribute__, data, DBGC, DBGC_HDA, EINVAL_KEY_EXCHANGE, ENOTSUP_GROUP, tls_key_schedule::exchange, group, tls_connection::key, len, exchange_algorithm::name, ntohs, rc, tls_agree_ephemeral(), tls_find_named_group(), TLS_NAMED_CURVE_TYPE, and tls_verify_dh_params().

◆ tls_send_client_key_exchange_ecdhe()

int tls_send_client_key_exchange_ecdhe ( struct tls_connection * tls)
static

Transmit Client Key Exchange record using ECDHE key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1854 of file tls.c.

1854 {
1855 struct tls_key_schedule *key = &tls->key;
1856 struct exchange_algorithm *exchange = key->exchange;
1857 size_t pubsize = exchange->pubsize;
1858 struct {
1859 uint32_t type_length;
1860 uint8_t public_len;
1861 uint8_t public[pubsize];
1862 } __attribute__ (( packed )) key_xchg;
1863 int rc;
1864
1865 /* Generate Client Key Exchange record */
1866 key_xchg.type_length =
1868 htonl ( sizeof ( key_xchg ) -
1869 sizeof ( key_xchg.type_length ) ) );
1870 key_xchg.public_len = sizeof ( key_xchg.public );
1871 if ( ( rc = tls_share_ephemeral ( tls, key_xchg.public ) ) != 0 )
1872 return rc;
1873
1874 /* Transmit Client Key Exchange record */
1875 if ( ( rc = tls_send_handshake ( tls, &key_xchg,
1876 sizeof ( key_xchg ) ) ) !=0 ) {
1877 return rc;
1878 }
1879
1880 return 0;
1881}

References __attribute__, cpu_to_le32, htonl, key, tls_connection::key, exchange_algorithm::pubsize, rc, TLS_CLIENT_KEY_EXCHANGE, tls_send_handshake(), and tls_share_ephemeral().

◆ tls_tx_resume()

void tls_tx_resume ( struct tls_connection * tls)
static

Resume TX state machine.

Parameters
tlsTLS connection

Definition at line 1902 of file tls.c.

1902 {
1903 process_add ( &tls->tx.process );
1904}
void process_add(struct process *process)
Add process to process list.
Definition process.c:60

References tls_tx::process, process_add(), and tls_connection::tx.

Referenced by tls_new_finished(), tls_restart(), tls_tx_resume_all(), tls_tx_step(), and tls_validator_done().

◆ tls_restart()

void tls_restart ( struct tls_connection * tls)
static

Restart negotiation.

Parameters
tlsTLS connection

Definition at line 1923 of file tls.c.

1923 {
1924
1925 /* Sanity check */
1926 assert ( ! tls->tx.pending );
1927 assert ( ! is_pending ( &tls->client.negotiation ) );
1928 assert ( ! is_pending ( &tls->server.negotiation ) );
1929 assert ( ! is_pending ( &tls->server.validation ) );
1930
1931 /* Reset ephemeral master secret */
1933
1934 /* (Re)start negotiation */
1936 tls_tx_resume ( tls );
1937 pending_get ( &tls->client.negotiation );
1938 pending_get ( &tls->server.negotiation );
1939}
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition pending.c:46
unsigned int pending
Pending transmissions.
Definition tls.h:475
@ TLS_TX_CLIENT_HELLO
Definition tls.h:187

References assert, tls_connection::client, is_pending(), tls_client::negotiation, tls_server::negotiation, tls_tx::pending, pending_get(), tls_connection::server, tls_regenerate_ephemeral_master(), TLS_TX_CLIENT_HELLO, tls_tx_resume(), tls_connection::tx, and tls_server::validation.

Referenced by add_tls(), and tls_new_hello_request().

◆ tls_client_hello()

int tls_client_hello ( struct tls_connection * tls,
int(* action )(struct tls_connection *tls, const void *data, size_t len) )
static

Digest or transmit Client Hello record.

Parameters
tlsTLS connection
actionAction to take on Client Hello record
Return values
rcReturn status code

Definition at line 1963 of file tls.c.

1966 {
1967 struct tls_session *session = tls->session;
1968 size_t name_len = strlen ( session->name );
1969 struct {
1970 uint16_t type;
1971 uint16_t len;
1972 struct {
1973 uint16_t len;
1974 struct {
1975 uint8_t type;
1976 uint16_t len;
1977 uint8_t name[name_len];
1978 } __attribute__ (( packed )) list[1];
1979 } __attribute__ (( packed )) data;
1980 } __attribute__ (( packed )) *server_name_ext;
1981 struct {
1982 uint16_t type;
1983 uint16_t len;
1984 struct {
1985 uint8_t max;
1986 } __attribute__ (( packed )) data;
1987 } __attribute__ (( packed )) *max_fragment_length_ext;
1988 struct {
1989 uint16_t type;
1990 uint16_t len;
1991 struct {
1992 uint16_t len;
1994 } __attribute__ (( packed )) data;
1995 } __attribute__ (( packed )) *signature_algorithms_ext;
1996 struct {
1997 uint16_t type;
1998 uint16_t len;
1999 struct {
2000 uint8_t len;
2002 sizeof ( tls->verify.client ) :0 ];
2003 } __attribute__ (( packed )) data;
2004 } __attribute__ (( packed )) *renegotiation_info_ext;
2005 struct {
2006 uint16_t type;
2007 uint16_t len;
2008 struct {
2009 uint8_t data[session->ticket_len];
2010 } __attribute__ (( packed )) data;
2011 } __attribute__ (( packed )) *session_ticket_ext;
2012 struct {
2013 uint16_t type;
2014 uint16_t len;
2015 struct {
2016 uint16_t len;
2018 } __attribute__ (( packed )) data;
2019 } __attribute__ (( packed )) *named_group_ext;
2020 struct {
2021 uint16_t type;
2022 uint16_t len;
2023 } __attribute__ (( packed )) *extended_master_secret_ext;
2024 struct {
2025 typeof ( *server_name_ext ) server_name;
2026 typeof ( *max_fragment_length_ext ) max_fragment_length;
2027 typeof ( *signature_algorithms_ext ) signature_algorithms;
2028 typeof ( *renegotiation_info_ext ) renegotiation_info;
2029 typeof ( *session_ticket_ext ) session_ticket;
2030 typeof ( *extended_master_secret_ext ) extended_master_secret;
2031 typeof ( *named_group_ext )
2032 named_group[TLS_NUM_NAMED_GROUPS ? 1 : 0];
2033 } __attribute__ (( packed )) *extensions;
2034 struct {
2035 uint32_t type_length;
2037 uint8_t random[32];
2038 uint8_t session_id_len;
2039 uint8_t session_id[tls->session_id_len];
2040 uint16_t cipher_suite_len;
2041 uint16_t cipher_suites[TLS_NUM_CIPHER_SUITES];
2042 uint8_t compression_methods_len;
2043 uint8_t compression_methods[1];
2044 uint16_t extensions_len;
2045 typeof ( *extensions ) extensions;
2046 } __attribute__ (( packed )) hello;
2047 struct tls_cipher_suite *suite;
2048 struct tls_signature_hash_algorithm *sighash;
2049 struct tls_named_group *group;
2050 unsigned int i;
2051
2052 /* Construct record */
2053 memset ( &hello, 0, sizeof ( hello ) );
2054 hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) |
2055 htonl ( sizeof ( hello ) -
2056 sizeof ( hello.type_length ) ) );
2057 hello.version = htons ( TLS_VERSION_MAX );
2058 memcpy ( &hello.random, &tls->client.random, sizeof ( hello.random ) );
2059 hello.session_id_len = tls->session_id_len;
2060 memcpy ( hello.session_id, tls->session_id,
2061 sizeof ( hello.session_id ) );
2062 hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) );
2063 i = 0 ; for_each_table_entry ( suite, TLS_CIPHER_SUITES )
2064 hello.cipher_suites[i++] = suite->code;
2065 hello.compression_methods_len = sizeof ( hello.compression_methods );
2066 hello.extensions_len = htons ( sizeof ( hello.extensions ) );
2067 extensions = &hello.extensions;
2068
2069 /* Construct server name extension */
2070 server_name_ext = &extensions->server_name;
2071 server_name_ext->type = htons ( TLS_SERVER_NAME );
2072 server_name_ext->len = htons ( sizeof ( server_name_ext->data ) );
2073 server_name_ext->data.len
2074 = htons ( sizeof ( server_name_ext->data.list ) );
2075 server_name_ext->data.list[0].type = TLS_SERVER_NAME_HOST_NAME;
2076 server_name_ext->data.list[0].len
2077 = htons ( sizeof ( server_name_ext->data.list[0].name ) );
2078 memcpy ( server_name_ext->data.list[0].name, session->name,
2079 sizeof ( server_name_ext->data.list[0].name ) );
2080
2081 /* Construct maximum fragment length extension */
2082 max_fragment_length_ext = &extensions->max_fragment_length;
2083 max_fragment_length_ext->type = htons ( TLS_MAX_FRAGMENT_LENGTH );
2084 max_fragment_length_ext->len
2085 = htons ( sizeof ( max_fragment_length_ext->data ) );
2086 max_fragment_length_ext->data.max = TLS_MAX_FRAGMENT_LENGTH_VALUE;
2087
2088 /* Construct supported signature algorithms extension */
2089 signature_algorithms_ext = &extensions->signature_algorithms;
2090 signature_algorithms_ext->type = htons ( TLS_SIGNATURE_ALGORITHMS );
2091 signature_algorithms_ext->len
2092 = htons ( sizeof ( signature_algorithms_ext->data ) );
2093 signature_algorithms_ext->data.len
2094 = htons ( sizeof ( signature_algorithms_ext->data.code ) );
2096 signature_algorithms_ext->data.code[i++] = sighash->code;
2097
2098 /* Construct renegotiation information extension */
2099 renegotiation_info_ext = &extensions->renegotiation_info;
2100 renegotiation_info_ext->type = htons ( TLS_RENEGOTIATION_INFO );
2101 renegotiation_info_ext->len
2102 = htons ( sizeof ( renegotiation_info_ext->data ) );
2103 renegotiation_info_ext->data.len
2104 = sizeof ( renegotiation_info_ext->data.data );
2105 memcpy ( renegotiation_info_ext->data.data, tls->verify.client,
2106 sizeof ( renegotiation_info_ext->data.data ) );
2107
2108 /* Construct session ticket extension */
2109 session_ticket_ext = &extensions->session_ticket;
2110 session_ticket_ext->type = htons ( TLS_SESSION_TICKET );
2111 session_ticket_ext->len
2112 = htons ( sizeof ( session_ticket_ext->data ) );
2113 memcpy ( session_ticket_ext->data.data, session->ticket,
2114 sizeof ( session_ticket_ext->data.data ) );
2115
2116 /* Construct extended master secret extension */
2117 extended_master_secret_ext = &extensions->extended_master_secret;
2118 extended_master_secret_ext->type
2120 extended_master_secret_ext->len = 0;
2121
2122 /* Construct named groups extension, if applicable */
2123 if ( sizeof ( extensions->named_group ) ) {
2124 named_group_ext = &extensions->named_group[0];
2125 named_group_ext->type = htons ( TLS_NAMED_GROUP );
2126 named_group_ext->len
2127 = htons ( sizeof ( named_group_ext->data ) );
2128 named_group_ext->data.len
2129 = htons ( sizeof ( named_group_ext->data.code ) );
2131 if ( group->code )
2132 named_group_ext->data.code[i++] = group->code;
2133 }
2135 }
2136
2137 return action ( tls, &hello, sizeof ( hello ) );
2138}
#define max(x, y)
Definition ath.h:41
#define TLS_VERSION_MAX
Maximum TLS version.
Definition crypto.h:17
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
uint16_t hello
Hello time.
Definition stp.h:27
struct tls_verify_data verify
Verification data.
Definition tls.h:556
size_t session_id_len
Length of session ID.
Definition tls.h:538
uint8_t session_id[32]
Session ID.
Definition tls.h:536
int secure_renegotiation
Secure renegotiation flag.
Definition tls.h:552
const char * name
Server name.
Definition tls.h:339
size_t ticket_len
Length of session ticket.
Definition tls.h:354
uint8_t client[12]
Client verification data.
Definition tls.h:174
#define TLS_NUM_CIPHER_SUITES
Number of supported cipher suites.
Definition tls.c:1199
#define TLS_NUM_SIG_HASH_ALGORITHMS
Number of supported signature and hash algorithms.
Definition tls.c:1345
#define TLS_NUM_NAMED_GROUPS
Number of non-anonymous TLS named groups.
Definition tls.h:273
#define TLS_EXTENDED_MASTER_SECRET
Definition tls.h:155
#define TLS_RENEGOTIATION_INFO
Definition tls.h:161
#define TLS_MAX_FRAGMENT_LENGTH_VALUE
Advertised maximum fragment length.
Definition tls.h:571
#define TLS_CLIENT_HELLO
Definition tls.h:68
#define TLS_SERVER_NAME
Definition tls.h:132
#define TLS_SERVER_NAME_HOST_NAME
Definition tls.h:133
#define TLS_MAX_FRAGMENT_LENGTH
Definition tls.h:136
#define TLS_NAMED_GROUP
Definition tls.h:143
#define TLS_SESSION_TICKET
Definition tls.h:158
#define TLS_SIGNATURE_ALGORITHMS
Definition tls.h:152

References __attribute__, assert, tls_connection::client, tls_verify_data::client, code, tls_cipher_suite::code, tls_signature_hash_algorithm::code, cpu_to_le32, data, for_each_table_entry, group, hello, htonl, htons, len, tls_session::list, max, memcpy(), memset(), name, tls_session::name, random(), tls_client::random, tls_connection::secure_renegotiation, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, strlen(), tls_session::ticket, tls_session::ticket_len, TLS_CIPHER_SUITES, TLS_CLIENT_HELLO, TLS_EXTENDED_MASTER_SECRET, TLS_MAX_FRAGMENT_LENGTH, TLS_MAX_FRAGMENT_LENGTH_VALUE, TLS_NAMED_GROUP, TLS_NAMED_GROUPS, TLS_NUM_CIPHER_SUITES, TLS_NUM_NAMED_GROUPS, TLS_NUM_SIG_HASH_ALGORITHMS, TLS_RENEGOTIATION_INFO, TLS_SERVER_NAME, TLS_SERVER_NAME_HOST_NAME, TLS_SESSION_TICKET, TLS_SIG_HASH_ALGORITHMS, TLS_SIGNATURE_ALGORITHMS, TLS_VERSION_MAX, type, typeof(), tls_connection::verify, and version.

Referenced by tls_new_server_hello(), and tls_send_client_hello().

◆ tls_send_client_hello()

int tls_send_client_hello ( struct tls_connection * tls)
static

Transmit Client Hello record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 2146 of file tls.c.

2146 {
2147
2148 return tls_client_hello ( tls, tls_send_handshake );
2149}
static int tls_client_hello(struct tls_connection *tls, int(*action)(struct tls_connection *tls, const void *data, size_t len))
Digest or transmit Client Hello record.
Definition tls.c:1963

References tls_client_hello(), and tls_send_handshake().

Referenced by tls_tx_step().

◆ tls_send_certificate()

int tls_send_certificate ( struct tls_connection * tls)
static

Transmit Certificate record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 2157 of file tls.c.

2157 {
2158 struct {
2160 uint8_t data[0];
2161 } __attribute__ (( packed )) *certificate;
2162 struct {
2163 uint32_t type_length;
2165 typeof ( *certificate ) certificates[0];
2166 } __attribute__ (( packed )) *certificates;
2167 struct x509_link *link;
2168 struct x509_certificate *cert;
2169 struct io_buffer *iobuf;
2170 size_t len;
2171
2172 /* Calculate length of client certificates */
2173 len = 0;
2175 cert = link->cert;
2176 len += ( sizeof ( *certificate ) + cert->raw.len );
2177 DBGC ( tls, "TLS %p sending client certificate %s\n",
2178 tls, x509_name ( cert ) );
2179 }
2180
2181 /* Allocate storage for Certificate record (which may be too
2182 * large for the stack).
2183 */
2184 iobuf = tls_alloc_iob ( tls, ( sizeof ( *certificates ) + len ) );
2185 if ( ! iobuf )
2186 return -ENOMEM_CERTIFICATE;
2187
2188 /* Populate record */
2189 certificates = iob_put ( iobuf, sizeof ( *certificates ) );
2190 certificates->type_length =
2192 htonl ( sizeof ( *certificates ) + len -
2193 sizeof ( certificates->type_length ) ) );
2194 tls_set_uint24 ( &certificates->length, len );
2196 cert = link->cert;
2197 certificate = iob_put ( iobuf, sizeof ( *certificate ) );
2198 tls_set_uint24 ( &certificate->length, cert->raw.len );
2199 memcpy ( iob_put ( iobuf, cert->raw.len ), cert->raw.data,
2200 cert->raw.len );
2201 }
2202
2203 /* Transmit record */
2204 return tls_send_record ( tls, TLS_TYPE_HANDSHAKE,
2205 iob_disown ( iobuf ) );
2206}
u32 link
Link to next descriptor.
Definition ar9003_mac.h:1
u16 length
Definition sky2.h:1
const void * data
Start of data.
Definition asn1.h:23
size_t len
Length of data.
Definition asn1.h:25
A TLS 24-bit integer.
Definition tls.c:236
struct asn1_cursor raw
Raw certificate.
Definition x509.h:231
struct list_head links
List of links.
Definition x509.h:205
#define ENOMEM_CERTIFICATE
Definition tls.c:127
static void tls_set_uint24(tls24_t *field24, unsigned long value)
Set 24-bit field value.
Definition tls.c:262
#define TLS_CERTIFICATE
Definition tls.h:71

References __attribute__, tls_client::chain, tls_connection::client, cpu_to_le32, asn1_cursor::data, data, DBGC, ENOMEM_CERTIFICATE, htonl, iob_disown, iob_put, asn1_cursor::len, len, length, link, x509_chain::links, io_buffer::list, list_for_each_entry, memcpy(), x509_certificate::raw, tls_alloc_iob(), TLS_CERTIFICATE, tls_send_record(), tls_set_uint24(), TLS_TYPE_HANDSHAKE, typeof(), and x509_name().

Referenced by tls_tx_step().

◆ tls_send_client_key_exchange()

int tls_send_client_key_exchange ( struct tls_connection * tls)
static

Transmit Client Key Exchange record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 2214 of file tls.c.

2214 {
2215 struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
2216 struct tls_cipher_suite *suite = cipherspec->suite;
2217 int rc;
2218
2219 /* Transmit Client Key Exchange record via key exchange algorithm */
2220 if ( ( rc = suite->exchange->client ( tls ) ) != 0 ) {
2221 DBGC ( tls, "TLS %p could not exchange keys: %s\n",
2222 tls, strerror ( rc ) );
2223 return rc;
2224 }
2225
2226 /* Generate master secret */
2228
2229 /* Generate keys from master secret */
2230 if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
2231 DBGC ( tls, "TLS %p could not generate keys: %s\n",
2232 tls, strerror ( rc ) );
2233 return rc;
2234 }
2235
2236 return 0;
2237}
int(* client)(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition tls.h:215
static void tls_generate_master_secret(struct tls_connection *tls)
Generate master secret.
Definition tls.c:927
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition tls.c:978

References tls_tx::cipherspec, tls_key_exchange_algorithm::client, DBGC, tls_cipher_suite::exchange, tls_cipherspec_pair::pending, rc, strerror(), tls_cipherspec::suite, tls_generate_keys(), tls_generate_master_secret(), and tls_connection::tx.

Referenced by tls_tx_step().

◆ tls_send_certificate_verify()

int tls_send_certificate_verify ( struct tls_connection * tls)
static

Transmit Certificate Verify record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 2245 of file tls.c.

2245 {
2246 struct digest_algorithm *digest = tls->key.digest;
2247 struct x509_certificate *cert = x509_first ( tls->client.chain );
2248 struct pubkey_algorithm *pubkey = cert->signature_algorithm->pubkey;
2249 struct asn1_cursor *key = privkey_cursor ( tls->client.key );
2250 uint8_t digest_out[ digest->digestsize ];
2251 struct tls_signature_hash_algorithm *sig_hash = NULL;
2252 struct asn1_builder builder = { NULL, 0 };
2253 int rc;
2254
2255 /* Generate digest to be signed */
2256 tls_verify_handshake ( tls, digest_out );
2257
2258 /* TLSv1.2 and later use explicit algorithm identifiers */
2259 if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
2260 sig_hash = tls_signature_hash_algorithm ( pubkey, digest );
2261 if ( ! sig_hash ) {
2262 DBGC ( tls, "TLS %p could not identify (%s,%s) "
2263 "signature and hash algorithm\n", tls,
2264 pubkey->name, digest->name );
2266 goto err_sig_hash;
2267 }
2268 }
2269
2270 /* Sign digest */
2271 if ( ( rc = pubkey_sign ( pubkey, key, digest, digest_out,
2272 &builder ) ) != 0 ) {
2273 DBGC ( tls, "TLS %p could not sign %s digest using %s client "
2274 "private key: %s\n", tls, digest->name, pubkey->name,
2275 strerror ( rc ) );
2276 goto err_pubkey_sign;
2277 }
2278
2279 /* Construct Certificate Verify record */
2280 {
2281 int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
2282 struct {
2283 uint32_t type_length;
2284 uint16_t sig_hash[use_sig_hash];
2285 uint16_t signature_len;
2286 } __attribute__ (( packed )) header;
2287
2288 header.type_length = ( cpu_to_le32 ( TLS_CERTIFICATE_VERIFY ) |
2289 htonl ( builder.len +
2290 sizeof ( header ) -
2291 sizeof ( header.type_length )));
2292 if ( use_sig_hash ) {
2293 memcpy ( &header.sig_hash[0], &sig_hash->code,
2294 sizeof ( header.sig_hash[0] ) );
2295 }
2296 header.signature_len = htons ( builder.len );
2297
2298 if ( ( rc = asn1_prepend_raw ( &builder, &header,
2299 sizeof ( header ) ) ) != 0 ) {
2300 DBGC ( tls, "TLS %p could not construct Certificate "
2301 "Verify: %s\n", tls, strerror ( rc ) );
2302 goto err_prepend;
2303 }
2304 }
2305
2306 /* Transmit record */
2307 if ( ( rc = tls_send_handshake ( tls, builder.data,
2308 builder.len ) ) != 0 ) {
2309 goto err_send;
2310 }
2311
2312 err_send:
2313 err_prepend:
2314 err_pubkey_sign:
2315 err_sig_hash:
2316 zfree ( builder.data );
2317 return rc;
2318}
static int pubkey_sign(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature)
Definition crypto.h:376
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition privkey.h:53
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable).
Definition asn1.h:420
struct asn1_algorithm * signature_algorithm
Signature algorithm.
Definition x509.h:239
static struct tls_signature_hash_algorithm * tls_signature_hash_algorithm(struct pubkey_algorithm *pubkey, struct digest_algorithm *digest)
Find TLS signature and hash algorithm.
Definition tls.c:1356
#define TLS_CERTIFICATE_VERIFY
Definition tls.h:75

References __attribute__, asn1_prepend_raw(), tls_client::chain, tls_connection::client, tls_signature_hash_algorithm::code, cpu_to_le32, asn1_builder::data, DBGC, tls_key_schedule::digest, digest_algorithm::digestsize, ENOTSUP_SIG_HASH, header, htonl, htons, key, tls_client::key, tls_connection::key, asn1_builder::len, memcpy(), digest_algorithm::name, pubkey_algorithm::name, NULL, privkey_cursor(), asn1_algorithm::pubkey, pubkey_sign(), rc, x509_certificate::signature_algorithm, strerror(), TLS_CERTIFICATE_VERIFY, tls_send_handshake(), tls_signature_hash_algorithm(), tls_verify_handshake(), tls_version(), TLS_VERSION_TLS_1_2, x509_first(), and zfree().

Referenced by tls_tx_step().

◆ tls_send_change_cipher()

int tls_send_change_cipher ( struct tls_connection * tls)
static

Transmit Change Cipher record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 2326 of file tls.c.

2326 {
2327 static const struct {
2328 uint8_t spec;
2329 } __attribute__ (( packed )) change_cipher = {
2330 .spec = TLS_CHANGE_CIPHER_SPEC,
2331 };
2332
2334 &change_cipher, sizeof ( change_cipher ) );
2335}
uint16_t spec
ENA specification version.
Definition ena.h:15
#define TLS_CHANGE_CIPHER_SPEC
Change cipher spec magic byte.
Definition tls.h:55
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
Definition tls.h:52

References __attribute__, spec, TLS_CHANGE_CIPHER_SPEC, tls_send_plaintext(), and TLS_TYPE_CHANGE_CIPHER.

Referenced by tls_tx_step().

◆ tls_send_finished()

int tls_send_finished ( struct tls_connection * tls)
static

Transmit Finished record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 2343 of file tls.c.

2343 {
2344 struct digest_algorithm *digest = tls->key.digest;
2345 struct tls_key_schedule *key = &tls->key;
2346 struct {
2347 uint32_t type_length;
2348 uint8_t verify_data[ sizeof ( tls->verify.client ) ];
2349 } __attribute__ (( packed )) finished;
2350 uint8_t digest_out[ digest->digestsize ];
2351 int rc;
2352
2353 /* Fail unless bound identity has been validated */
2354 if ( ! ( key->bound &&
2355 x509_is_valid ( key->bound, tls->server.root ) ) ) {
2356 DBGC ( tls, "TLS %p bound identity is not valid\n", tls );
2357 return -EPERM_BOUND;
2358 }
2359
2360 /* Construct client verification data */
2361 tls_verify_handshake ( tls, digest_out );
2362 tls_prf_label ( tls, tls->verify.client, sizeof ( tls->verify.client ),
2363 "client finished", digest_out, sizeof ( digest_out ) );
2364
2365 /* Construct record */
2366 memset ( &finished, 0, sizeof ( finished ) );
2367 finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
2368 htonl ( sizeof ( finished ) -
2369 sizeof ( finished.type_length ) ) );
2370 memcpy ( finished.verify_data, tls->verify.client,
2371 sizeof ( finished.verify_data ) );
2372
2373 /* Transmit record */
2374 if ( ( rc = tls_send_handshake ( tls, &finished,
2375 sizeof ( finished ) ) ) != 0 )
2376 return rc;
2377
2378 /* Mark client as finished */
2379 pending_put ( &tls->client.negotiation );
2380
2381 return 0;
2382}
#define EPERM_BOUND
Definition tls.c:195
#define TLS_FINISHED
Definition tls.h:77

References __attribute__, tls_connection::client, tls_verify_data::client, cpu_to_le32, DBGC, tls_key_schedule::digest, digest_algorithm::digestsize, EPERM_BOUND, htonl, key, tls_connection::key, memcpy(), memset(), tls_client::negotiation, pending_put(), rc, tls_server::root, tls_connection::server, TLS_FINISHED, tls_prf_label, tls_send_handshake(), tls_verify_handshake(), tls_connection::verify, and x509_is_valid().

Referenced by tls_tx_step().

◆ tls_new_change_cipher()

int tls_new_change_cipher ( struct tls_connection * tls,
struct io_buffer * iobuf )
static

Receive new Change Cipher record.

Parameters
tlsTLS connection
iobufI/O buffer
Return values
rcReturn status code

Definition at line 2414 of file tls.c.

2415 {
2416 const struct {
2417 uint8_t spec;
2418 } __attribute__ (( packed )) *change_cipher = iobuf->data;
2419 size_t len = iob_len ( iobuf );
2420 int rc;
2421
2422 /* Sanity check */
2423 if ( ( sizeof ( *change_cipher ) != len ) ||
2424 ( change_cipher->spec != TLS_CHANGE_CIPHER_SPEC ) ) {
2425 DBGC ( tls, "TLS %p received invalid Change Cipher\n", tls );
2426 DBGC_HD ( tls, change_cipher, len );
2427 return -EINVAL_CHANGE_CIPHER;
2428 }
2429 iob_pull ( iobuf, sizeof ( *change_cipher ) );
2430
2431 /* Change receive cipher spec */
2432 if ( ( rc = tls_change_cipher ( tls, &tls->rx.cipherspec ) ) != 0 ) {
2433 DBGC ( tls, "TLS %p could not activate RX cipher: %s\n",
2434 tls, strerror ( rc ) );
2435 return rc;
2436 }
2437 tls->rx.seq = ~( ( uint64_t ) 0 );
2438
2439 return 0;
2440}
unsigned long long uint64_t
Definition stdint.h:13
#define iob_pull(iobuf, len)
Definition iobuf.h:167
uint64_t seq
Sequence number.
Definition tls.h:485
#define EINVAL_CHANGE_CIPHER
Definition tls.c:59
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec_pair *pair)
Activate next cipher suite.
Definition tls.c:1323

References __attribute__, tls_rx::cipherspec, io_buffer::data, DBGC, DBGC_HD, EINVAL_CHANGE_CIPHER, iob_len(), iob_pull, len, rc, tls_connection::rx, tls_rx::seq, spec, strerror(), tls_change_cipher(), and TLS_CHANGE_CIPHER_SPEC.

Referenced by tls_new_record().

◆ tls_new_alert()

int tls_new_alert ( struct tls_connection * tls,
struct io_buffer * iobuf )
static

Receive new Alert record.

Parameters
tlsTLS connection
iobufI/O buffer
Return values
rcReturn status code

Definition at line 2449 of file tls.c.

2450 {
2451 const struct {
2452 uint8_t level;
2453 uint8_t description;
2454 char next[0];
2455 } __attribute__ (( packed )) *alert = iobuf->data;
2456 size_t len = iob_len ( iobuf );
2457
2458 /* Sanity check */
2459 if ( sizeof ( *alert ) != len ) {
2460 DBGC ( tls, "TLS %p received overlength Alert\n", tls );
2461 DBGC_HD ( tls, alert, len );
2462 return -EINVAL_ALERT;
2463 }
2464 iob_pull ( iobuf, sizeof ( *alert ) );
2465
2466 /* Handle alert */
2467 switch ( alert->level ) {
2468 case TLS_ALERT_WARNING:
2469 switch ( alert->description ) {
2471 DBGC ( tls, "TLS %p closed by notification\n", tls );
2472 tls_close ( tls, 0 );
2473 break;
2474 default:
2475 DBGC ( tls, "TLS %p received warning alert %d\n",
2476 tls, alert->description );
2477 break;
2478 }
2479 return 0;
2480 case TLS_ALERT_FATAL:
2481 DBGC ( tls, "TLS %p received fatal alert %d\n",
2482 tls, alert->description );
2483 return -EPERM_ALERT;
2484 default:
2485 DBGC ( tls, "TLS %p received unknown alert level %d"
2486 "(alert %d)\n", tls, alert->level, alert->description );
2487 return -EIO_ALERT;
2488 }
2489}
uint32_t next
Next descriptor address.
Definition dwmac.h:11
#define EINVAL_ALERT
Definition tls.c:63
#define EPERM_ALERT
Definition tls.c:171
#define EIO_ALERT
Definition tls.c:115
#define TLS_ALERT_FATAL
Definition tls.h:81

References __attribute__, alert(), io_buffer::data, DBGC, DBGC_HD, EINVAL_ALERT, EIO_ALERT, EPERM_ALERT, iob_len(), iob_pull, len, next, TLS_ALERT_CLOSE_NOTIFY, TLS_ALERT_FATAL, TLS_ALERT_WARNING, and tls_close().

Referenced by tls_new_record().

◆ tls_new_hello_request()

int tls_new_hello_request ( struct tls_connection * tls,
const void *data __unused,
size_t len __unused )
static

Receive new Hello Request handshake record.

Parameters
tlsTLS connection
dataPlaintext handshake record
lenLength of plaintext handshake record
Return values
rcReturn status code

Definition at line 2499 of file tls.c.

2501 {
2502
2503 /* Ignore if a handshake is in progress */
2504 if ( ! tls_ready ( tls ) ) {
2505 DBGC ( tls, "TLS %p ignoring Hello Request\n", tls );
2506 return 0;
2507 }
2508
2509 /* Fail unless server supports secure renegotiation */
2510 if ( ! ( tls->secure_renegotiation && tls->extended_master_secret ) ) {
2511 DBGC ( tls, "TLS %p refusing to renegotiate insecurely\n",
2512 tls );
2513 return -EPERM_RENEG_INSECURE;
2514 }
2515
2516 /* Restart negotiation */
2517 tls_restart ( tls );
2518
2519 return 0;
2520}
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition tls.c:274
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition tls.c:1923
#define EPERM_RENEG_INSECURE
Definition tls.c:179

References __unused, data, DBGC, EPERM_RENEG_INSECURE, tls_connection::extended_master_secret, len, tls_connection::secure_renegotiation, tls_ready(), and tls_restart().

Referenced by tls_new_handshake().

◆ tls_new_server_hello()

int tls_new_server_hello ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive new Server Hello handshake record.

Parameters
tlsTLS connection
dataPlaintext handshake record
lenLength of plaintext handshake record
Return values
rcReturn status code

Definition at line 2530 of file tls.c.

2531 {
2532 const struct {
2534 uint8_t random[32];
2535 uint8_t session_id_len;
2536 uint8_t session_id[0];
2537 } __attribute__ (( packed )) *hello_a = data;
2538 const uint8_t *session_id;
2539 const struct {
2540 uint16_t cipher_suite;
2541 uint8_t compression_method;
2542 char next[0];
2543 } __attribute__ (( packed )) *hello_b;
2544 const struct {
2545 uint16_t len;
2546 uint8_t data[0];
2547 } __attribute__ (( packed )) *exts;
2548 const struct {
2549 uint16_t type;
2550 uint16_t len;
2551 uint8_t data[0];
2552 } __attribute__ (( packed )) *ext;
2553 const struct {
2554 uint8_t len;
2555 uint8_t data[0];
2556 } __attribute__ (( packed )) *reneg = NULL;
2557 const struct {
2558 uint8_t data[0];
2559 } __attribute__ (( packed )) *ems = NULL;
2561 size_t exts_len;
2562 size_t ext_len;
2563 size_t remaining;
2564 int rc;
2565
2566 /* Parse header */
2567 if ( ( sizeof ( *hello_a ) > len ) ||
2568 ( hello_a->session_id_len > ( len - sizeof ( *hello_a ) ) ) ||
2569 ( sizeof ( *hello_b ) > ( len - sizeof ( *hello_a ) -
2570 hello_a->session_id_len ) ) ) {
2571 DBGC ( tls, "TLS %p received underlength Server Hello\n", tls );
2572 DBGC_HD ( tls, data, len );
2573 return -EINVAL_HELLO;
2574 }
2575 session_id = hello_a->session_id;
2576 hello_b = ( ( void * ) ( session_id + hello_a->session_id_len ) );
2577
2578 /* Parse extensions, if present */
2579 remaining = ( len - sizeof ( *hello_a ) - hello_a->session_id_len -
2580 sizeof ( *hello_b ) );
2581 if ( remaining ) {
2582
2583 /* Parse extensions length */
2584 exts = ( ( void * ) hello_b->next );
2585 if ( ( sizeof ( *exts ) > remaining ) ||
2586 ( ( exts_len = ntohs ( exts->len ) ) >
2587 ( remaining - sizeof ( *exts ) ) ) ) {
2588 DBGC ( tls, "TLS %p received underlength extensions\n",
2589 tls );
2590 DBGC_HD ( tls, data, len );
2591 return -EINVAL_HELLO;
2592 }
2593
2594 /* Parse extensions */
2595 for ( ext = ( ( void * ) exts->data ), remaining = exts_len ;
2596 remaining ;
2597 ext = ( ( ( void * ) ext ) + sizeof ( *ext ) + ext_len ),
2598 remaining -= ( sizeof ( *ext ) + ext_len ) ) {
2599
2600 /* Parse extension length */
2601 if ( ( sizeof ( *ext ) > remaining ) ||
2602 ( ( ext_len = ntohs ( ext->len ) ) >
2603 ( remaining - sizeof ( *ext ) ) ) ) {
2604 DBGC ( tls, "TLS %p received underlength "
2605 "extension\n", tls );
2606 DBGC_HD ( tls, data, len );
2607 return -EINVAL_HELLO;
2608 }
2609
2610 /* Record known extensions */
2611 switch ( ext->type ) {
2612 case htons ( TLS_RENEGOTIATION_INFO ) :
2613 reneg = ( ( void * ) ext->data );
2614 if ( ( sizeof ( *reneg ) > ext_len ) ||
2615 ( reneg->len >
2616 ( ext_len - sizeof ( *reneg ) ) ) ) {
2617 DBGC ( tls, "TLS %p received "
2618 "underlength renegotiation "
2619 "info\n", tls );
2620 DBGC_HD ( tls, data, len );
2621 return -EINVAL_HELLO;
2622 }
2623 break;
2625 ems = ( ( void * ) ext->data );
2626 break;
2627 }
2628 }
2629 }
2630
2631 /* Check and store protocol version */
2632 version = ntohs ( hello_a->version );
2633 if ( version < TLS_VERSION_MIN ) {
2634 DBGC ( tls, "TLS %p does not support protocol version %d.%d\n",
2635 tls, ( version >> 8 ), ( version & 0xff ) );
2636 return -ENOTSUP_VERSION;
2637 }
2638 if ( version > tls->version ) {
2639 DBGC ( tls, "TLS %p server attempted to illegally upgrade to "
2640 "protocol version %d.%d\n",
2641 tls, ( version >> 8 ), ( version & 0xff ) );
2642 return -EPROTO_VERSION;
2643 }
2644 tls->version = version;
2645 DBGC ( tls, "TLS %p using protocol version %d.%d\n",
2646 tls, ( version >> 8 ), ( version & 0xff ) );
2647
2648 /* Select cipher suite */
2649 if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 )
2650 return rc;
2651
2652 /* Add preceding Client Hello to handshake digest */
2653 if ( ( rc = tls_client_hello ( tls, tls_add_handshake ) ) != 0 )
2654 return rc;
2655
2656 /* Copy out server random bytes */
2657 memcpy ( &tls->server.random, &hello_a->random,
2658 sizeof ( tls->server.random ) );
2659
2660 /* Handle extended master secret */
2661 tls->extended_master_secret = ( !! ems );
2662
2663 /* Check session ID */
2664 if ( hello_a->session_id_len &&
2665 ( hello_a->session_id_len == tls->session_id_len ) &&
2666 ( memcmp ( session_id, tls->session_id,
2667 tls->session_id_len ) == 0 ) ) {
2668
2669 /* Session ID match: reuse master secret */
2670 DBGC ( tls, "TLS %p resuming session ID:\n", tls );
2671 DBGC_HDA ( tls, 0, tls->session_id, tls->session_id_len );
2672 tls_resume_secret ( tls );
2673 if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
2674 return rc;
2675
2676 /* Ensure master secret generation method matches */
2677 if ( tls->extended_master_secret !=
2679 DBGC ( tls, "TLS %p mismatched extended master secret "
2680 "extension\n", tls );
2681 return -EPERM_EMS;
2682 }
2683
2684 } else {
2685
2686 /* Record new session ID, if present */
2687 if ( hello_a->session_id_len &&
2688 ( hello_a->session_id_len <= sizeof ( tls->session_id ))){
2689 tls->session_id_len = hello_a->session_id_len;
2690 memcpy ( tls->session_id, session_id,
2691 tls->session_id_len );
2692 DBGC ( tls, "TLS %p new session ID:\n", tls );
2693 DBGC_HDA ( tls, 0, tls->session_id,
2694 tls->session_id_len );
2695 }
2696 }
2697
2698 /* Handle secure renegotiation */
2699 if ( tls->secure_renegotiation ) {
2700
2701 /* Secure renegotiation is expected; verify data */
2702 if ( ( reneg == NULL ) ||
2703 ( reneg->len != sizeof ( tls->verify ) ) ||
2704 ( memcmp ( reneg->data, &tls->verify,
2705 sizeof ( tls->verify ) ) != 0 ) ) {
2706 DBGC ( tls, "TLS %p server failed secure "
2707 "renegotiation\n", tls );
2708 return -EPERM_RENEG_VERIFY;
2709 }
2710
2711 } else if ( reneg != NULL ) {
2712
2713 /* Secure renegotiation is being enabled */
2714 if ( reneg->len != 0 ) {
2715 DBGC ( tls, "TLS %p server provided non-empty initial "
2716 "renegotiation\n", tls );
2717 return -EPERM_RENEG_VERIFY;
2718 }
2719 tls->secure_renegotiation = 1;
2720 }
2721
2722 return 0;
2723}
uint16_t ext
Extended status.
Definition ena.h:9
#define ENOTSUP_VERSION
Definition stp.c:46
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
int extended_master_secret
Extended master secret flag.
Definition tls.h:360
#define EPERM_EMS
Definition tls.c:191
static void tls_resume_secret(struct tls_connection *tls)
Resume from resumption master secret.
Definition tls.c:1119
#define EINVAL_HELLO
Definition tls.c:67
static int tls_select_cipher(struct tls_connection *tls, unsigned int cipher_suite)
Select next cipher suite.
Definition tls.c:1280
#define EPROTO_VERSION
Definition tls.c:199
#define EPERM_RENEG_VERIFY
Definition tls.c:183

References __attribute__, data, DBGC, DBGC_HD, DBGC_HDA, EINVAL_HELLO, ENOTSUP_VERSION, EPERM_EMS, EPERM_RENEG_VERIFY, EPROTO_VERSION, ext, tls_connection::extended_master_secret, tls_session::extended_master_secret, htons, len, memcmp(), memcpy(), next, ntohs, NULL, random(), tls_server::random, rc, tls_connection::secure_renegotiation, tls_connection::server, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, tls_add_handshake(), tls_client_hello(), TLS_EXTENDED_MASTER_SECRET, tls_generate_keys(), TLS_RENEGOTIATION_INFO, tls_resume_secret(), tls_select_cipher(), TLS_VERSION_MIN, type, tls_connection::verify, tls_connection::version, and version.

Referenced by tls_new_handshake().

◆ tls_new_session_ticket()

int tls_new_session_ticket ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive New Session Ticket handshake record.

Parameters
tlsTLS connection
dataPlaintext handshake record
lenLength of plaintext handshake record
Return values
rcReturn status code

Definition at line 2733 of file tls.c.

2734 {
2735 const struct {
2737 uint16_t len;
2738 uint8_t ticket[0];
2739 } __attribute__ (( packed )) *new_session_ticket = data;
2740 size_t ticket_len;
2741
2742 /* Parse header */
2743 if ( sizeof ( *new_session_ticket ) > len ) {
2744 DBGC ( tls, "TLS %p received underlength New Session Ticket\n",
2745 tls );
2746 DBGC_HD ( tls, data, len );
2747 return -EINVAL_TICKET;
2748 }
2749 ticket_len = ntohs ( new_session_ticket->len );
2750 if ( ticket_len > ( len - sizeof ( *new_session_ticket ) ) ) {
2751 DBGC ( tls, "TLS %p received overlength New Session Ticket\n",
2752 tls );
2753 DBGC_HD ( tls, data, len );
2754 return -EINVAL_TICKET;
2755 }
2756
2757 /* Free any unapplied new session ticket */
2758 zfree ( tls->new_session_ticket );
2759 tls->new_session_ticket = NULL;
2760 tls->new_session_ticket_len = 0;
2761
2762 /* Record ticket */
2763 tls->new_session_ticket = malloc ( ticket_len );
2764 if ( ! tls->new_session_ticket )
2765 return -ENOMEM;
2766 memcpy ( tls->new_session_ticket, new_session_ticket->ticket,
2767 ticket_len );
2768 tls->new_session_ticket_len = ticket_len;
2769 DBGC ( tls, "TLS %p new session ticket:\n", tls );
2770 DBGC_HDA ( tls, 0, tls->new_session_ticket,
2772
2773 return 0;
2774}
size_t new_session_ticket_len
Length of new session ticket.
Definition tls.h:542
#define EINVAL_TICKET
Definition tls.c:107
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
Definition wpa.h:27

References __attribute__, data, DBGC, DBGC_HD, DBGC_HDA, EINVAL_TICKET, ENOMEM, len, lifetime, malloc(), memcpy(), tls_connection::new_session_ticket, tls_connection::new_session_ticket_len, ntohs, NULL, and zfree().

Referenced by tls_new_handshake().

◆ tls_parse_chain()

int tls_parse_chain ( struct tls_connection * tls,
const void * data,
size_t len )
static

Parse certificate chain.

Parameters
tlsTLS connection
dataCertificate chain
lenLength of certificate chain
Return values
rcReturn status code

Definition at line 2784 of file tls.c.

2785 {
2786 struct x509_certificate *cert;
2787 size_t remaining = len;
2788 int rc;
2789
2790 /* Free any existing certificate chain */
2791 x509_chain_put ( tls->server.chain );
2792 tls->server.chain = NULL;
2793
2794 /* Certificate has changed and so the key schedule is no
2795 * longer bound to the server identity.
2796 */
2797 tls->key.bound = 0;
2798
2799 /* Create certificate chain */
2800 tls->server.chain = x509_alloc_chain();
2801 if ( ! tls->server.chain ) {
2802 rc = -ENOMEM_CHAIN;
2803 goto err_alloc_chain;
2804 }
2805
2806 /* Add certificates to chain */
2807 while ( remaining ) {
2808 const struct {
2809 tls24_t length;
2810 uint8_t data[0];
2811 } __attribute__ (( packed )) *certificate = data;
2812 size_t certificate_len;
2813 size_t record_len;
2814
2815 /* Parse header */
2816 if ( sizeof ( *certificate ) > remaining ) {
2817 DBGC ( tls, "TLS %p underlength certificate:\n", tls );
2818 DBGC_HDA ( tls, 0, data, remaining );
2820 goto err_underlength;
2821 }
2822 certificate_len = tls_uint24 ( &certificate->length );
2823 if ( certificate_len > ( remaining - sizeof ( *certificate ) )){
2824 DBGC ( tls, "TLS %p overlength certificate:\n", tls );
2825 DBGC_HDA ( tls, 0, data, remaining );
2827 goto err_overlength;
2828 }
2829 record_len = ( sizeof ( *certificate ) + certificate_len );
2830
2831 /* Add certificate to chain */
2832 if ( ( rc = x509_append_raw ( tls->server.chain,
2833 certificate->data,
2834 certificate_len ) ) != 0 ) {
2835 DBGC ( tls, "TLS %p could not append certificate: %s\n",
2836 tls, strerror ( rc ) );
2837 DBGC_HDA ( tls, 0, data, remaining );
2838 goto err_parse;
2839 }
2840 cert = x509_last ( tls->server.chain );
2841 DBGC ( tls, "TLS %p found certificate %s\n",
2842 tls, x509_name ( cert ) );
2843
2844 /* Move to next certificate in list */
2845 data += record_len;
2846 remaining -= record_len;
2847 }
2848
2849 /* Identify server certificate */
2850 cert = x509_first ( tls->server.chain );
2851 if ( ! cert ) {
2852 DBGC ( tls, "TLS %p certificate chain is empty\n", tls );
2853 rc = -ENOENT_CERT;
2854 goto err_empty;
2855 }
2856
2857 /* Verify server name */
2858 if ( ( rc = x509_check_name ( cert, tls->session->name ) ) != 0 ) {
2859 DBGC ( tls, "TLS %p server certificate does not match %s: %s\n",
2860 tls, tls->session->name, strerror ( rc ) );
2861 goto err_name;
2862 }
2863
2864 return 0;
2865
2866 err_name:
2867 err_empty:
2868 err_parse:
2869 err_overlength:
2870 err_underlength:
2871 x509_chain_put ( tls->server.chain );
2872 tls->server.chain = NULL;
2873 err_alloc_chain:
2874 return rc;
2875}
#define ENOMEM_CHAIN
Definition tls.c:131
#define EINVAL_CERTIFICATE
Definition tls.c:71
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition tls.c:251
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition x509.c:1564
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition x509.c:1615
int x509_append_raw(struct x509_chain *chain, const void *data, size_t len)
Append X.509 certificate to X.509 certificate chain.
Definition x509.c:1674
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition x509.h:325

References __attribute__, tls_key_schedule::bound, tls_server::chain, data, DBGC, DBGC_HDA, EINVAL_CERTIFICATE, ENOENT_CERT, ENOMEM_CHAIN, tls_connection::key, len, length, tls_session::name, NULL, rc, tls_connection::server, tls_connection::session, strerror(), tls_uint24(), x509_alloc_chain(), x509_append_raw(), x509_chain_put(), x509_check_name(), x509_first(), x509_last(), and x509_name().

Referenced by tls_new_certificate().

◆ tls_new_certificate()

int tls_new_certificate ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive new Certificate handshake record.

Parameters
tlsTLS connection
dataPlaintext handshake record
lenLength of plaintext handshake record
Return values
rcReturn status code

Definition at line 2885 of file tls.c.

2886 {
2887 const struct {
2889 uint8_t certificates[0];
2890 } __attribute__ (( packed )) *certificate = data;
2891 size_t certificates_len;
2892 int rc;
2893
2894 /* Parse header */
2895 if ( sizeof ( *certificate ) > len ) {
2896 DBGC ( tls, "TLS %p received underlength Server Certificate\n",
2897 tls );
2898 DBGC_HD ( tls, data, len );
2899 return -EINVAL_CERTIFICATES;
2900 }
2901 certificates_len = tls_uint24 ( &certificate->length );
2902 if ( certificates_len > ( len - sizeof ( *certificate ) ) ) {
2903 DBGC ( tls, "TLS %p received overlength Server Certificate\n",
2904 tls );
2905 DBGC_HD ( tls, data, len );
2906 return -EINVAL_CERTIFICATES;
2907 }
2908
2909 /* Parse certificate chain */
2910 if ( ( rc = tls_parse_chain ( tls, certificate->certificates,
2911 certificates_len ) ) != 0 )
2912 return rc;
2913
2914 return 0;
2915}
#define EINVAL_CERTIFICATES
Definition tls.c:75
static int tls_parse_chain(struct tls_connection *tls, const void *data, size_t len)
Parse certificate chain.
Definition tls.c:2784

References __attribute__, data, DBGC, DBGC_HD, EINVAL_CERTIFICATES, len, length, rc, tls_parse_chain(), and tls_uint24().

Referenced by tls_new_handshake().

◆ tls_new_server_key_exchange()

int tls_new_server_key_exchange ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive new Server Key Exchange handshake record.

Parameters
tlsTLS connection
dataPlaintext handshake record
lenLength of plaintext handshake record
Return values
rcReturn status code

Definition at line 2925 of file tls.c.

2926 {
2927 struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
2928 struct tls_cipher_suite *suite = cipherspec->suite;
2929 int rc;
2930
2931 /* Parse via key exchange algorithm */
2932 if ( ( rc = suite->exchange->server ( tls, data, len ) ) != 0 )
2933 return rc;
2934
2935 return 0;
2936}
int(* server)(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Key Exchange record using ECDHE key exchange.
Definition tls.h:207

References tls_tx::cipherspec, data, tls_cipher_suite::exchange, len, tls_cipherspec_pair::pending, rc, tls_key_exchange_algorithm::server, tls_cipherspec::suite, and tls_connection::tx.

Referenced by tls_new_handshake().

◆ tls_new_certificate_request()

int tls_new_certificate_request ( struct tls_connection * tls,
const void *data __unused,
size_t len __unused )
static

Receive new Certificate Request handshake record.

Parameters
tlsTLS connection
dataPlaintext handshake record
lenLength of plaintext handshake record
Return values
rcReturn status code

Definition at line 2946 of file tls.c.

2948 {
2949 struct x509_certificate *cert;
2950 int rc;
2951
2952 /* We can only send a single certificate, so there is no point
2953 * in parsing the Certificate Request.
2954 */
2955
2956 /* Free any existing client certificate chain */
2957 x509_chain_put ( tls->client.chain );
2958 tls->client.chain = NULL;
2959
2960 /* Create client certificate chain */
2961 tls->client.chain = x509_alloc_chain();
2962 if ( ! tls->client.chain ) {
2963 rc = -ENOMEM;
2964 goto err_alloc;
2965 }
2966
2967 /* Determine client certificate to be sent, if any */
2968 cert = x509_find_key ( NULL, tls->client.key );
2969 if ( cert ) {
2970 DBGC ( tls, "TLS %p selected client certificate %s\n",
2971 tls, x509_name ( cert ) );
2972
2973 /* Append client certificate to chain */
2974 if ( ( rc = x509_append ( tls->client.chain, cert ) ) != 0 )
2975 goto err_append;
2976
2977 /* Append any relevant issuer certificates */
2978 if ( ( rc = x509_auto_append ( tls->client.chain,
2979 &certstore ) ) != 0 )
2980 goto err_auto_append;
2981 } else {
2982
2983 /* Send an empty certificate chain */
2984 DBGC ( tls, "TLS %p could not find certificate corresponding "
2985 "to private key\n", tls );
2986 }
2987
2988 return 0;
2989
2990 err_auto_append:
2991 err_append:
2992 x509_chain_put ( tls->client.chain );
2993 tls->client.chain = NULL;
2994 err_alloc:
2995 return rc;
2996}
struct x509_chain certstore
Certificate store.
Definition certstore.c:90
int x509_auto_append(struct x509_chain *chain, struct x509_chain *store)
Append X.509 certificates to X.509 certificate chain.
Definition x509.c:1868
struct x509_certificate * x509_find_key(struct x509_chain *store, struct private_key *key)
Identify X.509 certificate by corresponding public key.
Definition x509.c:1835
int x509_append(struct x509_chain *chain, struct x509_certificate *cert)
Append X.509 certificate to X.509 certificate chain.
Definition x509.c:1638

References __unused, certstore, tls_client::chain, tls_connection::client, data, DBGC, ENOMEM, tls_client::key, len, NULL, rc, x509_alloc_chain(), x509_append(), x509_auto_append(), x509_chain_put(), x509_find_key(), and x509_name().

Referenced by tls_new_handshake().

◆ tls_new_server_hello_done()

int tls_new_server_hello_done ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive new Server Hello Done handshake record.

Parameters
tlsTLS connection
dataPlaintext handshake record
lenLength of plaintext handshake record
Return values
rcReturn status code

Definition at line 3006 of file tls.c.

3007 {
3008 const struct {
3009 char next[0];
3010 } __attribute__ (( packed )) *hello_done = data;
3011 int rc;
3012
3013 /* Sanity check */
3014 if ( sizeof ( *hello_done ) != len ) {
3015 DBGC ( tls, "TLS %p received overlength Server Hello Done\n",
3016 tls );
3017 DBGC_HD ( tls, data, len );
3018 return -EINVAL_HELLO_DONE;
3019 }
3020
3021 /* Begin certificate validation */
3022 if ( ( rc = create_validator ( &tls->server.validator,
3023 tls->server.chain,
3024 tls->server.root ) ) != 0 ) {
3025 DBGC ( tls, "TLS %p could not start certificate validation: "
3026 "%s\n", tls, strerror ( rc ) );
3027 return rc;
3028 }
3029 pending_get ( &tls->server.validation );
3030
3031 return 0;
3032}
#define EINVAL_HELLO_DONE
Definition tls.c:79
int create_validator(struct interface *job, struct x509_chain *chain, struct x509_root *root)
Instantiate a certificate validator.
Definition validator.c:760

References __attribute__, tls_server::chain, create_validator(), data, DBGC, DBGC_HD, EINVAL_HELLO_DONE, len, next, pending_get(), rc, tls_server::root, tls_connection::server, strerror(), tls_server::validation, and tls_server::validator.

Referenced by tls_new_handshake().

◆ tls_new_finished()

int tls_new_finished ( struct tls_connection * tls,
const void * data,
size_t len )
static

Receive new Finished handshake record.

Parameters
tlsTLS connection
dataPlaintext handshake record
lenLength of plaintext handshake record
Return values
rcReturn status code

Definition at line 3042 of file tls.c.

3043 {
3044 struct tls_session *session = tls->session;
3045 struct tls_key_schedule *key = &tls->key;
3046 struct digest_algorithm *digest = tls->key.digest;
3047 const struct {
3048 uint8_t verify_data[ sizeof ( tls->verify.server ) ];
3049 char next[0];
3050 } __attribute__ (( packed )) *finished = data;
3051 uint8_t digest_out[ digest->digestsize ];
3052
3053 /* Sanity checks */
3054 if ( ! ( digest->digestsize && key->keyed && key->bound ) ) {
3055 DBGC ( tls, "TLS %p received premature Finished\n", tls );
3056 DBGC_HDA ( tls, 0, data, len );
3057 return -EINVAL_FINISHED;
3058 }
3059 if ( sizeof ( *finished ) != len ) {
3060 DBGC ( tls, "TLS %p received overlength Finished\n", tls );
3061 DBGC_HDA ( tls, 0, data, len );
3062 return -EINVAL_FINISHED;
3063 }
3064
3065 /* Verify data */
3066 tls_verify_handshake ( tls, digest_out );
3067 tls_prf_label ( tls, tls->verify.server, sizeof ( tls->verify.server ),
3068 "server finished", digest_out, sizeof ( digest_out ) );
3069 if ( memcmp ( tls->verify.server, finished->verify_data,
3070 sizeof ( tls->verify.server ) ) != 0 ) {
3071 DBGC ( tls, "TLS %p verification failed\n", tls );
3072 return -EPERM_VERIFY;
3073 }
3074
3075 /* Mark server as finished */
3076 pending_put ( &tls->server.negotiation );
3077
3078 /* If we are resuming a session (i.e. if the server Finished
3079 * arrives before the client Finished is sent), then schedule
3080 * transmission of Change Cipher and Finished.
3081 */
3082 if ( is_pending ( &tls->client.negotiation ) ) {
3084 tls_tx_resume ( tls );
3085 }
3086
3087 /* Record session ID, ticket, and master secret, if applicable */
3088 if ( x509_is_valid ( key->bound, tls->server.root ) &&
3089 ( tls->session_id_len || tls->new_session_ticket_len ) ) {
3092 x509_put ( session->cert );
3093 session->cert = x509_get ( key->bound );
3094 if ( tls->session_id_len ) {
3095 session->id_len = tls->session_id_len;
3096 memcpy ( session->id, tls->session_id,
3097 sizeof ( session->id ) );
3098 }
3099 if ( tls->new_session_ticket_len ) {
3100 zfree ( session->ticket );
3101 session->ticket = tls->new_session_ticket;
3102 session->ticket_len = tls->new_session_ticket_len;
3103 tls->new_session_ticket = NULL;
3104 tls->new_session_ticket_len = 0;
3105 }
3106 }
3107
3108 /* Move to end of session's connection list and allow other
3109 * connections to start making progress.
3110 */
3111 list_del ( &tls->list );
3112 list_add_tail ( &tls->list, &session->conn );
3113 tls_tx_resume_all ( session );
3114
3115 /* Send notification of a window change */
3117
3118 return 0;
3119}
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
uint8_t id[32]
Session ID.
Definition tls.h:348
size_t id_len
Length of session ID.
Definition tls.h:350
uint8_t server[12]
Server verification data.
Definition tls.h:176
#define EINVAL_FINISHED
Definition tls.c:83
static void tls_generate_resumption_master(struct tls_connection *tls)
Generate resumption master secret.
Definition tls.c:1059
#define EPERM_VERIFY
Definition tls.c:175
@ TLS_TX_FINISHED
Definition tls.h:192
@ TLS_TX_CHANGE_CIPHER
Definition tls.h:191
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

References __attribute__, tls_session::cert, tls_connection::client, tls_session::conn, data, DBGC, DBGC_HDA, tls_key_schedule::digest, digest_algorithm::digestsize, EINVAL_FINISHED, EPERM_VERIFY, tls_connection::extended_master_secret, tls_session::extended_master_secret, tls_session::id, tls_session::id_len, is_pending(), key, tls_connection::key, len, tls_connection::list, list_add_tail, list_del, memcmp(), memcpy(), tls_client::negotiation, tls_server::negotiation, tls_connection::new_session_ticket, tls_connection::new_session_ticket_len, next, NULL, tls_tx::pending, pending_put(), tls_connection::plainstream, tls_server::root, tls_connection::server, tls_verify_data::server, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, tls_session::ticket, tls_session::ticket_len, tls_generate_resumption_master(), tls_prf_label, TLS_TX_CHANGE_CIPHER, TLS_TX_FINISHED, tls_tx_resume(), tls_tx_resume_all(), tls_verify_handshake(), tls_connection::tx, tls_connection::verify, x509_get(), x509_is_valid(), x509_put(), xfer_window_changed(), and zfree().

Referenced by tls_new_handshake().

◆ tls_new_handshake()

int tls_new_handshake ( struct tls_connection * tls,
struct io_buffer * iobuf )
static

Receive new Handshake record.

Parameters
tlsTLS connection
iobufI/O buffer
Return values
rcReturn status code

Definition at line 3128 of file tls.c.

3129 {
3130 size_t remaining;
3131 int rc;
3132
3133 while ( ( remaining = iob_len ( iobuf ) ) ) {
3134 const struct {
3135 uint8_t type;
3137 uint8_t payload[0];
3138 } __attribute__ (( packed )) *handshake = iobuf->data;
3139 const void *payload;
3140 size_t payload_len;
3141 size_t record_len;
3142
3143 /* Parse header */
3144 if ( sizeof ( *handshake ) > remaining ) {
3145 /* Leave remaining fragment unconsumed */
3146 break;
3147 }
3148 payload_len = tls_uint24 ( &handshake->length );
3149 if ( payload_len > ( remaining - sizeof ( *handshake ) ) ) {
3150 /* Leave remaining fragment unconsumed */
3151 break;
3152 }
3153 payload = &handshake->payload;
3154 record_len = ( sizeof ( *handshake ) + payload_len );
3155
3156 /* Handle payload */
3157 switch ( handshake->type ) {
3158 case TLS_HELLO_REQUEST:
3159 rc = tls_new_hello_request ( tls, payload,
3160 payload_len );
3161 break;
3162 case TLS_SERVER_HELLO:
3163 rc = tls_new_server_hello ( tls, payload, payload_len );
3164 break;
3166 rc = tls_new_session_ticket ( tls, payload,
3167 payload_len );
3168 break;
3169 case TLS_CERTIFICATE:
3170 rc = tls_new_certificate ( tls, payload, payload_len );
3171 break;
3173 rc = tls_new_server_key_exchange ( tls, payload,
3174 payload_len );
3175 break;
3177 rc = tls_new_certificate_request ( tls, payload,
3178 payload_len );
3179 break;
3181 rc = tls_new_server_hello_done ( tls, payload,
3182 payload_len );
3183 break;
3184 case TLS_FINISHED:
3185 rc = tls_new_finished ( tls, payload, payload_len );
3186 break;
3187 default:
3188 DBGC ( tls, "TLS %p ignoring handshake type %d\n",
3189 tls, handshake->type );
3190 rc = 0;
3191 break;
3192 }
3193
3194 /* Add to handshake digest (except for Hello Requests,
3195 * which are explicitly excluded).
3196 */
3197 if ( handshake->type != TLS_HELLO_REQUEST )
3198 tls_add_handshake ( tls, handshake, record_len );
3199
3200 /* Abort on failure */
3201 if ( rc != 0 )
3202 return rc;
3203
3204 /* Move to next handshake record */
3205 iob_pull ( iobuf, record_len );
3206 }
3207
3208 return 0;
3209}
static int tls_new_finished(struct tls_connection *tls, const void *data, size_t len)
Receive new Finished handshake record.
Definition tls.c:3042
static int tls_new_server_hello(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Hello handshake record.
Definition tls.c:2530
static int tls_new_certificate_request(struct tls_connection *tls, const void *data __unused, size_t len __unused)
Receive new Certificate Request handshake record.
Definition tls.c:2946
static int tls_new_session_ticket(struct tls_connection *tls, const void *data, size_t len)
Receive New Session Ticket handshake record.
Definition tls.c:2733
static int tls_new_hello_request(struct tls_connection *tls, const void *data __unused, size_t len __unused)
Receive new Hello Request handshake record.
Definition tls.c:2499
static int tls_new_certificate(struct tls_connection *tls, const void *data, size_t len)
Receive new Certificate handshake record.
Definition tls.c:2885
static int tls_new_server_hello_done(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Hello Done handshake record.
Definition tls.c:3006
static int tls_new_server_key_exchange(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Key Exchange handshake record.
Definition tls.c:2925
#define TLS_SERVER_HELLO
Definition tls.h:69
#define TLS_SERVER_KEY_EXCHANGE
Definition tls.h:72
#define TLS_NEW_SESSION_TICKET
Definition tls.h:70
#define TLS_HELLO_REQUEST
Definition tls.h:67
#define TLS_CERTIFICATE_REQUEST
Definition tls.h:73
#define TLS_SERVER_HELLO_DONE
Definition tls.h:74

References __attribute__, io_buffer::data, DBGC, iob_len(), iob_pull, length, rc, tls_add_handshake(), TLS_CERTIFICATE, TLS_CERTIFICATE_REQUEST, TLS_FINISHED, TLS_HELLO_REQUEST, tls_new_certificate(), tls_new_certificate_request(), tls_new_finished(), tls_new_hello_request(), tls_new_server_hello(), tls_new_server_hello_done(), tls_new_server_key_exchange(), TLS_NEW_SESSION_TICKET, tls_new_session_ticket(), TLS_SERVER_HELLO, TLS_SERVER_HELLO_DONE, TLS_SERVER_KEY_EXCHANGE, tls_uint24(), and type.

Referenced by tls_new_record().

◆ tls_new_unknown()

int tls_new_unknown ( struct tls_connection *tls __unused,
struct io_buffer * iobuf )
static

Receive new unknown record.

Parameters
tlsTLS connection
iobufI/O buffer
Return values
rcReturn status code

Definition at line 3218 of file tls.c.

3219 {
3220
3221 /* RFC4346 says that we should just ignore unknown record types */
3222 iob_pull ( iobuf, iob_len ( iobuf ) );
3223 return 0;
3224}

References __unused, iob_len(), and iob_pull.

Referenced by tls_new_record().

◆ tls_new_data()

int tls_new_data ( struct tls_connection * tls,
struct list_head * rx_data )
static

Receive new data record.

Parameters
tlsTLS connection
rx_dataList of received data buffers
Return values
rcReturn status code

Definition at line 3233 of file tls.c.

3234 {
3235 struct io_buffer *iobuf;
3236 int rc;
3237
3238 /* Fail unless we are ready to receive data */
3239 if ( ! tls_ready ( tls ) )
3240 return -ENOTCONN;
3241
3242 /* Deliver each I/O buffer in turn */
3243 while ( ( iobuf = list_first_entry ( rx_data, struct io_buffer,
3244 list ) ) ) {
3245 list_del ( &iobuf->list );
3246 if ( ( rc = xfer_deliver_iob ( &tls->plainstream,
3247 iobuf ) ) != 0 ) {
3248 DBGC ( tls, "TLS %p could not deliver data: "
3249 "%s\n", tls, strerror ( rc ) );
3250 return rc;
3251 }
3252 }
3253
3254 return 0;
3255}
#define ENOTCONN
The socket is not connected.
Definition errno.h:613
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334

References DBGC, ENOTCONN, io_buffer::list, list_del, list_first_entry, tls_connection::plainstream, rc, strerror(), tls_ready(), and xfer_deliver_iob().

Referenced by tls_new_record().

◆ tls_new_record()

int tls_new_record ( struct tls_connection * tls,
unsigned int type,
struct list_head * rx_data )
static

Receive new record.

Parameters
tlsTLS connection
typeRecord type
rx_dataList of received data buffers
Return values
rcReturn status code

Definition at line 3265 of file tls.c.

3266 {
3267 int ( * handler ) ( struct tls_connection *tls,
3268 struct io_buffer *iobuf );
3269 struct io_buffer *tmp = NULL;
3270 struct io_buffer **iobuf;
3271 int rc;
3272
3273 /* Deliver data records as-is to the plainstream interface */
3274 if ( type == TLS_TYPE_DATA )
3275 return tls_new_data ( tls, rx_data );
3276
3277 /* Determine handler and fragment buffer */
3278 iobuf = &tmp;
3279 switch ( type ) {
3281 handler = tls_new_change_cipher;
3282 break;
3283 case TLS_TYPE_ALERT:
3284 handler = tls_new_alert;
3285 break;
3286 case TLS_TYPE_HANDSHAKE:
3287 handler = tls_new_handshake;
3288 iobuf = &tls->rx.handshake;
3289 break;
3290 default:
3291 DBGC ( tls, "TLS %p unknown record type %d\n", tls, type );
3292 handler = tls_new_unknown;
3293 break;
3294 }
3295
3296 /* Merge into a single I/O buffer */
3297 if ( *iobuf )
3298 list_add ( &(*iobuf)->list, rx_data );
3299 *iobuf = iob_concatenate ( rx_data );
3300 if ( ! *iobuf ) {
3301 DBGC ( tls, "TLS %p could not concatenate non-data record "
3302 "type %d\n", tls, type );
3304 goto err_concatenate;
3305 }
3306
3307 /* Handle record */
3308 if ( ( rc = handler ( tls, *iobuf ) ) != 0 )
3309 goto err_handle;
3310
3311 /* Discard I/O buffer if empty */
3312 if ( ! iob_len ( *iobuf ) ) {
3313 free_iob ( *iobuf );
3314 *iobuf = NULL;
3315 }
3316
3317 /* Sanity check */
3318 assert ( tmp == NULL );
3319
3320 return 0;
3321
3322 err_handle:
3323 free_iob ( *iobuf );
3324 *iobuf = NULL;
3325 err_concatenate:
3326 return rc;
3327}
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
Definition iobuf.c:250
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
static int tls_new_change_cipher(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Change Cipher record.
Definition tls.c:2414
#define ENOMEM_RX_CONCAT
Definition tls.c:147
static int tls_new_unknown(struct tls_connection *tls __unused, struct io_buffer *iobuf)
Receive new unknown record.
Definition tls.c:3218
static int tls_new_data(struct tls_connection *tls, struct list_head *rx_data)
Receive new data record.
Definition tls.c:3233
static int tls_new_handshake(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Handshake record.
Definition tls.c:3128
static int tls_new_alert(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Alert record.
Definition tls.c:2449
#define TLS_TYPE_DATA
Application data content type.
Definition tls.h:64

References assert, DBGC, ENOMEM_RX_CONCAT, free_iob(), tls_rx::handshake, iob_concatenate(), iob_len(), list_add, NULL, rc, tls_connection::rx, tls_new_alert(), tls_new_change_cipher(), tls_new_data(), tls_new_handshake(), tls_new_unknown(), TLS_TYPE_ALERT, TLS_TYPE_CHANGE_CIPHER, TLS_TYPE_DATA, TLS_TYPE_HANDSHAKE, tmp, and type.

Referenced by tls_new_ciphertext().

◆ tls_hmac_init()

void tls_hmac_init ( struct tls_cipherspec * cipherspec,
void * ctx,
struct tls_auth_header * authhdr )
static

Initialise HMAC.

Parameters
cipherspecCipher specification
ctxContext
authhdrAuthentication header

Definition at line 3343 of file tls.c.

3344 {
3345 struct tls_cipher_suite *suite = cipherspec->suite;
3346 struct digest_algorithm *digest = suite->digest;
3347
3348 hmac_init ( digest, ctx, cipherspec->mac_secret, suite->mac_len );
3349 hmac_update ( digest, ctx, authhdr, sizeof ( *authhdr ) );
3350}
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *secret, size_t len)
Initialise HMAC.
Definition hmac.c:106

References ctx, tls_cipher_suite::digest, hmac_init(), hmac_update(), tls_cipher_suite::mac_len, tls_cipherspec::mac_secret, and tls_cipherspec::suite.

Referenced by tls_hmac(), and tls_hmac_list().

◆ tls_hmac_update()

void tls_hmac_update ( struct tls_cipherspec * cipherspec,
void * ctx,
const void * data,
size_t len )
static

Update HMAC.

Parameters
cipherspecCipher specification
ctxContext
dataData
lenLength of data

Definition at line 3360 of file tls.c.

3361 {
3362 struct digest_algorithm *digest = cipherspec->suite->digest;
3363
3364 hmac_update ( digest, ctx, data, len );
3365}

References ctx, data, tls_cipher_suite::digest, hmac_update(), len, and tls_cipherspec::suite.

Referenced by tls_hmac(), and tls_hmac_list().

◆ tls_hmac_final()

void tls_hmac_final ( struct tls_cipherspec * cipherspec,
void * ctx,
void * hmac )
static

Finalise HMAC.

Parameters
cipherspecCipher specification
ctxContext
macHMAC to fill in

Definition at line 3374 of file tls.c.

3375 {
3376 struct digest_algorithm *digest = cipherspec->suite->digest;
3377
3378 hmac_final ( digest, ctx, hmac );
3379}

References ctx, tls_cipher_suite::digest, hmac_final(), and tls_cipherspec::suite.

Referenced by tls_hmac(), and tls_hmac_list().

◆ tls_hmac()

void tls_hmac ( struct tls_cipherspec * cipherspec,
struct tls_auth_header * authhdr,
const void * data,
size_t len,
void * hmac )
static

Calculate HMAC.

Parameters
cipherspecCipher specification
authhdrAuthentication header
dataData
lenLength of data
macHMAC to fill in

Definition at line 3390 of file tls.c.

3392 {
3393 struct digest_algorithm *digest = cipherspec->suite->digest;
3394 uint8_t ctx[ hmac_ctxsize ( digest ) ];
3395
3396 tls_hmac_init ( cipherspec, ctx, authhdr );
3397 tls_hmac_update ( cipherspec, ctx, data, len );
3398 tls_hmac_final ( cipherspec, ctx, hmac );
3399}
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition tls.c:3343
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition tls.c:3374
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition tls.c:3360

References ctx, data, tls_cipher_suite::digest, hmac_ctxsize(), len, tls_cipherspec::suite, tls_hmac_final(), tls_hmac_init(), and tls_hmac_update().

Referenced by tls_send_record().

◆ tls_hmac_list()

void tls_hmac_list ( struct tls_cipherspec * cipherspec,
struct tls_auth_header * authhdr,
struct list_head * list,
void * hmac )
static

Calculate HMAC over list of I/O buffers.

Parameters
cipherspecCipher specification
authhdrAuthentication header
listList of I/O buffers
macHMAC to fill in

Definition at line 3409 of file tls.c.

3411 {
3412 struct digest_algorithm *digest = cipherspec->suite->digest;
3413 uint8_t ctx[ hmac_ctxsize ( digest ) ];
3414 struct io_buffer *iobuf;
3415
3416 tls_hmac_init ( cipherspec, ctx, authhdr );
3417 list_for_each_entry ( iobuf, list, list ) {
3418 tls_hmac_update ( cipherspec, ctx, iobuf->data,
3419 iob_len ( iobuf ) );
3420 }
3421 tls_hmac_final ( cipherspec, ctx, hmac );
3422}

References ctx, io_buffer::data, tls_cipher_suite::digest, hmac_ctxsize(), iob_len(), io_buffer::list, list_for_each_entry, tls_cipherspec::suite, tls_hmac_final(), tls_hmac_init(), and tls_hmac_update().

Referenced by tls_new_ciphertext().

◆ tls_iob_reserved()

size_t tls_iob_reserved ( struct tls_connection * tls,
size_t len )
static

Calculate maximum additional length required for transmitted record(s).

Parameters
tlsTLS connection
lenI/O buffer payload length
Return values
reserveMaximum additional length to reserve

Definition at line 3431 of file tls.c.

3431 {
3432 struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.active;
3433 struct tls_cipher_suite *suite = cipherspec->suite;
3434 struct cipher_algorithm *cipher = suite->cipher;
3435 struct tls_header *tlshdr;
3436 unsigned int count;
3437 size_t each;
3438
3439 /* Calculate number of records (allowing for zero-length records) */
3440 count = ( len ? ( ( len + TLS_TX_BUFSIZE - 1 ) / TLS_TX_BUFSIZE ) : 1 );
3441
3442 /* Calculate maximum additional length per record */
3443 each = ( sizeof ( *tlshdr ) + suite->record_iv_len + suite->mac_len +
3444 ( is_block_cipher ( cipher ) ? cipher->blocksize : 0 ) +
3445 cipher->authsize );
3446
3447 /* Calculate maximum total additional length */
3448 return ( count * each );
3449}
static unsigned int count
Number of entries.
Definition dwmac.h:220

References tls_cipherspec_pair::active, cipher_algorithm::authsize, cipher_algorithm::blocksize, tls_cipher_suite::cipher, tls_tx::cipherspec, count, is_block_cipher(), len, tls_cipher_suite::mac_len, tls_cipher_suite::record_iv_len, tls_cipherspec::suite, TLS_TX_BUFSIZE, and tls_connection::tx.

Referenced by tls_alloc_iob(), and tls_send_record().

◆ tls_verify_padding()

int tls_verify_padding ( struct tls_connection * tls,
struct io_buffer * iobuf )
static

Verify block padding.

Parameters
tlsTLS connection
iobufLast received I/O buffer
Return values
lenPadding length, or negative error
rcReturn status code

Definition at line 3658 of file tls.c.

3659 {
3660 uint8_t *padding;
3661 unsigned int pad;
3662 unsigned int i;
3663 size_t len;
3664
3665 /* Extract and verify padding */
3666 padding = ( iobuf->tail - 1 );
3667 pad = *padding;
3668 len = ( pad + 1 );
3669 if ( len > iob_len ( iobuf ) ) {
3670 DBGC ( tls, "TLS %p received underlength padding\n", tls );
3671 DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3672 return -EINVAL_PADDING;
3673 }
3674 for ( i = 0 ; i < pad ; i++ ) {
3675 if ( *(--padding) != pad ) {
3676 DBGC ( tls, "TLS %p received bad padding\n", tls );
3677 DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3678 return -EINVAL_PADDING;
3679 }
3680 }
3681
3682 return len;
3683}
u32 pad[9]
Padding.
Definition ar9003_mac.h:23
void * tail
End of data.
Definition iobuf.h:115
#define EINVAL_PADDING
Definition tls.c:95

References io_buffer::data, DBGC, DBGC_HD, EINVAL_PADDING, iob_len(), len, pad, and io_buffer::tail.

Referenced by tls_new_ciphertext().

◆ tls_new_ciphertext()

int tls_new_ciphertext ( struct tls_connection * tls,
struct tls_header * tlshdr,
struct list_head * rx_data )
static

Receive new ciphertext record.

Parameters
tlsTLS connection
tlshdrRecord header
rx_dataList of received data buffers
Return values
rcReturn status code

Definition at line 3693 of file tls.c.

3695 {
3696 struct tls_cipherspec *cipherspec = &tls->rx.cipherspec.active;
3697 struct tls_cipher_suite *suite = cipherspec->suite;
3698 struct cipher_algorithm *cipher = suite->cipher;
3699 struct digest_algorithm *digest = suite->digest;
3700 size_t len = ntohs ( tlshdr->length );
3701 struct {
3702 uint8_t fixed[suite->fixed_iv_len];
3703 uint8_t record[suite->record_iv_len];
3704 } __attribute__ (( packed )) iv;
3705 struct tls_auth_header authhdr;
3706 uint8_t verify_mac[digest->digestsize];
3707 uint8_t verify_auth[cipher->authsize];
3708 struct io_buffer *first;
3709 struct io_buffer *last;
3710 struct io_buffer *iobuf;
3711 void *mac;
3712 void *auth;
3713 size_t check_len;
3714 int pad_len;
3715 int rc;
3716
3717 /* Locate first and last data buffers */
3718 assert ( ! list_empty ( rx_data ) );
3719 first = list_first_entry ( rx_data, struct io_buffer, list );
3720 last = list_last_entry ( rx_data, struct io_buffer, list );
3721
3722 /* Extract initialisation vector */
3723 if ( iob_len ( first ) < sizeof ( iv.record ) ) {
3724 DBGC ( tls, "TLS %p received underlength IV\n", tls );
3725 DBGC_HD ( tls, first->data, iob_len ( first ) );
3726 return -EINVAL_IV;
3727 }
3728 memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
3729 memcpy ( iv.record, first->data, sizeof ( iv.record ) );
3730 iob_pull ( first, sizeof ( iv.record ) );
3731 len -= sizeof ( iv.record );
3732
3733 /* Extract unencrypted authentication tag */
3734 if ( iob_len ( last ) < cipher->authsize ) {
3735 DBGC ( tls, "TLS %p received underlength authentication tag\n",
3736 tls );
3737 DBGC_HD ( tls, last->data, iob_len ( last ) );
3738 return -EINVAL_MAC;
3739 }
3740 iob_unput ( last, cipher->authsize );
3741 len -= cipher->authsize;
3742 auth = last->tail;
3743
3744 /* Construct authentication data */
3745 authhdr.seq = cpu_to_be64 ( tls->rx.seq );
3746 authhdr.header.type = tlshdr->type;
3747 authhdr.header.version = tlshdr->version;
3748 authhdr.header.length = htons ( len );
3749
3750 /* Set initialisation vector */
3751 if ( ( rc = cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv,
3752 sizeof ( iv ) ) ) != 0 ) {
3753 DBGC ( tls, "TLS %p could not set RX IV: %s\n",
3754 tls, strerror ( rc ) );
3755 return rc;
3756 }
3757
3758 /* Process authentication data, if applicable */
3759 if ( is_auth_cipher ( cipher ) ) {
3760 cipher_decrypt ( cipher, cipherspec->cipher_ctx, &authhdr,
3761 NULL, sizeof ( authhdr ) );
3762 }
3763
3764 /* Decrypt the received data */
3765 check_len = 0;
3766 list_for_each_entry ( iobuf, &tls->rx.data, list ) {
3767 cipher_decrypt ( cipher, cipherspec->cipher_ctx,
3768 iobuf->data, iobuf->data, iob_len ( iobuf ) );
3769 check_len += iob_len ( iobuf );
3770 }
3771 assert ( check_len == len );
3772
3773 /* Strip block padding, if applicable */
3774 if ( is_block_cipher ( cipher ) ) {
3775 pad_len = tls_verify_padding ( tls, last );
3776 if ( pad_len < 0 ) {
3777 /* Assume zero padding length to avoid timing attacks */
3778 pad_len = 0;
3779 }
3780 iob_unput ( last, pad_len );
3781 len -= pad_len;
3782 }
3783
3784 /* Extract decrypted MAC */
3785 if ( iob_len ( last ) < suite->mac_len ) {
3786 DBGC ( tls, "TLS %p received underlength MAC\n", tls );
3787 DBGC_HD ( tls, last->data, iob_len ( last ) );
3788 return -EINVAL_MAC;
3789 }
3790 iob_unput ( last, suite->mac_len );
3791 len -= suite->mac_len;
3792 mac = last->tail;
3793
3794 /* Dump received data */
3795 DBGC2 ( tls, "Received plaintext data:\n" );
3796 check_len = 0;
3797 list_for_each_entry ( iobuf, rx_data, list ) {
3798 DBGC2_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3799 check_len += iob_len ( iobuf );
3800 }
3801 assert ( check_len == len );
3802
3803 /* Generate MAC */
3804 authhdr.header.length = htons ( len );
3805 if ( suite->mac_len )
3806 tls_hmac_list ( cipherspec, &authhdr, rx_data, verify_mac );
3807
3808 /* Generate authentication tag */
3809 cipher_auth ( cipher, cipherspec->cipher_ctx, verify_auth );
3810
3811 /* Verify MAC */
3812 if ( memcmp ( mac, verify_mac, suite->mac_len ) != 0 ) {
3813 DBGC ( tls, "TLS %p failed MAC verification\n", tls );
3814 return -EINVAL_MAC;
3815 }
3816
3817 /* Verify authentication tag */
3818 if ( memcmp ( auth, verify_auth, cipher->authsize ) != 0 ) {
3819 DBGC ( tls, "TLS %p failed authentication tag verification\n",
3820 tls );
3821 return -EINVAL_MAC;
3822 }
3823
3824 /* Process plaintext record */
3825 if ( ( rc = tls_new_record ( tls, tlshdr->type, rx_data ) ) != 0 )
3826 return rc;
3827
3828 return 0;
3829}
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition crypto.h:336
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition list.h:347
uint32_t first
First block in range.
Definition pccrr.h:1
#define EINVAL_IV
Definition tls.c:91
static void tls_hmac_list(struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, struct list_head *list, void *hmac)
Calculate HMAC over list of I/O buffers.
Definition tls.c:3409
#define EINVAL_MAC
Definition tls.c:103
static int tls_verify_padding(struct tls_connection *tls, struct io_buffer *iobuf)
Verify block padding.
Definition tls.c:3658
static int tls_new_record(struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
Receive new record.
Definition tls.c:3265

References __attribute__, tls_cipherspec_pair::active, assert, cipher_algorithm::authsize, tls_cipher_suite::cipher, cipher_auth(), tls_cipherspec::cipher_ctx, cipher_decrypt, cipher_setiv(), tls_rx::cipherspec, cpu_to_be64, io_buffer::data, tls_rx::data, DBGC, DBGC2, DBGC2_HD, DBGC_HD, tls_cipher_suite::digest, digest_algorithm::digestsize, EINVAL_IV, EINVAL_MAC, first, fixed, tls_cipherspec::fixed_iv, tls_cipher_suite::fixed_iv_len, tls_auth_header::header, htons, iob_len(), iob_pull, iob_unput, is_auth_cipher(), is_block_cipher(), iv, len, tls_header::length, io_buffer::list, list_empty, list_first_entry, list_for_each_entry, list_last_entry, mac, tls_cipher_suite::mac_len, memcmp(), memcpy(), ntohs, NULL, rc, tls_cipher_suite::record_iv_len, tls_connection::rx, tls_auth_header::seq, tls_rx::seq, strerror(), tls_cipherspec::suite, io_buffer::tail, tls_hmac_list(), tls_new_record(), tls_verify_padding(), tls_header::type, and tls_header::version.

Referenced by tls_newdata_process_data().

◆ tls_plainstream_window()

size_t tls_plainstream_window ( struct tls_connection * tls)
static

Check flow control window.

Parameters
tlsTLS connection
Return values
lenLength of window

Definition at line 3844 of file tls.c.

3844 {
3845
3846 /* Block window unless we are ready to accept data */
3847 if ( ! tls_ready ( tls ) )
3848 return 0;
3849
3850 return xfer_window ( &tls->cipherstream );
3851}
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

References tls_connection::cipherstream, tls_ready(), and xfer_window().

◆ tls_plainstream_deliver()

int tls_plainstream_deliver ( struct tls_connection * tls,
struct io_buffer * iobuf,
struct xfer_metadata *meta __unused )
static

Deliver datagram as raw data.

Parameters
tlsTLS connection
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 3861 of file tls.c.

3863 {
3864 int rc;
3865
3866 /* Refuse unless we are ready to accept data */
3867 if ( ! tls_ready ( tls ) ) {
3868 rc = -ENOTCONN;
3869 goto done;
3870 }
3871
3872 /* Send data record */
3873 if ( ( rc = tls_send_record ( tls, TLS_TYPE_DATA,
3874 iob_disown ( iobuf ) ) ) != 0 )
3875 goto done;
3876
3877 done:
3878 free_iob ( iobuf );
3879 return rc;
3880}
struct bofm_section_header done
Definition bofm_test.c:46

References __unused, done, ENOTCONN, free_iob(), iob_disown, meta, rc, tls_ready(), tls_send_record(), and TLS_TYPE_DATA.

◆ tls_progress()

int tls_progress ( struct tls_connection * tls,
struct job_progress * progress )
static

Report job progress.

Parameters
tlsTLS connection
progressProgress report to fill in
Return values
ongoing_rcOngoing job status code (if known)

Definition at line 3889 of file tls.c.

3890 {
3891
3892 /* Return cipherstream or validator progress as applicable */
3893 if ( is_pending ( &tls->server.validation ) ) {
3894 return job_progress ( &tls->server.validator, progress );
3895 } else {
3896 return job_progress ( &tls->cipherstream, progress );
3897 }
3898}
int job_progress(struct interface *intf, struct job_progress *progress)
Get job progress.
Definition job.c:44

References tls_connection::cipherstream, is_pending(), job_progress(), tls_connection::server, tls_server::validation, and tls_server::validator.

◆ tls_newdata_process_header()

int tls_newdata_process_header ( struct tls_connection * tls)
static

Handle received TLS header.

Parameters
tlsTLS connection
Return values
rcReturned status code

Definition at line 3929 of file tls.c.

3929 {
3930 struct tls_cipherspec *cipherspec = &tls->rx.cipherspec.active;
3931 struct cipher_algorithm *cipher = cipherspec->suite->cipher;
3932 size_t iv_len = cipherspec->suite->record_iv_len;
3933 size_t data_len = ntohs ( tls->rx.header.length );
3934 size_t remaining = data_len;
3935 size_t frag_len;
3936 size_t reserve;
3937 struct io_buffer *iobuf;
3938 struct io_buffer *tmp;
3939 int rc;
3940
3941 /* Sanity check */
3942 assert ( ( TLS_RX_BUFSIZE % cipher->alignsize ) == 0 );
3943
3944 /* Calculate alignment reservation at start of first data buffer */
3945 reserve = ( ( -iv_len ) & ( cipher->alignsize - 1 ) );
3946 remaining += reserve;
3947
3948 /* Allocate data buffers now that we know the length */
3949 assert ( list_empty ( &tls->rx.data ) );
3950 while ( remaining ) {
3951
3952 /* Calculate fragment length. Ensure that no block is
3953 * smaller than TLS_RX_MIN_BUFSIZE (by increasing the
3954 * allocation length if necessary).
3955 */
3956 frag_len = remaining;
3957 if ( frag_len > TLS_RX_BUFSIZE )
3958 frag_len = TLS_RX_BUFSIZE;
3959 remaining -= frag_len;
3960 if ( remaining < TLS_RX_MIN_BUFSIZE ) {
3961 frag_len += remaining;
3962 remaining = 0;
3963 }
3964
3965 /* Allocate buffer */
3966 iobuf = alloc_iob_raw ( frag_len, TLS_RX_ALIGN, 0 );
3967 if ( ! iobuf ) {
3968 DBGC ( tls, "TLS %p could not allocate %zd of %zd "
3969 "bytes for receive buffer\n", tls,
3970 remaining, data_len );
3971 rc = -ENOMEM_RX_DATA;
3972 goto err;
3973 }
3974
3975 /* Ensure tailroom is exactly what we asked for. This
3976 * will result in unaligned I/O buffers when the
3977 * fragment length is unaligned, which can happen only
3978 * before we switch to using a block cipher.
3979 */
3980 iob_reserve ( iobuf, ( iob_tailroom ( iobuf ) - frag_len ) );
3981
3982 /* Ensure first buffer length will be aligned to a
3983 * multiple of the cipher alignment size after
3984 * stripping the record IV.
3985 */
3986 iob_reserve ( iobuf, reserve );
3987 reserve = 0;
3988
3989 /* Add I/O buffer to list */
3990 list_add_tail ( &iobuf->list, &tls->rx.data );
3991 }
3992
3993 /* Move to data state */
3994 tls->rx.state = TLS_RX_DATA;
3995
3996 return 0;
3997
3998 err:
3999 list_for_each_entry_safe ( iobuf, tmp, &tls->rx.data, list ) {
4000 list_del ( &iobuf->list );
4001 free_iob ( iobuf );
4002 }
4003 return rc;
4004}
struct io_buffer * alloc_iob_raw(size_t len, size_t align, size_t offset)
Allocate I/O buffer with specified alignment and offset.
Definition iobuf.c:49
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition iobuf.h:240
size_t alignsize
Alignment size.
Definition crypto.h:80
enum tls_rx_state state
State machine current state.
Definition tls.h:487
struct tls_header header
Current received record header.
Definition tls.h:489
#define ENOMEM_RX_DATA
Definition tls.c:143
#define TLS_RX_MIN_BUFSIZE
Minimum RX I/O buffer size.
Definition tls.h:597
#define TLS_RX_ALIGN
RX I/O buffer alignment.
Definition tls.h:600
@ TLS_RX_DATA
Definition tls.h:182
#define TLS_RX_BUFSIZE
RX I/O buffer size.
Definition tls.h:589
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes).
Definition ucode.h:15

References tls_cipherspec_pair::active, cipher_algorithm::alignsize, alloc_iob_raw(), assert, tls_cipher_suite::cipher, tls_rx::cipherspec, tls_rx::data, data_len, DBGC, ENOMEM_RX_DATA, free_iob(), tls_rx::header, iob_reserve, iob_tailroom(), tls_header::length, io_buffer::list, list_add_tail, list_del, list_empty, list_for_each_entry_safe, ntohs, rc, tls_cipher_suite::record_iv_len, tls_connection::rx, tls_rx::state, tls_cipherspec::suite, TLS_RX_ALIGN, TLS_RX_BUFSIZE, TLS_RX_DATA, TLS_RX_MIN_BUFSIZE, and tmp.

Referenced by tls_cipherstream_deliver().

◆ tls_newdata_process_data()

int tls_newdata_process_data ( struct tls_connection * tls)
static

Handle received TLS data payload.

Parameters
tlsTLS connection
Return values
rcReturned status code

Definition at line 4012 of file tls.c.

4012 {
4013 struct io_buffer *iobuf;
4014 int rc;
4015
4016 /* Move current buffer to end of list */
4017 iobuf = list_first_entry ( &tls->rx.data, struct io_buffer, list );
4018 list_del ( &iobuf->list );
4019 list_add_tail ( &iobuf->list, &tls->rx.data );
4020
4021 /* Continue receiving data if any space remains */
4022 iobuf = list_first_entry ( &tls->rx.data, struct io_buffer, list );
4023 if ( iob_tailroom ( iobuf ) )
4024 return 0;
4025
4026 /* Process record */
4027 if ( ( rc = tls_new_ciphertext ( tls, &tls->rx.header,
4028 &tls->rx.data ) ) != 0 )
4029 return rc;
4030
4031 /* Increment RX sequence number */
4032 tls->rx.seq += 1;
4033
4034 /* Return to header state */
4035 assert ( list_empty ( &tls->rx.data ) );
4036 tls->rx.state = TLS_RX_HEADER;
4037 iob_unput ( &tls->rx.iobuf, sizeof ( tls->rx.header ) );
4038
4039 return 0;
4040}
struct io_buffer iobuf
Current received record header (static I/O buffer).
Definition tls.h:491
static int tls_new_ciphertext(struct tls_connection *tls, struct tls_header *tlshdr, struct list_head *rx_data)
Receive new ciphertext record.
Definition tls.c:3693
@ TLS_RX_HEADER
Definition tls.h:181

References assert, tls_rx::data, tls_rx::header, iob_tailroom(), iob_unput, tls_rx::iobuf, io_buffer::list, list_add_tail, list_del, list_empty, list_first_entry, rc, tls_connection::rx, tls_rx::seq, tls_rx::state, tls_new_ciphertext(), and TLS_RX_HEADER.

Referenced by tls_cipherstream_deliver().

◆ tls_cipherstream_window()

size_t tls_cipherstream_window ( struct tls_connection * tls)
static

Check flow control window.

Parameters
tlsTLS connection
Return values
lenLength of window

Definition at line 4048 of file tls.c.

4048 {
4049
4050 /* Open window until we are ready to accept data */
4051 if ( ! tls_ready ( tls ) )
4052 return -1UL;
4053
4054 return xfer_window ( &tls->plainstream );
4055}

References tls_connection::plainstream, tls_ready(), and xfer_window().

◆ tls_cipherstream_deliver()

int tls_cipherstream_deliver ( struct tls_connection * tls,
struct io_buffer * iobuf,
struct xfer_metadata *xfer __unused )
static

Receive new ciphertext.

Parameters
tlsTLS connection
iobufI/O buffer
metaData transfer metadat
Return values
rcReturn status code

Definition at line 4065 of file tls.c.

4067 {
4068 size_t frag_len;
4069 int ( * process ) ( struct tls_connection *tls );
4070 struct io_buffer *dest;
4071 int rc;
4072
4073 while ( iob_len ( iobuf ) ) {
4074
4075 /* Select buffer according to current state */
4076 switch ( tls->rx.state ) {
4077 case TLS_RX_HEADER:
4078 dest = &tls->rx.iobuf;
4080 break;
4081 case TLS_RX_DATA:
4082 dest = list_first_entry ( &tls->rx.data,
4083 struct io_buffer, list );
4084 assert ( dest != NULL );
4086 break;
4087 default:
4088 assert ( 0 );
4090 goto done;
4091 }
4092
4093 /* Copy data portion to buffer */
4094 frag_len = iob_len ( iobuf );
4095 if ( frag_len > iob_tailroom ( dest ) )
4096 frag_len = iob_tailroom ( dest );
4097 memcpy ( iob_put ( dest, frag_len ), iobuf->data, frag_len );
4098 iob_pull ( iobuf, frag_len );
4099
4100 /* Process data if buffer is now full */
4101 if ( iob_tailroom ( dest ) == 0 ) {
4102 if ( ( rc = process ( tls ) ) != 0 ) {
4103 tls_close_alert ( tls, rc );
4104 goto done;
4105 }
4106 }
4107 }
4108 rc = 0;
4109
4110 done:
4111 free_iob ( iobuf );
4112 return rc;
4113}
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
A process.
Definition process.h:18
#define EINVAL_RX_STATE
Definition tls.c:99
static int tls_newdata_process_data(struct tls_connection *tls)
Handle received TLS data payload.
Definition tls.c:4012
static int tls_newdata_process_header(struct tls_connection *tls)
Handle received TLS header.
Definition tls.c:3929
static void tls_close_alert(struct tls_connection *tls, int rc)
Send closure alert and finish with TLS connection.
Definition tls.c:403

References __unused, assert, io_buffer::data, tls_rx::data, dest, done, EINVAL_RX_STATE, free_iob(), iob_len(), iob_pull, iob_put, iob_tailroom(), tls_rx::iobuf, io_buffer::list, list_first_entry, memcpy(), NULL, rc, tls_connection::rx, tls_rx::state, tls_close_alert(), tls_newdata_process_data(), tls_newdata_process_header(), TLS_RX_DATA, and TLS_RX_HEADER.

◆ tls_validator_done()

void tls_validator_done ( struct tls_connection * tls,
int rc )
static

Handle certificate validation completion.

Parameters
tlsTLS connection
rcReason for completion

Definition at line 4144 of file tls.c.

4144 {
4145
4146 /* Mark validation as complete */
4147 pending_put ( &tls->server.validation );
4148
4149 /* Close validator interface */
4150 intf_restart ( &tls->server.validator, rc );
4151
4152 /* Check for validation failure */
4153 if ( rc != 0 ) {
4154 DBGC ( tls, "TLS %p certificate validation failed: %s\n",
4155 tls, strerror ( rc ) );
4156 goto err;
4157 }
4158 DBGC ( tls, "TLS %p certificate validation succeeded\n", tls );
4159
4160 /* Schedule transmission of applicable handshake messages */
4164 if ( tls->client.chain ) {
4166 if ( ! list_empty ( &tls->client.chain->links ) )
4168 }
4169 tls_tx_resume ( tls );
4170
4171 return;
4172
4173 err:
4174 tls_close_alert ( tls, rc );
4175 return;
4176}
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
@ TLS_TX_CLIENT_KEY_EXCHANGE
Definition tls.h:189
@ TLS_TX_CERTIFICATE_VERIFY
Definition tls.h:190
@ TLS_TX_CERTIFICATE
Definition tls.h:188

References tls_client::chain, tls_connection::client, DBGC, intf_restart(), x509_chain::links, list_empty, tls_tx::pending, pending_put(), rc, tls_connection::server, strerror(), tls_close_alert(), TLS_TX_CERTIFICATE, TLS_TX_CERTIFICATE_VERIFY, TLS_TX_CHANGE_CIPHER, TLS_TX_CLIENT_KEY_EXCHANGE, TLS_TX_FINISHED, tls_tx_resume(), tls_connection::tx, tls_server::validation, and tls_server::validator.

◆ tls_tx_step()

void tls_tx_step ( struct tls_connection * tls)
static

TLS TX state machine.

Parameters
tlsTLS connection

Definition at line 4200 of file tls.c.

4200 {
4201 struct tls_session *session = tls->session;
4202 struct tls_connection *conn;
4203 int rc;
4204
4205 /* Wait for cipherstream to become ready */
4206 if ( ! xfer_window ( &tls->cipherstream ) )
4207 return;
4208
4209 /* Send first pending transmission */
4210 if ( tls->tx.pending & TLS_TX_CLIENT_HELLO ) {
4211 /* Serialise server negotiations within a session, to
4212 * provide a consistent view of session IDs and
4213 * session tickets.
4214 */
4215 list_for_each_entry ( conn, &session->conn, list ) {
4216 if ( conn == tls )
4217 break;
4218 if ( is_pending ( &conn->server.negotiation ) )
4219 return;
4220 }
4221 /* Record or generate session ID and associated master secret */
4222 if ( session->id_len ) {
4223 /* Attempt to resume an existing session */
4224 memcpy ( tls->session_id, session->id,
4225 sizeof ( tls->session_id ) );
4227 } else {
4228 /* No existing session: use a random session ID */
4229 assert ( sizeof ( tls->session_id ) ==
4230 sizeof ( tls->client.random ) );
4231 memcpy ( tls->session_id, &tls->client.random,
4232 sizeof ( tls->session_id ) );
4233 tls->session_id_len = sizeof ( tls->session_id );
4234 }
4235 /* Send Client Hello */
4236 if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
4237 DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
4238 tls, strerror ( rc ) );
4239 goto err;
4240 }
4242 } else if ( tls->tx.pending & TLS_TX_CERTIFICATE ) {
4243 /* Send Certificate */
4244 if ( ( rc = tls_send_certificate ( tls ) ) != 0 ) {
4245 DBGC ( tls, "TLS %p cold not send Certificate: %s\n",
4246 tls, strerror ( rc ) );
4247 goto err;
4248 }
4250 } else if ( tls->tx.pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
4251 /* Send Client Key Exchange */
4252 if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
4253 DBGC ( tls, "TLS %p could not send Client Key "
4254 "Exchange: %s\n", tls, strerror ( rc ) );
4255 goto err;
4256 }
4258 } else if ( tls->tx.pending & TLS_TX_CERTIFICATE_VERIFY ) {
4259 /* Send Certificate Verify */
4260 if ( ( rc = tls_send_certificate_verify ( tls ) ) != 0 ) {
4261 DBGC ( tls, "TLS %p could not send Certificate "
4262 "Verify: %s\n", tls, strerror ( rc ) );
4263 goto err;
4264 }
4266 } else if ( tls->tx.pending & TLS_TX_CHANGE_CIPHER ) {
4267 /* Send Change Cipher, and then change the cipher in use */
4268 if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
4269 DBGC ( tls, "TLS %p could not send Change Cipher: "
4270 "%s\n", tls, strerror ( rc ) );
4271 goto err;
4272 }
4273 if ( ( rc = tls_change_cipher ( tls,
4274 &tls->tx.cipherspec ) ) != 0 ){
4275 DBGC ( tls, "TLS %p could not activate TX cipher: "
4276 "%s\n", tls, strerror ( rc ) );
4277 goto err;
4278 }
4279 tls->tx.seq = 0;
4281 } else if ( tls->tx.pending & TLS_TX_FINISHED ) {
4282 /* Send Finished */
4283 if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
4284 DBGC ( tls, "TLS %p could not send Finished: %s\n",
4285 tls, strerror ( rc ) );
4286 goto err;
4287 }
4288 tls->tx.pending &= ~TLS_TX_FINISHED;
4289 }
4290
4291 /* Reschedule process if pending transmissions remain,
4292 * otherwise send notification of a window change.
4293 */
4294 if ( tls->tx.pending ) {
4295 tls_tx_resume ( tls );
4296 } else {
4298 }
4299
4300 return;
4301
4302 err:
4303 tls_close_alert ( tls, rc );
4304}
static int tls_send_certificate(struct tls_connection *tls)
Transmit Certificate record.
Definition tls.c:2157
static int tls_send_finished(struct tls_connection *tls)
Transmit Finished record.
Definition tls.c:2343
static int tls_send_client_hello(struct tls_connection *tls)
Transmit Client Hello record.
Definition tls.c:2146
static int tls_send_client_key_exchange(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition tls.c:2214
static int tls_send_change_cipher(struct tls_connection *tls)
Transmit Change Cipher record.
Definition tls.c:2326
static int tls_send_certificate_verify(struct tls_connection *tls)
Transmit Certificate Verify record.
Definition tls.c:2245

References assert, tls_tx::cipherspec, tls_connection::cipherstream, tls_connection::client, tls_session::conn, DBGC, tls_session::id, tls_session::id_len, is_pending(), tls_connection::list, list_for_each_entry, memcpy(), tls_server::negotiation, tls_tx::pending, tls_connection::plainstream, tls_client::random, rc, tls_tx::seq, tls_connection::server, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, strerror(), tls_change_cipher(), tls_close_alert(), tls_send_certificate(), tls_send_certificate_verify(), tls_send_change_cipher(), tls_send_client_hello(), tls_send_client_key_exchange(), tls_send_finished(), TLS_TX_CERTIFICATE, TLS_TX_CERTIFICATE_VERIFY, TLS_TX_CHANGE_CIPHER, TLS_TX_CLIENT_HELLO, TLS_TX_CLIENT_KEY_EXCHANGE, TLS_TX_FINISHED, tls_tx_resume(), tls_connection::tx, xfer_window(), and xfer_window_changed().

◆ tls_session()

int tls_session ( struct tls_connection * tls,
const char * name )
static

Find or create session for TLS connection.

Parameters
tlsTLS connection
nameServer name
Return values
rcReturn status code

Definition at line 4324 of file tls.c.

4324 {
4325 struct tls_session *session;
4326 char *name_copy;
4327 int rc;
4328
4329 /* Find existing matching session, if any */
4330 list_for_each_entry ( session, &tls_sessions, list ) {
4331 if ( ( strcmp ( name, session->name ) == 0 ) &&
4332 ( tls->server.root == session->root ) &&
4333 ( tls->client.key == session->key ) ) {
4334 ref_get ( &session->refcnt );
4335 tls->session = session;
4336 DBGC ( tls, "TLS %p joining session %s\n", tls, name );
4337 return 0;
4338 }
4339 }
4340
4341 /* Create new session */
4342 session = zalloc ( sizeof ( *session ) + strlen ( name )
4343 + 1 /* NUL */ );
4344 if ( ! session ) {
4345 rc = -ENOMEM;
4346 goto err_alloc;
4347 }
4348 ref_init ( &session->refcnt, free_tls_session );
4349 name_copy = ( ( ( void * ) session ) + sizeof ( *session ) );
4350 strcpy ( name_copy, name );
4351 session->name = name_copy;
4352 session->root = x509_root_get ( tls->server.root );
4353 session->key = privkey_get ( tls->client.key );
4354 INIT_LIST_HEAD ( &session->conn );
4355 list_add ( &session->list, &tls_sessions );
4356
4357 /* Poison resumption master secret */
4358 tls_ephemeral_label ( tls, "res poison",
4359 session->resumption_master_secret,
4360 sizeof ( session->resumption_master_secret ) );
4361
4362 /* Record session */
4363 tls->session = session;
4364
4365 DBGC ( tls, "TLS %p created session %s\n", tls, name );
4366 return 0;
4367
4368 ref_put ( &session->refcnt );
4369 err_alloc:
4370 return rc;
4371}
const char * name
Definition ath9k_hw.c:1986
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
Definition privkey.h:31
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
char * strcpy(char *dest, const char *src)
Copy string.
Definition string.c:378
static void free_tls_session(struct refcnt *refcnt)
Free TLS session.
Definition tls.c:308
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition x509.h:393

References tls_connection::client, tls_session::conn, DBGC, ENOMEM, free_tls_session(), INIT_LIST_HEAD, tls_client::key, tls_session::key, tls_session::list, list_add, list_for_each_entry, name, tls_session::name, privkey_get(), rc, ref_get, ref_init, ref_put, tls_session::refcnt, tls_session::resumption_master_secret, tls_server::root, tls_session::root, tls_connection::server, tls_connection::session, strcmp(), strcpy(), strlen(), tls_ephemeral_label(), x509_root_get(), and zalloc().

◆ add_tls()

int add_tls ( struct interface * xfer,
const char * name,
struct x509_root * root,
struct private_key * key )

Add TLS on an interface.

Parameters
xferData transfer interface
nameHost name
rootRoot of trust (or NULL to use default)
keyPrivate key (or NULL to use default)
Return values
rcReturn status code

Definition at line 4389 of file tls.c.

4390 {
4391 struct tls_connection *tls;
4392 int rc;
4393
4394 /* Allocate and initialise TLS structure */
4395 tls = malloc ( sizeof ( *tls ) );
4396 if ( ! tls ) {
4397 rc = -ENOMEM;
4398 goto err_alloc;
4399 }
4400 memset ( tls, 0, sizeof ( *tls ) );
4401 ref_init ( &tls->refcnt, free_tls );
4402 INIT_LIST_HEAD ( &tls->list );
4407 &tls->refcnt );
4408 tls->client.key = privkey_get ( key ? key : &private_key );
4410 tls->version = TLS_VERSION_MAX;
4411 tls_clear_cipher ( tls, &tls->tx.cipherspec.active );
4412 tls_clear_cipher ( tls, &tls->tx.cipherspec.pending );
4413 tls_clear_cipher ( tls, &tls->rx.cipherspec.active );
4414 tls_clear_cipher ( tls, &tls->rx.cipherspec.pending );
4415 tls_clear_digest ( tls );
4416 iob_populate ( &tls->rx.iobuf, &tls->rx.header, 0,
4417 sizeof ( tls->rx.header ) );
4418 INIT_LIST_HEAD ( &tls->rx.data );
4419 if ( ( rc = tls_generate_ephemeral_master ( tls ) ) != 0 )
4420 goto err_ephemeral;
4421 if ( ( rc = tls_session ( tls, name ) ) != 0 )
4422 goto err_session;
4423 list_add_tail ( &tls->list, &tls->session->conn );
4424
4425 /* Start negotiation */
4426 tls_restart ( tls );
4427
4428 /* Attach to parent interface, mortalise self, and return */
4429 intf_insert ( xfer, &tls->plainstream, &tls->cipherstream );
4430 ref_put ( &tls->refcnt );
4431 return 0;
4432
4433 err_session:
4434 err_ephemeral:
4435 ref_put ( &tls->refcnt );
4436 err_alloc:
4437 return rc;
4438}
void intf_insert(struct interface *intf, struct interface *upper, struct interface *lower)
Insert a filter interface.
Definition interface.c:402
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
static void iob_populate(struct io_buffer *iobuf, void *data, size_t len, size_t max_len)
Create a temporary I/O buffer.
Definition iobuf.h:255
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition process.h:146
struct x509_root root_certificates
Root certificates.
Definition rootcert.c:79
struct stp_switch root
Root switch.
Definition stp.h:15
A private key.
Definition privkey.h:17
struct refcnt refcnt
Reference counter.
Definition tls.h:529
static struct interface_descriptor tls_cipherstream_desc
TLS ciphertext stream interface descriptor.
Definition tls.c:4127
static struct interface_descriptor tls_validator_desc
TLS certificate validator interface descriptor.
Definition tls.c:4184
static struct interface_descriptor tls_plainstream_desc
TLS plaintext stream interface descriptor.
Definition tls.c:3912
static void free_tls(struct refcnt *refcnt)
Free TLS connection.
Definition tls.c:333
static int tls_generate_ephemeral_master(struct tls_connection *tls)
Generate ephemeral master secret.
Definition tls.c:425
static struct process_descriptor tls_process_desc
TLS TX process descriptor.
Definition tls.c:4307

References tls_cipherspec_pair::active, tls_rx::cipherspec, tls_tx::cipherspec, tls_connection::cipherstream, tls_connection::client, tls_session::conn, tls_rx::data, ENOMEM, free_tls(), tls_rx::header, INIT_LIST_HEAD, intf_init(), intf_insert(), iob_populate(), tls_rx::iobuf, key, tls_client::key, tls_connection::list, list_add_tail, malloc(), memset(), name, tls_cipherspec_pair::pending, tls_connection::plainstream, privkey_get(), tls_tx::process, process_init_stopped(), rc, ref_init, ref_put, tls_connection::refcnt, root, tls_server::root, root_certificates, tls_connection::rx, tls_connection::server, tls_connection::session, tls_cipherstream_desc, tls_clear_cipher(), tls_clear_digest(), tls_generate_ephemeral_master(), tls_plainstream_desc, tls_process_desc, tls_restart(), tls_validator_desc, TLS_VERSION_MAX, tls_connection::tx, tls_server::validator, tls_connection::version, and x509_root_get().

Referenced by apply_syslogs_settings(), https_filter(), ipair_rx_session(), and REQUIRING_SYMBOL().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( add_tls )

References add_tls().

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_crypto )

Variable Documentation

◆ tls_cipher_suite_null

struct tls_cipher_suite tls_cipher_suite_null
Initial value:
= {
.pubkey = &pubkey_null,
.cipher = &cipher_null,
.digest = &digest_null,
}
struct cipher_algorithm cipher_null
Definition crypto_null.c:94
struct pubkey_algorithm pubkey_null
struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm
Public key exchange algorithm.
Definition tls.c:1655

Null cipher suite.

Definition at line 1191 of file tls.c.

1191 {
1192 .exchange = &tls_pubkey_exchange_algorithm,
1193 .pubkey = &pubkey_null,
1194 .cipher = &cipher_null,
1195 .digest = &digest_null,
1196};

Referenced by tls_change_cipher(), and tls_clear_cipher().

◆ tls_pubkey_exchange_algorithm

struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm
Initial value:
= {
.name = "pubkey",
}
static int tls_new_server_key_exchange_pubkey(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Key Exchange record using public key transport.
Definition tls.c:1558
static int tls_send_client_key_exchange_pubkey(struct tls_connection *tls)
Transmit Client Key Exchange record using public key exchange.
Definition tls.c:1573

Public key exchange algorithm.

Definition at line 1655 of file tls.c.

1655 {
1656 .name = "pubkey",
1659};

Referenced by __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), and __tls_cipher_suite().

◆ tls_dhe_exchange_algorithm

struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm
Initial value:
= {
.name = "dhe",
}
static int tls_send_client_key_exchange_dhe(struct tls_connection *tls)
Transmit Client Key Exchange record using DHE key exchange.
Definition tls.c:1740
static int tls_new_server_key_exchange_dhe(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Key Exchange record using DHE key exchange.
Definition tls.c:1669

Ephemeral Diffie-Hellman key exchange algorithm.

Definition at line 1781 of file tls.c.

1781 {
1782 .name = "dhe",
1785};

Referenced by __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), and __tls_cipher_suite().

◆ tls_ecdhe_exchange_algorithm

struct tls_key_exchange_algorithm tls_ecdhe_exchange_algorithm
Initial value:
= {
.name = "ecdhe",
}
static int tls_new_server_key_exchange_ecdhe(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Key Exchange record using ECDHE key exchange.
Definition tls.c:1795
static int tls_send_client_key_exchange_ecdhe(struct tls_connection *tls)
Transmit Client Key Exchange record using ECDHE key exchange.
Definition tls.c:1854

Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm.

Definition at line 1884 of file tls.c.

1884 {
1885 .name = "ecdhe",
1888};

Referenced by __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), and __tls_cipher_suite().

◆ tls_plainstream_ops

struct interface_operation tls_plainstream_ops[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
Job progress.
Definition job.h:16
static int tls_progress(struct tls_connection *tls, struct job_progress *progress)
Report job progress.
Definition tls.c:3889
static int tls_plainstream_deliver(struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Deliver datagram as raw data.
Definition tls.c:3861
static size_t tls_plainstream_window(struct tls_connection *tls)
Check flow control window.
Definition tls.c:3844
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195

TLS plaintext stream interface operations.

Definition at line 3901 of file tls.c.

◆ tls_plainstream_desc

struct interface_descriptor tls_plainstream_desc
static
Initial value:
=
INTF_DESC_PASSTHRU ( struct tls_connection, plainstream,
tls_plainstream_ops, cipherstream )
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition interface.h:98
static struct interface_operation tls_plainstream_ops[]
TLS plaintext stream interface operations.
Definition tls.c:3901

TLS plaintext stream interface descriptor.

Definition at line 3912 of file tls.c.

Referenced by add_tls().

◆ tls_cipherstream_ops

struct interface_operation tls_cipherstream_ops[]
static
Initial value:
= {
}
static int tls_cipherstream_deliver(struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *xfer __unused)
Receive new ciphertext.
Definition tls.c:4065
static size_t tls_cipherstream_window(struct tls_connection *tls)
Check flow control window.
Definition tls.c:4048

TLS ciphertext stream interface operations.

Definition at line 4116 of file tls.c.

◆ tls_cipherstream_desc

struct interface_descriptor tls_cipherstream_desc
static
Initial value:
=
INTF_DESC_PASSTHRU ( struct tls_connection, cipherstream,
tls_cipherstream_ops, plainstream )
static struct interface_operation tls_cipherstream_ops[]
TLS ciphertext stream interface operations.
Definition tls.c:4116

TLS ciphertext stream interface descriptor.

Definition at line 4127 of file tls.c.

Referenced by add_tls().

◆ tls_validator_ops

struct interface_operation tls_validator_ops[]
static
Initial value:
= {
}
static void tls_validator_done(struct tls_connection *tls, int rc)
Handle certificate validation completion.
Definition tls.c:4144

TLS certificate validator interface operations.

Definition at line 4179 of file tls.c.

4179 {
4181};

◆ tls_validator_desc

struct interface_descriptor tls_validator_desc
static
Initial value:
=
INTF_DESC ( struct tls_connection, server.validator,
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static struct interface_operation tls_validator_ops[]
TLS certificate validator interface operations.
Definition tls.c:4179

TLS certificate validator interface descriptor.

Definition at line 4184 of file tls.c.

Referenced by add_tls().

◆ tls_process_desc

struct process_descriptor tls_process_desc
static
Initial value:
=
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition process.h:98
static void tls_tx_step(struct tls_connection *tls)
TLS TX state machine.
Definition tls.c:4200
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition wpa.h:4

TLS TX process descriptor.

Definition at line 4307 of file tls.c.

Referenced by add_tls().