iPXE
Data Structures | Macros | Functions | Variables
tls.c File Reference

Transport Layer Security Protocol. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.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/aes.h>
#include <ipxe/rsa.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/dhe.h>
#include <ipxe/ecdhe.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 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_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )
 
#define EINFO_ENOTSUP_CURVE
 
#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 EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )
 
#define EINFO_EPROTO_VERSION
 
#define tls_prf_label(tls, secret, secret_len, out, out_len, label, ...)
 Generate secure pseudo-random data. More...
 
#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )
 Number of supported cipher suites. More...
 
#define TLS_NUM_SIG_HASH_ALGORITHMS   table_num_entries ( TLS_SIG_HASH_ALGORITHMS )
 Number of supported signature and hash algorithms. More...
 
#define TLS_NUM_NAMED_CURVES   table_num_entries ( TLS_NAMED_CURVES )
 Number of supported named curves. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
static LIST_HEAD (tls_sessions)
 List of TLS session. More...
 
static void tls_tx_resume_all (struct tls_session *session)
 Resume TX state machine for all connections within a session. More...
 
static struct io_buffertls_alloc_iob (struct tls_connection *tls, size_t len)
 Allocate I/O buffer for transmitted record(s) More...
 
static int tls_send_record (struct tls_connection *tls, unsigned int type, struct io_buffer *iobuf)
 Send plaintext record(s) More...
 
static int tls_send_plaintext (struct tls_connection *tls, unsigned int type, const void *data, size_t len)
 Send plaintext record. More...
 
static void tls_clear_cipher (struct tls_connection *tls, struct tls_cipherspec *cipherspec)
 
static void tls_verify_handshake (struct tls_connection *tls, void *out)
 Calculate handshake verification hash. More...
 
static unsigned long tls_uint24 (const tls24_t *field24)
 Extract 24-bit field value. More...
 
static void tls_set_uint24 (tls24_t *field24, unsigned long value)
 Set 24-bit field value. More...
 
static int tls_ready (struct tls_connection *tls)
 Determine if TLS connection is ready for application data. More...
 
static int tls_version (struct tls_connection *tls, unsigned int version)
 Check for TLS version. More...
 
static void md5_sha1_init (void *ctx)
 Initialise MD5+SHA1 algorithm. More...
 
static void md5_sha1_update (void *ctx, const void *data, size_t len)
 Accumulate data with MD5+SHA1 algorithm. More...
 
static void md5_sha1_final (void *ctx, void *out)
 Generate MD5+SHA1 digest. More...
 
static void free_tls_session (struct refcnt *refcnt)
 Free TLS session. More...
 
static void free_tls (struct refcnt *refcnt)
 Free TLS connection. More...
 
static void tls_close (struct tls_connection *tls, int rc)
 Finish with TLS connection. More...
 
static int tls_generate_random (struct tls_connection *tls, void *data, size_t len)
 Generate random data. More...
 
static void tls_hmac_update_va (struct digest_algorithm *digest, void *ctx, va_list args)
 Update HMAC with a list of ( data, len ) pairs. More...
 
static void tls_p_hash_va (struct tls_connection *tls, struct digest_algorithm *digest, const void *secret, size_t secret_len, void *out, size_t out_len, va_list seeds)
 Generate secure pseudo-random data using a single hash function. More...
 
static void tls_prf (struct tls_connection *tls, const void *secret, size_t secret_len, void *out, size_t out_len,...)
 Generate secure pseudo-random data. More...
 
static void tls_generate_master_secret (struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
 Generate master secret. More...
 
static int tls_generate_keys (struct tls_connection *tls)
 Generate key material. More...
 
static void tls_clear_handshake (struct tls_connection *tls)
 Clear handshake digest algorithm. More...
 
static int tls_select_handshake (struct tls_connection *tls, struct digest_algorithm *digest)
 Select handshake digest algorithm. More...
 
static int tls_add_handshake (struct tls_connection *tls, const void *data, size_t len)
 Add handshake record to verification hash. More...
 
static struct tls_cipher_suitetls_find_cipher_suite (unsigned int cipher_suite)
 Identify cipher suite. More...
 
static void tls_clear_cipher (struct tls_connection *tls __unused, struct tls_cipherspec *cipherspec)
 Clear cipher suite. More...
 
static int tls_set_cipher (struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
 Set cipher suite. More...
 
static int tls_select_cipher (struct tls_connection *tls, unsigned int cipher_suite)
 Select next cipher suite. More...
 
static int tls_change_cipher (struct tls_connection *tls, struct tls_cipherspec_pair *pair)
 Activate next cipher suite. More...
 
static struct tls_signature_hash_algorithmtls_signature_hash_algorithm (struct pubkey_algorithm *pubkey, struct digest_algorithm *digest)
 Find TLS signature and hash algorithm. More...
 
static struct pubkey_algorithmtls_signature_hash_pubkey (struct tls_signature_hash_id code)
 Find TLS signature algorithm. More...
 
static struct digest_algorithmtls_signature_hash_digest (struct tls_signature_hash_id code)
 Find TLS hash algorithm. More...
 
static struct tls_named_curvetls_find_named_curve (unsigned int named_curve)
 Identify named curve. More...
 
static void tls_tx_resume (struct tls_connection *tls)
 Resume TX state machine. More...
 
static void tls_restart (struct tls_connection *tls)
 Restart negotiation. More...
 
static int tls_send_handshake (struct tls_connection *tls, const void *data, size_t len)
 Transmit Handshake record. More...
 
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. More...
 
static int tls_send_client_hello (struct tls_connection *tls)
 Transmit Client Hello record. More...
 
static int tls_send_certificate (struct tls_connection *tls)
 Transmit Certificate record. More...
 
static int tls_send_client_key_exchange_pubkey (struct tls_connection *tls)
 Transmit Client Key Exchange record using public key exchange. More...
 
static int tls_verify_dh_params (struct tls_connection *tls, size_t param_len)
 Verify Diffie-Hellman parameter signature. More...
 
static int tls_send_client_key_exchange_dhe (struct tls_connection *tls)
 Transmit Client Key Exchange record using DHE key exchange. More...
 
static int tls_send_client_key_exchange_ecdhe (struct tls_connection *tls)
 Transmit Client Key Exchange record using ECDHE key exchange. More...
 
static int tls_send_client_key_exchange (struct tls_connection *tls)
 Transmit Client Key Exchange record. More...
 
static int tls_send_certificate_verify (struct tls_connection *tls)
 Transmit Certificate Verify record. More...
 
static int tls_send_change_cipher (struct tls_connection *tls)
 Transmit Change Cipher record. More...
 
static int tls_send_finished (struct tls_connection *tls)
 Transmit Finished record. More...
 
static int tls_new_change_cipher (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Change Cipher record. More...
 
static int tls_new_alert (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Alert record. More...
 
static int tls_new_hello_request (struct tls_connection *tls, const void *data __unused, size_t len __unused)
 Receive new Hello Request handshake record. More...
 
static int tls_new_server_hello (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Hello handshake record. More...
 
static int tls_new_session_ticket (struct tls_connection *tls, const void *data, size_t len)
 Receive New Session Ticket handshake record. More...
 
static int tls_parse_chain (struct tls_connection *tls, const void *data, size_t len)
 Parse certificate chain. More...
 
static int tls_new_certificate (struct tls_connection *tls, const void *data, size_t len)
 Receive new Certificate handshake record. More...
 
static int tls_new_server_key_exchange (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Key Exchange handshake record. More...
 
static int tls_new_certificate_request (struct tls_connection *tls, const void *data __unused, size_t len __unused)
 Receive new Certificate Request handshake record. More...
 
static int tls_new_server_hello_done (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Hello Done handshake record. More...
 
static int tls_new_finished (struct tls_connection *tls, const void *data, size_t len)
 Receive new Finished handshake record. More...
 
static int tls_new_handshake (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Handshake record. More...
 
static int tls_new_unknown (struct tls_connection *tls __unused, struct io_buffer *iobuf)
 Receive new unknown record. More...
 
static int tls_new_data (struct tls_connection *tls, struct list_head *rx_data)
 Receive new data record. More...
 
static int tls_new_record (struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
 Receive new record. More...
 
static void tls_hmac_init (struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
 Initialise HMAC. More...
 
static void tls_hmac_update (struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
 Update HMAC. More...
 
static void tls_hmac_final (struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
 Finalise HMAC. More...
 
static void tls_hmac (struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, const void *data, size_t len, void *hmac)
 Calculate HMAC. More...
 
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. More...
 
static size_t tls_iob_reserved (struct tls_connection *tls, size_t len)
 Calculate maximum additional length required for transmitted record(s) More...
 
static int tls_verify_padding (struct tls_connection *tls, struct io_buffer *iobuf)
 Verify block padding. More...
 
static int tls_new_ciphertext (struct tls_connection *tls, struct tls_header *tlshdr, struct list_head *rx_data)
 Receive new ciphertext record. More...
 
static size_t tls_plainstream_window (struct tls_connection *tls)
 Check flow control window. More...
 
static int tls_plainstream_deliver (struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Deliver datagram as raw data. More...
 
static int tls_progress (struct tls_connection *tls, struct job_progress *progress)
 Report job progress. More...
 
static int tls_newdata_process_header (struct tls_connection *tls)
 Handle received TLS header. More...
 
static int tls_newdata_process_data (struct tls_connection *tls)
 Handle received TLS data payload. More...
 
static size_t tls_cipherstream_window (struct tls_connection *tls)
 Check flow control window. More...
 
static int tls_cipherstream_deliver (struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *xfer __unused)
 Receive new ciphertext. More...
 
static void tls_validator_done (struct tls_connection *tls, int rc)
 Handle certificate validation completion. More...
 
static void tls_tx_step (struct tls_connection *tls)
 TLS TX state machine. More...
 
static int tls_session (struct tls_connection *tls, const char *name)
 Find or create session for TLS connection. More...
 
int add_tls (struct interface *xfer, const char *name, struct x509_root *root, struct private_key *key)
 Add TLS on an interface. More...
 
 REQUIRING_SYMBOL (add_tls)
 
 REQUIRE_OBJECT (config_crypto)
 

Variables

static struct digest_algorithm md5_sha1_algorithm
 Hybrid MD5+SHA1 digest algorithm. More...
 
struct rsa_digestinfo_prefix rsa_md5_sha1_prefix __rsa_digestinfo_prefix
 RSA digestInfo prefix for MD5+SHA1 algorithm. More...
 
struct tls_cipher_suite tls_cipher_suite_null
 Null cipher suite. More...
 
struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm
 Public key exchange algorithm. More...
 
struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm
 Ephemeral Diffie-Hellman key exchange algorithm. More...
 
struct tls_key_exchange_algorithm tls_ecdhe_exchange_algorithm
 Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm. More...
 
static struct interface_operation tls_plainstream_ops []
 TLS plaintext stream interface operations. More...
 
static struct interface_descriptor tls_plainstream_desc
 TLS plaintext stream interface descriptor. More...
 
static struct interface_operation tls_cipherstream_ops []
 TLS ciphertext stream interface operations. More...
 
static struct interface_descriptor tls_cipherstream_desc
 TLS ciphertext stream interface descriptor. More...
 
static struct interface_operation tls_validator_ops []
 TLS certificate validator interface operations. More...
 
static struct interface_descriptor tls_validator_desc
 TLS certificate validator interface descriptor. More...
 
static struct process_descriptor tls_process_desc
 TLS TX process descriptor. More...
 

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 58 of file tls.c.

◆ EINFO_EINVAL_CHANGE_CIPHER

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

Definition at line 59 of file tls.c.

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

Definition at line 62 of file tls.c.

◆ EINFO_EINVAL_ALERT

#define EINFO_EINVAL_ALERT
Value:
"Invalid Alert record" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 63 of file tls.c.

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

Definition at line 66 of file tls.c.

◆ EINFO_EINVAL_HELLO

#define EINFO_EINVAL_HELLO
Value:
"Invalid Server Hello record" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 67 of file tls.c.

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

Definition at line 70 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATE

#define EINFO_EINVAL_CERTIFICATE
Value:
"Invalid Certificate" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 71 of file tls.c.

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

Definition at line 74 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATES

#define EINFO_EINVAL_CERTIFICATES
Value:
"Invalid Server Certificate record" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 75 of file tls.c.

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

Definition at line 78 of file tls.c.

◆ EINFO_EINVAL_HELLO_DONE

#define EINFO_EINVAL_HELLO_DONE
Value:
"Invalid Server Hello Done record" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 79 of file tls.c.

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

Definition at line 82 of file tls.c.

◆ EINFO_EINVAL_FINISHED

#define EINFO_EINVAL_FINISHED
Value:
"Invalid Server Finished record" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 83 of file tls.c.

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

Definition at line 86 of file tls.c.

◆ EINFO_EINVAL_HANDSHAKE

#define EINFO_EINVAL_HANDSHAKE
Value:
"Invalid Handshake record" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 87 of file tls.c.

◆ EINVAL_IV

#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )

Definition at line 90 of file tls.c.

◆ EINFO_EINVAL_IV

#define EINFO_EINVAL_IV
Value:
"Invalid initialisation vector" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 91 of file tls.c.

◆ EINVAL_PADDING

#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )

Definition at line 94 of file tls.c.

◆ EINFO_EINVAL_PADDING

#define EINFO_EINVAL_PADDING
Value:
"Invalid block padding" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 95 of file tls.c.

◆ EINVAL_RX_STATE

#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )

Definition at line 98 of file tls.c.

◆ EINFO_EINVAL_RX_STATE

#define EINFO_EINVAL_RX_STATE
Value:
"Invalid receive state" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 99 of file tls.c.

◆ EINVAL_MAC

#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )

Definition at line 102 of file tls.c.

◆ EINFO_EINVAL_MAC

#define EINFO_EINVAL_MAC
Value:
"Invalid MAC or authentication tag" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 103 of file tls.c.

◆ EINVAL_TICKET

#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )

Definition at line 106 of file tls.c.

◆ EINFO_EINVAL_TICKET

#define EINFO_EINVAL_TICKET
Value:
"Invalid New Session Ticket record")
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 107 of file tls.c.

◆ EINVAL_KEY_EXCHANGE

#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )

Definition at line 110 of file tls.c.

◆ EINFO_EINVAL_KEY_EXCHANGE

#define EINFO_EINVAL_KEY_EXCHANGE
Value:
"Invalid Server Key Exchange record" )
#define EINFO_EINVAL
Definition: errno.h:429
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 111 of file tls.c.

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

Definition at line 114 of file tls.c.

◆ EINFO_EIO_ALERT

#define EINFO_EIO_ALERT
Value:
"Unknown alert level" )
#define EINFO_EIO
Definition: errno.h:434
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 115 of file tls.c.

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

Definition at line 118 of file tls.c.

◆ EINFO_ENOMEM_CONTEXT

#define EINFO_ENOMEM_CONTEXT
Value:
"Not enough space for crypto context" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_ENOMEM
Definition: errno.h:535

Definition at line 119 of file tls.c.

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

Definition at line 122 of file tls.c.

◆ EINFO_ENOMEM_CERTIFICATE

#define EINFO_ENOMEM_CERTIFICATE
Value:
"Not enough space for certificate" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_ENOMEM
Definition: errno.h:535

Definition at line 123 of file tls.c.

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

Definition at line 126 of file tls.c.

◆ EINFO_ENOMEM_CHAIN

#define EINFO_ENOMEM_CHAIN
Value:
"Not enough space for certificate chain" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_ENOMEM
Definition: errno.h:535

Definition at line 127 of file tls.c.

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

Definition at line 130 of file tls.c.

◆ EINFO_ENOMEM_TX_PLAINTEXT

#define EINFO_ENOMEM_TX_PLAINTEXT
Value:
"Not enough space for transmitted plaintext" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_ENOMEM
Definition: errno.h:535

Definition at line 131 of file tls.c.

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

Definition at line 134 of file tls.c.

◆ EINFO_ENOMEM_TX_CIPHERTEXT

#define EINFO_ENOMEM_TX_CIPHERTEXT
Value:
"Not enough space for transmitted ciphertext" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_ENOMEM
Definition: errno.h:535

Definition at line 135 of file tls.c.

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

Definition at line 138 of file tls.c.

◆ EINFO_ENOMEM_RX_DATA

#define EINFO_ENOMEM_RX_DATA
Value:
"Not enough space for received data" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_ENOMEM
Definition: errno.h:535

Definition at line 139 of file tls.c.

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

Definition at line 142 of file tls.c.

◆ EINFO_ENOMEM_RX_CONCAT

#define EINFO_ENOMEM_RX_CONCAT
Value:
"Not enough space to concatenate received data" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_ENOMEM
Definition: errno.h:535

Definition at line 143 of file tls.c.

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

Definition at line 146 of file tls.c.

◆ EINFO_ENOTSUP_CIPHER

#define EINFO_ENOTSUP_CIPHER
Value:
"Unsupported cipher" )
#define EINFO_ENOTSUP
Definition: errno.h:590
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 147 of file tls.c.

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

Definition at line 150 of file tls.c.

◆ EINFO_ENOTSUP_NULL

#define EINFO_ENOTSUP_NULL
Value:
"Refusing to use null cipher" )
#define EINFO_ENOTSUP
Definition: errno.h:590
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 151 of file tls.c.

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

Definition at line 154 of file tls.c.

◆ EINFO_ENOTSUP_SIG_HASH

#define EINFO_ENOTSUP_SIG_HASH
Value:
"Unsupported signature and hash algorithm" )
#define EINFO_ENOTSUP
Definition: errno.h:590
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 155 of file tls.c.

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

Definition at line 158 of file tls.c.

◆ EINFO_ENOTSUP_VERSION

#define EINFO_ENOTSUP_VERSION
Value:
"Unsupported protocol version" )
#define EINFO_ENOTSUP
Definition: errno.h:590
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 159 of file tls.c.

◆ ENOTSUP_CURVE

#define ENOTSUP_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )

Definition at line 162 of file tls.c.

◆ EINFO_ENOTSUP_CURVE

#define EINFO_ENOTSUP_CURVE
Value:
"Unsupported elliptic curve" )
#define EINFO_ENOTSUP
Definition: errno.h:590
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 163 of file tls.c.

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

Definition at line 166 of file tls.c.

◆ EINFO_EPERM_ALERT

#define EINFO_EPERM_ALERT
Value:
"Received fatal alert" )
#define EINFO_EPERM
Definition: errno.h:615
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 167 of file tls.c.

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

Definition at line 170 of file tls.c.

◆ EINFO_EPERM_VERIFY

#define EINFO_EPERM_VERIFY
Value:
"Handshake verification failed" )
#define EINFO_EPERM
Definition: errno.h:615
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 171 of file tls.c.

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

Definition at line 174 of file tls.c.

◆ EINFO_EPERM_RENEG_INSECURE

#define EINFO_EPERM_RENEG_INSECURE
Value:
"Secure renegotiation not supported" )
#define EINFO_EPERM
Definition: errno.h:615
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 175 of file tls.c.

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

Definition at line 178 of file tls.c.

◆ EINFO_EPERM_RENEG_VERIFY

#define EINFO_EPERM_RENEG_VERIFY
Value:
"Secure renegotiation verification failed" )
#define EINFO_EPERM
Definition: errno.h:615
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 179 of file tls.c.

◆ EPERM_KEY_EXCHANGE

#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )

Definition at line 182 of file tls.c.

◆ EINFO_EPERM_KEY_EXCHANGE

#define EINFO_EPERM_KEY_EXCHANGE
Value:
"ServerKeyExchange verification failed" )
#define EINFO_EPERM
Definition: errno.h:615
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 183 of file tls.c.

◆ EPERM_EMS

#define EPERM_EMS   __einfo_error ( EINFO_EPERM_EMS )

Definition at line 186 of file tls.c.

◆ EINFO_EPERM_EMS

#define EINFO_EPERM_EMS
Value:
"Extended master secret extension mismatch" )
#define EINFO_EPERM
Definition: errno.h:615
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 187 of file tls.c.

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

Definition at line 190 of file tls.c.

◆ EINFO_EPROTO_VERSION

#define EINFO_EPROTO_VERSION
Value:
"Illegal protocol version upgrade" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_EPROTO
Definition: errno.h:625

Definition at line 191 of file tls.c.

◆ tls_prf_label

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

Generate secure pseudo-random data.

Parameters
secretSecret
secret_lenLength of secret
outOutput buffer
out_lenLength of output buffer
labelString literal label
...( data, len ) pairs of seed data

Definition at line 622 of file tls.c.

◆ TLS_NUM_CIPHER_SUITES

#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )

Number of supported cipher suites.

Definition at line 858 of file tls.c.

◆ 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 1004 of file tls.c.

◆ TLS_NUM_NAMED_CURVES

#define TLS_NUM_NAMED_CURVES   table_num_entries ( TLS_NAMED_CURVES )

Number of supported named curves.

Definition at line 1076 of file tls.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ LIST_HEAD()

static LIST_HEAD ( tls_sessions  )
static

List of TLS session.

◆ tls_tx_resume_all()

static 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 1118 of file tls.c.

1118  {
1119  struct tls_connection *tls;
1120 
1121  list_for_each_entry ( tls, &session->conn, list )
1122  tls_tx_resume ( tls );
1123 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1109
struct tls_session * session
Session.
Definition: tls.h:433
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct list_head list
List of connections within the same session.
Definition: tls.h:435
A TLS connection.
Definition: tls.h:428
struct list_head conn
List of connections.
Definition: tls.h:360

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()

static 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 3025 of file tls.c.

3026  {
3027  struct io_buffer *iobuf;
3028  size_t reserve;
3029 
3030  /* Calculate maximum additional length to reserve */
3031  reserve = tls_iob_reserved ( tls, len );
3032 
3033  /* Allocate I/O buffer */
3034  iobuf = xfer_alloc_iob ( &tls->cipherstream, ( reserve + len ) );
3035  if ( ! iobuf )
3036  return NULL;
3037 
3038  /* Reserve space */
3039  iob_reserve ( iobuf, reserve );
3040 
3041  return iobuf;
3042 }
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
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:2998
ring len
Length.
Definition: dwmac.h:231
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:448
#define iob_reserve(iobuf, len)
Definition: iobuf.h:71
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
A persistent I/O buffer.
Definition: iobuf.h:37

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_record()

static 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 3052 of file tls.c.

3053  {
3054  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.active;
3055  struct tls_cipher_suite *suite = cipherspec->suite;
3056  struct cipher_algorithm *cipher = suite->cipher;
3057  struct digest_algorithm *digest = suite->digest;
3058  struct {
3059  uint8_t fixed[suite->fixed_iv_len];
3060  uint8_t rec[suite->record_iv_len];
3061  } __attribute__ (( packed )) iv;
3062  struct tls_auth_header authhdr;
3063  struct tls_header *tlshdr;
3064  uint8_t mac[digest->digestsize];
3065  const void *plaintext;
3066  const void *encrypt;
3067  void *ciphertext;
3068  size_t record_len;
3069  size_t encrypt_len;
3070  size_t pad_len;
3071  size_t len;
3072  int rc;
3073 
3074  /* Record plaintext pointer and length */
3075  plaintext = iobuf->data;
3076  len = iob_len ( iobuf );
3077 
3078  /* Add to handshake digest if applicable */
3079  if ( type == TLS_TYPE_HANDSHAKE )
3080  tls_add_handshake ( tls, plaintext, len );
3081 
3082  /* Start constructing ciphertext at start of reserved space */
3083  iob_push ( iobuf, tls_iob_reserved ( tls, len ) );
3084  iob_unput ( iobuf, iob_len ( iobuf ) );
3085 
3086  /* Construct records */
3087  do {
3088  /* Limit length of this record (may be zero) */
3089  record_len = len;
3090  if ( record_len > TLS_TX_BUFSIZE )
3091  record_len = TLS_TX_BUFSIZE;
3092 
3093  /* Construct and set initialisation vector */
3094  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
3095  if ( ( rc = tls_generate_random ( tls, iv.rec,
3096  sizeof ( iv.rec ) ) ) != 0 ) {
3097  goto err_random;
3098  }
3099  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv,
3100  sizeof ( iv ) );
3101 
3102  /* Construct and process authentication data */
3103  authhdr.seq = cpu_to_be64 ( tls->tx.seq );
3104  authhdr.header.type = type;
3105  authhdr.header.version = htons ( tls->version );
3106  authhdr.header.length = htons ( record_len );
3107  if ( suite->mac_len ) {
3108  tls_hmac ( cipherspec, &authhdr, plaintext, record_len,
3109  mac );
3110  }
3111  if ( is_auth_cipher ( cipher ) ) {
3112  cipher_encrypt ( cipher, cipherspec->cipher_ctx,
3113  &authhdr, NULL, sizeof ( authhdr ) );
3114  }
3115 
3116  /* Calculate encryption length */
3117  encrypt_len = ( record_len + suite->mac_len );
3118  if ( is_block_cipher ( cipher ) ) {
3119  pad_len = ( ( ( cipher->blocksize - 1 ) &
3120  -( encrypt_len + 1 ) ) + 1 );
3121  } else {
3122  pad_len = 0;
3123  }
3124  encrypt_len += pad_len;
3125 
3126  /* Add record header */
3127  tlshdr = iob_put ( iobuf, sizeof ( *tlshdr ) );
3128  tlshdr->type = type;
3129  tlshdr->version = htons ( tls->version );
3130  tlshdr->length = htons ( sizeof ( iv.rec ) + encrypt_len +
3131  cipher->authsize );
3132 
3133  /* Add record initialisation vector, if applicable */
3134  memcpy ( iob_put ( iobuf, sizeof ( iv.rec ) ), iv.rec,
3135  sizeof ( iv.rec ) );
3136 
3137  /* Copy plaintext data if necessary */
3138  ciphertext = iob_put ( iobuf, record_len );
3139  assert ( ciphertext <= plaintext );
3140  if ( encrypt_len > record_len ) {
3141  memmove ( ciphertext, plaintext, record_len );
3142  encrypt = ciphertext;
3143  } else {
3144  encrypt = plaintext;
3145  }
3146 
3147  /* Add MAC, if applicable */
3148  memcpy ( iob_put ( iobuf, suite->mac_len ), mac,
3149  suite->mac_len );
3150 
3151  /* Add padding, if applicable */
3152  memset ( iob_put ( iobuf, pad_len ), ( pad_len - 1 ), pad_len );
3153 
3154  /* Encrypt data and append authentication tag */
3155  DBGC2 ( tls, "Sending plaintext data:\n" );
3156  DBGC2_HDA ( tls, 0, encrypt, encrypt_len );
3157  cipher_encrypt ( cipher, cipherspec->cipher_ctx, encrypt,
3158  ciphertext, encrypt_len );
3159  cipher_auth ( cipher, cipherspec->cipher_ctx,
3160  iob_put ( iobuf, cipher->authsize ) );
3161 
3162  /* Move to next record */
3163  tls->tx.seq += 1;
3164  plaintext += record_len;
3165  len -= record_len;
3166 
3167  } while ( len );
3168 
3169  /* Send ciphertext */
3170  if ( ( rc = xfer_deliver_iob ( &tls->cipherstream,
3171  iob_disown ( iobuf ) ) ) != 0 ) {
3172  DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
3173  tls, strerror ( rc ) );
3174  goto err_deliver;
3175  }
3176 
3177  assert ( iobuf == NULL );
3178  return 0;
3179 
3180  err_deliver:
3181  err_random:
3182  free_iob ( iobuf );
3183  return rc;
3184 }
#define __attribute__(x)
Definition: compiler.h:10
size_t blocksize
Block size.
Definition: crypto.h:60
static int is_auth_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:259
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:124
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:255
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:210
#define iob_push(iobuf, len)
Definition: iobuf.h:88
uint8_t type
Content type.
Definition: tls.h:33
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:818
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:40
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition: eltorito.h:13
TLS authentication header.
Definition: tls.h:147
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:250
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:228
size_t authsize
Authentication tag size.
Definition: crypto.h:74
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:216
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:256
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:2998
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:200
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:208
A TLS cipher suite.
Definition: tls.h:192
#define TLS_TX_BUFSIZE
TX maximum fragment length.
Definition: tls.h:484
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
#define DBGC2_HDA(...)
Definition: compiler.h:523
#define iob_unput(iobuf, len)
Definition: iobuf.h:139
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint64_t seq
Sequence number.
Definition: tls.h:368
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:448
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition: crypto.h:218
uint8_t mac_len
MAC length.
Definition: tls.h:212
unsigned char uint8_t
Definition: stdint.h:10
void * memmove(void *dest, const void *src, size_t len) __nonnull
A TLS header.
Definition: tls.h:28
struct tls_tx tx
Transmit state.
Definition: tls.h:466
long pad_len
Definition: bigint.h:30
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:62
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:2957
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:26
void * data
Start of data.
Definition: iobuf.h:52
uint16_t version
Protocol version.
Definition: tls.h:38
A message digest algorithm.
Definition: crypto.h:18
uint16_t version
Protocol version.
Definition: tls.h:451
#define cpu_to_be64(value)
Definition: byteswap.h:111
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:266
A cipher algorithm.
Definition: crypto.h:50
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition: crypto.h:244
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:198
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:459
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:260
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:254
void * memset(void *dest, int character, size_t len) __nonnull

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, pad_len, rc, tls_cipher_suite::record_iv_len, tls_auth_header::seq, tls_tx::seq, strerror(), tls_cipherspec::suite, tls_add_handshake(), tls_generate_random(), tls_hmac(), tls_iob_reserved(), TLS_TX_BUFSIZE, TLS_TYPE_HANDSHAKE, tls_connection::tx, type, tls_header::type, tls_header::version, tls_connection::version, and xfer_deliver_iob().

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

◆ tls_send_plaintext()

static 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 3195 of file tls.c.

3196  {
3197  struct io_buffer *iobuf;
3198  int rc;
3199 
3200  /* Allocate I/O buffer */
3201  iobuf = tls_alloc_iob ( tls, len );
3202  if ( ! iobuf )
3203  return -ENOMEM_TX_PLAINTEXT;
3204  memcpy ( iob_put ( iobuf, len ), data, len );
3205 
3206  /* Transmit I/O buffer */
3207  if ( ( rc = tls_send_record ( tls, type, iob_disown ( iobuf ) ) ) != 0 )
3208  return rc;
3209 
3210  return 0;
3211 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int tls_send_record(struct tls_connection *tls, unsigned int type, struct io_buffer *iobuf)
Send plaintext record(s)
Definition: tls.c:3052
#define iob_put(iobuf, len)
Definition: iobuf.h:124
uint32_t type
Operating system type.
Definition: ena.h:12
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:216
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
#define ENOMEM_TX_PLAINTEXT
Definition: tls.c:130
uint8_t data[48]
Additional event data.
Definition: ena.h:22
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:3025
A persistent I/O buffer.
Definition: iobuf.h:37

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

Referenced by tls_send_change_cipher(), and tls_send_handshake().

◆ tls_clear_cipher() [1/2]

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

◆ tls_verify_handshake()

static 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 834 of file tls.c.

834  {
835  struct digest_algorithm *digest = tls->handshake_digest;
836  uint8_t ctx[ digest->ctxsize ];
837 
838  memcpy ( ctx, tls->handshake_ctx, sizeof ( ctx ) );
839  digest_final ( digest, ctx, out );
840 }
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:207
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
__be32 out[4]
Definition: CIB_PRM.h:36
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:457
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned char uint8_t
Definition: stdint.h:10
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
size_t ctxsize
Context size.
Definition: crypto.h:22
A message digest algorithm.
Definition: crypto.h:18

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

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

◆ tls_uint24()

static 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 236 of file tls.c.

236  {
237 
238  return ( ( field24->high << 16 ) | be16_to_cpu ( field24->low ) );
239 }
#define be16_to_cpu(value)
Definition: byteswap.h:115
uint16_t low
Low word.
Definition: tls.c:225
uint8_t high
High byte.
Definition: tls.c:223

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()

static 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 247 of file tls.c.

247  {
248 
249  field24->high = ( value >> 16 );
250  field24->low = cpu_to_be16 ( value );
251 }
#define cpu_to_be16(value)
Definition: byteswap.h:109
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
uint16_t low
Low word.
Definition: tls.c:225
uint8_t high
High byte.
Definition: tls.c:223

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

Referenced by tls_send_certificate().

◆ tls_ready()

static 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 259 of file tls.c.

259  {
260  return ( ( ! is_pending ( &tls->client.negotiation ) ) &&
261  ( ! is_pending ( &tls->server.negotiation ) ) );
262 }
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:402
struct tls_server server
Server state.
Definition: tls.h:472
struct tls_client client
Client state.
Definition: tls.h:470
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:424

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()

static 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 276 of file tls.c.

276  {
277  return ( ( TLS_VERSION_MIN >= version ) ||
278  ( tls->version >= version ) );
279 }
u32 version
Driver version.
Definition: ath9k_hw.c:1983
uint16_t version
Protocol version.
Definition: tls.h:451
#define TLS_VERSION_MIN
Minimum TLS version.
Definition: crypto.h:13

References TLS_VERSION_MIN, tls_connection::version, and version.

Referenced by tls_prf(), tls_select_cipher(), tls_send_certificate_verify(), and tls_verify_dh_params().

◆ md5_sha1_init()

static void md5_sha1_init ( void *  ctx)
static

Initialise MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context

Definition at line 293 of file tls.c.

293  {
294  struct md5_sha1_context *context = ctx;
295 
296  digest_init ( &md5_algorithm, context->md5 );
297  digest_init ( &sha1_algorithm, context->sha1 );
298 }
An MD5+SHA1 context.
Definition: tls.h:311
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:196
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:315
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:313
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257

References ctx, digest_init(), md5_sha1_context::md5, md5_algorithm, md5_sha1_context::sha1, and sha1_algorithm.

◆ md5_sha1_update()

static void md5_sha1_update ( void *  ctx,
const void *  data,
size_t  len 
)
static

Accumulate data with MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context
dataData
lenLength of data

Definition at line 307 of file tls.c.

307  {
308  struct md5_sha1_context *context = ctx;
309 
310  digest_update ( &md5_algorithm, context->md5, data, len );
311  digest_update ( &sha1_algorithm, context->sha1, data, len );
312 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:201
An MD5+SHA1 context.
Definition: tls.h:311
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
ring len
Length.
Definition: dwmac.h:231
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:315
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:313
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257

References ctx, data, digest_update(), len, md5_sha1_context::md5, md5_algorithm, md5_sha1_context::sha1, and sha1_algorithm.

◆ md5_sha1_final()

static void md5_sha1_final ( void *  ctx,
void *  out 
)
static

Generate MD5+SHA1 digest.

Parameters
ctxMD5+SHA1 context
outOutput buffer

Definition at line 320 of file tls.c.

320  {
321  struct md5_sha1_context *context = ctx;
322  struct md5_sha1_digest *digest = out;
323 
324  digest_final ( &md5_algorithm, context->md5, digest->md5 );
325  digest_final ( &sha1_algorithm, context->sha1, digest->sha1 );
326 }
An MD5+SHA1 context.
Definition: tls.h:311
uint8_t sha1[SHA1_DIGEST_SIZE]
SHA-1 digest.
Definition: tls.h:326
uint8_t md5[MD5_DIGEST_SIZE]
MD5 digest.
Definition: tls.h:324
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:207
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
__be32 out[4]
Definition: CIB_PRM.h:36
An MD5+SHA1 digest.
Definition: tls.h:322
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:315
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:313
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257

References ctx, digest_final(), md5_sha1_context::md5, md5_sha1_digest::md5, md5_algorithm, out, md5_sha1_context::sha1, md5_sha1_digest::sha1, and sha1_algorithm.

◆ free_tls_session()

static void free_tls_session ( struct refcnt refcnt)
static

Free TLS session.

Parameters
refcntReference counter

Definition at line 358 of file tls.c.

358  {
359  struct tls_session *session =
360  container_of ( refcnt, struct tls_session, refcnt );
361 
362  /* Sanity check */
363  assert ( list_empty ( &session->conn ) );
364 
365  /* Remove from list of sessions */
366  list_del ( &session->list );
367 
368  /* Free dynamically-allocated resources */
369  x509_root_put ( session->root );
370  privkey_put ( session->key );
371  free ( session->ticket );
372 
373  /* Free session */
374  free ( session );
375 }
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition: privkey.h:41
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition: x509.h:403
A reference counter.
Definition: refcnt.h:26
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct list_head list
List of sessions.
Definition: tls.h:337
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * ticket
Session ticket.
Definition: tls.h:351
A TLS session.
Definition: tls.h:333
struct x509_root * root
Root of trust.
Definition: tls.h:342
struct private_key * key
Private key.
Definition: tls.h:344
struct list_head conn
List of connections.
Definition: tls.h:360

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

Referenced by tls_session().

◆ free_tls()

static void free_tls ( struct refcnt refcnt)
static

Free TLS connection.

Parameters
refcntReference counter

Definition at line 382 of file tls.c.

382  {
383  struct tls_connection *tls =
385  struct tls_session *session = tls->session;
386  struct io_buffer *iobuf;
387  struct io_buffer *tmp;
388 
389  /* Free dynamically-allocated resources */
390  free ( tls->new_session_ticket );
391  tls_clear_cipher ( tls, &tls->tx.cipherspec.active );
392  tls_clear_cipher ( tls, &tls->tx.cipherspec.pending );
393  tls_clear_cipher ( tls, &tls->rx.cipherspec.active );
394  tls_clear_cipher ( tls, &tls->rx.cipherspec.pending );
395  free ( tls->server.exchange );
396  free ( tls->handshake_ctx );
397  list_for_each_entry_safe ( iobuf, tmp, &tls->rx.data, list ) {
398  list_del ( &iobuf->list );
399  free_iob ( iobuf );
400  }
401  free_iob ( tls->rx.handshake );
402  privkey_put ( tls->client.key );
403  x509_chain_put ( tls->client.chain );
404  x509_chain_put ( tls->server.chain );
405  x509_root_put ( tls->server.root );
406 
407  /* Drop reference to session */
408  assert ( list_empty ( &tls->list ) );
409  ref_put ( &session->refcnt );
410 
411  /* Free TLS structure itself */
412  free ( tls );
413 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:299
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition: privkey.h:41
struct tls_session * session
Session.
Definition: tls.h:433
struct list_head data
List of received data buffers.
Definition: tls.h:388
struct io_buffer * handshake
Received handshake fragment.
Definition: tls.h:390
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:378
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:410
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition: x509.h:403
A reference counter.
Definition: refcnt.h:26
struct private_key * key
Private key (if used)
Definition: tls.h:398
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:64
struct tls_server server
Server state.
Definition: tls.h:472
struct refcnt refcnt
Reference counter.
Definition: tls.h:335
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:457
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
void * new_session_ticket
New session ticket.
Definition: tls.h:441
struct tls_client client
Client state.
Definition: tls.h:470
struct list_head list
List of connections within the same session.
Definition: tls.h:435
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
#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:458
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct x509_chain * chain
Certificate chain.
Definition: tls.h:416
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:268
struct tls_rx rx
Receive state.
Definition: tls.h:468
struct tls_tx tx
Transmit state.
Definition: tls.h:466
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
A TLS session.
Definition: tls.h:333
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:400
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:266
A TLS connection.
Definition: tls.h:428
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
A persistent I/O buffer.
Definition: iobuf.h:37
struct x509_root * root
Root of trust.
Definition: tls.h:414

References tls_cipherspec_pair::active, assert(), tls_client::chain, tls_server::chain, tls_tx::cipherspec, tls_rx::cipherspec, tls_connection::client, container_of, tls_rx::data, tls_server::exchange, free, free_iob(), tls_rx::handshake, tls_connection::handshake_ctx, 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(), tmp, tls_connection::tx, x509_chain_put(), and x509_root_put().

Referenced by add_tls().

◆ tls_close()

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

Finish with TLS connection.

Parameters
tlsTLS connection
rcStatus code

Definition at line 421 of file tls.c.

421  {
422 
423  /* Remove pending operations, if applicable */
424  pending_put ( &tls->client.negotiation );
425  pending_put ( &tls->server.negotiation );
426  pending_put ( &tls->server.validation );
427 
428  /* Remove process */
429  process_del ( &tls->tx.process );
430 
431  /* Close all interfaces */
432  intf_shutdown ( &tls->cipherstream, rc );
433  intf_shutdown ( &tls->plainstream, rc );
434  intf_shutdown ( &tls->server.validator, rc );
435 
436  /* Remove from session */
437  list_del ( &tls->list );
438  INIT_LIST_HEAD ( &tls->list );
439 
440  /* Resume all other connections, in case we were the lead connection */
441  tls_tx_resume_all ( tls->session );
442 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void tls_tx_resume_all(struct tls_session *session)
Resume TX state machine for all connections within a session.
Definition: tls.c:1118
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:278
struct process process
Transmit process.
Definition: tls.h:372
struct tls_session * session
Session.
Definition: tls.h:433
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:402
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
struct tls_server server
Server state.
Definition: tls.h:472
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
struct tls_client client
Client state.
Definition: tls.h:470
struct list_head list
List of connections within the same session.
Definition: tls.h:435
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:448
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:424
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:422
struct tls_tx tx
Transmit state.
Definition: tls.h:466
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
struct interface validator
Certificate validator.
Definition: tls.h:420
struct interface plainstream
Plaintext stream.
Definition: tls.h:446

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_tx_resume_all(), tls_connection::tx, tls_server::validation, and tls_server::validator.

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

◆ tls_generate_random()

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

Generate random data.

Parameters
tlsTLS connection
dataBuffer to fill
lenLength of buffer
Return values
rcReturn status code

Definition at line 459 of file tls.c.

460  {
461  int rc;
462 
463  /* Generate random bits with no additional input and without
464  * prediction resistance
465  */
466  if ( ( rc = rbg_generate ( NULL, 0, 0, data, len ) ) != 0 ) {
467  DBGC ( tls, "TLS %p could not generate random data: %s\n",
468  tls, strerror ( rc ) );
469  return rc;
470  }
471 
472  return 0;
473 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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:116
#define DBGC(...)
Definition: compiler.h:505
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References data, DBGC, len, NULL, rbg_generate(), rc, and strerror().

Referenced by add_tls(), tls_send_client_key_exchange_dhe(), tls_send_client_key_exchange_ecdhe(), tls_send_client_key_exchange_pubkey(), and tls_send_record().

◆ tls_hmac_update_va()

static 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 482 of file tls.c.

483  {
484  void *data;
485  size_t len;
486 
487  while ( ( data = va_arg ( args, void * ) ) ) {
488  len = va_arg ( args, size_t );
489  hmac_update ( digest, ctx, data, len );
490  }
491 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define va_arg(ap, type)
Definition: stdarg.h:8
ring len
Length.
Definition: dwmac.h:231
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

Referenced by tls_p_hash_va().

◆ tls_p_hash_va()

static void tls_p_hash_va ( struct tls_connection tls,
struct digest_algorithm digest,
const void *  secret,
size_t  secret_len,
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
secretSecret
secret_lenLength of secret
outOutput buffer
out_lenLength of output buffer
seeds( data, len ) pairs of seed data, terminated by NULL

Definition at line 504 of file tls.c.

508  {
509  uint8_t ctx[ hmac_ctxsize ( digest ) ];
510  uint8_t ctx_partial[ sizeof ( ctx ) ];
511  uint8_t a[digest->digestsize];
512  uint8_t out_tmp[digest->digestsize];
513  size_t frag_len = digest->digestsize;
514  va_list tmp;
515 
516  DBGC2 ( tls, "TLS %p %s secret:\n", tls, digest->name );
517  DBGC2_HD ( tls, secret, secret_len );
518 
519  /* Calculate A(1) */
520  hmac_init ( digest, ctx, secret, secret_len );
521  va_copy ( tmp, seeds );
522  tls_hmac_update_va ( digest, ctx, tmp );
523  va_end ( tmp );
524  hmac_final ( digest, ctx, a );
525  DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name );
526  DBGC2_HD ( tls, &a, sizeof ( a ) );
527 
528  /* Generate as much data as required */
529  while ( out_len ) {
530  /* Calculate output portion */
531  hmac_init ( digest, ctx, secret, secret_len );
532  hmac_update ( digest, ctx, a, sizeof ( a ) );
533  memcpy ( ctx_partial, ctx, sizeof ( ctx_partial ) );
534  va_copy ( tmp, seeds );
535  tls_hmac_update_va ( digest, ctx, tmp );
536  va_end ( tmp );
537  hmac_final ( digest, ctx, out_tmp );
538 
539  /* Copy output */
540  if ( frag_len > out_len )
541  frag_len = out_len;
542  memcpy ( out, out_tmp, frag_len );
543  DBGC2 ( tls, "TLS %p %s output:\n", tls, digest->name );
544  DBGC2_HD ( tls, out, frag_len );
545 
546  /* Calculate A(i) */
547  hmac_final ( digest, ctx_partial, a );
548  DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name );
549  DBGC2_HD ( tls, &a, sizeof ( a ) );
550 
551  out += frag_len;
552  out_len -= frag_len;
553  }
554 }
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition: hmac.c:57
#define va_end(ap)
Definition: stdarg.h:9
#define va_copy(dest, src)
Definition: stdarg.h:10
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
__be32 out[4]
Definition: CIB_PRM.h:36
unsigned long tmp
Definition: linux_pci.h:64
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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:482
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition: hmac.h:28
#define DBGC2_HD(...)
Definition: compiler.h:524
unsigned char uint8_t
Definition: stdint.h:10
#define DBGC2(...)
Definition: compiler.h:522
__builtin_va_list va_list
Definition: stdarg.h:6
size_t digestsize
Digest size.
Definition: crypto.h:26
const char * name
Algorithm name.
Definition: crypto.h:20
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition: hmac.c:87

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

Referenced by tls_prf().

◆ tls_prf()

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

Generate secure pseudo-random data.

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

Definition at line 566 of file tls.c.

567  {
568  va_list seeds;
569  va_list tmp;
570  size_t subsecret_len;
571  const void *md5_secret;
572  const void *sha1_secret;
573  uint8_t buf[out_len];
574  unsigned int i;
575 
576  va_start ( seeds, out_len );
577 
578  if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
579  /* Use handshake digest PRF for TLSv1.2 and later */
580  tls_p_hash_va ( tls, tls->handshake_digest, secret, secret_len,
581  out, out_len, seeds );
582  } else {
583  /* Use combination of P_MD5 and P_SHA-1 for TLSv1.1
584  * and earlier
585  */
586 
587  /* Split secret into two, with an overlap of up to one byte */
588  subsecret_len = ( ( secret_len + 1 ) / 2 );
589  md5_secret = secret;
590  sha1_secret = ( secret + secret_len - subsecret_len );
591 
592  /* Calculate MD5 portion */
593  va_copy ( tmp, seeds );
594  tls_p_hash_va ( tls, &md5_algorithm, md5_secret,
595  subsecret_len, out, out_len, seeds );
596  va_end ( tmp );
597 
598  /* Calculate SHA1 portion */
599  va_copy ( tmp, seeds );
600  tls_p_hash_va ( tls, &sha1_algorithm, sha1_secret,
601  subsecret_len, buf, out_len, seeds );
602  va_end ( tmp );
603 
604  /* XOR the two portions together into the final output buffer */
605  for ( i = 0 ; i < out_len ; i++ )
606  *( ( uint8_t * ) out + i ) ^= buf[i];
607  }
608 
609  va_end ( seeds );
610 }
#define va_end(ap)
Definition: stdarg.h:9
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
#define va_copy(dest, src)
Definition: stdarg.h:10
__be32 out[4]
Definition: CIB_PRM.h:36
unsigned long tmp
Definition: linux_pci.h:64
unsigned char uint8_t
Definition: stdint.h:10
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:276
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
__builtin_va_list va_list
Definition: stdarg.h:6
static void tls_p_hash_va(struct tls_connection *tls, struct digest_algorithm *digest, const void *secret, size_t secret_len, void *out, size_t out_len, va_list seeds)
Generate secure pseudo-random data using a single hash function.
Definition: tls.c:504
#define va_start(ap, last)
Definition: stdarg.h:7
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257

References tls_connection::handshake_digest, md5_algorithm, out, sha1_algorithm, tls_p_hash_va(), tls_version(), TLS_VERSION_TLS_1_2, tmp, va_copy, va_end, and va_start.

◆ tls_generate_master_secret()

static void tls_generate_master_secret ( struct tls_connection tls,
const void *  pre_master_secret,
size_t  pre_master_secret_len 
)
static

Generate master secret.

Parameters
tlsTLS connection
pre_master_secretPre-master secret
pre_master_secret_lenLength of pre-master secret

The client and server random values must already be known.

Definition at line 642 of file tls.c.

644  {
645  struct digest_algorithm *digest = tls->handshake_digest;
646  uint8_t digest_out[ digest->digestsize ];
647 
648  /* Generate handshake digest */
649  tls_verify_handshake ( tls, digest_out );
650 
651  /* Show inputs */
652  DBGC ( tls, "TLS %p pre-master secret:\n", tls );
653  DBGC_HD ( tls, pre_master_secret, pre_master_secret_len );
654  DBGC ( tls, "TLS %p client random bytes:\n", tls );
655  DBGC_HD ( tls, &tls->client.random, sizeof ( tls->client.random ) );
656  DBGC ( tls, "TLS %p server random bytes:\n", tls );
657  DBGC_HD ( tls, &tls->server.random, sizeof ( tls->server.random ) );
658  DBGC ( tls, "TLS %p session hash:\n", tls );
659  DBGC_HD ( tls, digest_out, sizeof ( digest_out ) );
660 
661  /* Generate master secret */
662  if ( tls->extended_master_secret ) {
663  tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
664  &tls->master_secret,
665  sizeof ( tls->master_secret ),
666  "extended master secret",
667  digest_out, sizeof ( digest_out ) );
668  } else {
669  tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
670  &tls->master_secret,
671  sizeof ( tls->master_secret ),
672  "master secret",
673  &tls->client.random,
674  sizeof ( tls->client.random ),
675  &tls->server.random,
676  sizeof ( tls->server.random ) );
677  }
678 
679  /* Show output */
680  DBGC ( tls, "TLS %p generated %smaster secret:\n", tls,
681  ( tls->extended_master_secret ? "extended ": "" ) );
682  DBGC_HD ( tls, &tls->master_secret, sizeof ( tls->master_secret ) );
683 }
uint8_t random[32]
Random bytes.
Definition: tls.h:408
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:834
#define DBGC(...)
Definition: compiler.h:505
struct tls_server server
Server state.
Definition: tls.h:472
struct tls_client client
Client state.
Definition: tls.h:470
int extended_master_secret
Extended master secret flag.
Definition: tls.h:461
uint8_t master_secret[48]
Master secret.
Definition: tls.h:453
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
size_t digestsize
Digest size.
Definition: crypto.h:26
A message digest algorithm.
Definition: crypto.h:18
struct tls_client_random random
Random bytes.
Definition: tls.h:396
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:622

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

Referenced by tls_send_client_key_exchange_dhe(), tls_send_client_key_exchange_ecdhe(), and tls_send_client_key_exchange_pubkey().

◆ tls_generate_keys()

static 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 692 of file tls.c.

692  {
693  struct tls_cipherspec *tx_cipherspec = &tls->tx.cipherspec.pending;
694  struct tls_cipherspec *rx_cipherspec = &tls->rx.cipherspec.pending;
695  size_t hash_size = tx_cipherspec->suite->mac_len;
696  size_t key_size = tx_cipherspec->suite->key_len;
697  size_t iv_size = tx_cipherspec->suite->fixed_iv_len;
698  size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
699  uint8_t key_block[total];
700  uint8_t *key;
701  int rc;
702 
703  /* Generate key block */
704  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
705  key_block, sizeof ( key_block ), "key expansion",
706  &tls->server.random, sizeof ( tls->server.random ),
707  &tls->client.random, sizeof ( tls->client.random ) );
708 
709  /* Split key block into portions */
710  key = key_block;
711 
712  /* TX MAC secret */
713  memcpy ( tx_cipherspec->mac_secret, key, hash_size );
714  DBGC ( tls, "TLS %p TX MAC secret:\n", tls );
715  DBGC_HD ( tls, key, hash_size );
716  key += hash_size;
717 
718  /* RX MAC secret */
719  memcpy ( rx_cipherspec->mac_secret, key, hash_size );
720  DBGC ( tls, "TLS %p RX MAC secret:\n", tls );
721  DBGC_HD ( tls, key, hash_size );
722  key += hash_size;
723 
724  /* TX key */
725  if ( ( rc = cipher_setkey ( tx_cipherspec->suite->cipher,
726  tx_cipherspec->cipher_ctx,
727  key, key_size ) ) != 0 ) {
728  DBGC ( tls, "TLS %p could not set TX key: %s\n",
729  tls, strerror ( rc ) );
730  return rc;
731  }
732  DBGC ( tls, "TLS %p TX key:\n", tls );
733  DBGC_HD ( tls, key, key_size );
734  key += key_size;
735 
736  /* RX key */
737  if ( ( rc = cipher_setkey ( rx_cipherspec->suite->cipher,
738  rx_cipherspec->cipher_ctx,
739  key, key_size ) ) != 0 ) {
740  DBGC ( tls, "TLS %p could not set TX key: %s\n",
741  tls, strerror ( rc ) );
742  return rc;
743  }
744  DBGC ( tls, "TLS %p RX key:\n", tls );
745  DBGC_HD ( tls, key, key_size );
746  key += key_size;
747 
748  /* TX initialisation vector */
749  memcpy ( tx_cipherspec->fixed_iv, key, iv_size );
750  DBGC ( tls, "TLS %p TX IV:\n", tls );
751  DBGC_HD ( tls, key, iv_size );
752  key += iv_size;
753 
754  /* RX initialisation vector */
755  memcpy ( rx_cipherspec->fixed_iv, key, iv_size );
756  DBGC ( tls, "TLS %p RX IV:\n", tls );
757  DBGC_HD ( tls, key, iv_size );
758  key += iv_size;
759 
760  assert ( ( key_block + total ) == key );
761 
762  return 0;
763 }
uint8_t random[32]
Random bytes.
Definition: tls.h:408
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:378
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:250
struct tls_server server
Server state.
Definition: tls.h:472
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:470
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:256
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:208
uint8_t master_secret[48]
Master secret.
Definition: tls.h:453
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC_HD(...)
Definition: compiler.h:507
uint8_t mac_len
MAC length.
Definition: tls.h:212
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:268
struct tls_rx rx
Receive state.
Definition: tls.h:468
struct tls_tx tx
Transmit state.
Definition: tls.h:466
struct tls_client_random random
Random bytes.
Definition: tls.h:396
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:198
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:622
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:260
union @391 key
Sense key.
Definition: scsi.h:17
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:212
void * mac_secret
MAC secret.
Definition: tls.h:258
uint8_t key_len
Key length.
Definition: tls.h:206

References assert(), tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_setkey(), tls_tx::cipherspec, tls_rx::cipherspec, tls_connection::client, DBGC, DBGC_HD, tls_cipherspec::fixed_iv, tls_cipher_suite::fixed_iv_len, key, tls_cipher_suite::key_len, tls_cipher_suite::mac_len, tls_cipherspec::mac_secret, tls_connection::master_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_clear_handshake()

static void tls_clear_handshake ( struct tls_connection tls)
static

Clear handshake digest algorithm.

Parameters
tlsTLS connection

Definition at line 777 of file tls.c.

777  {
778 
779  /* Select null digest algorithm */
781 
782  /* Free any existing context */
783  free ( tls->handshake_ctx );
784  tls->handshake_ctx = NULL;
785 }
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:457
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct digest_algorithm digest_null
Definition: crypto_null.c:48
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References digest_null, free, tls_connection::handshake_ctx, tls_connection::handshake_digest, and NULL.

Referenced by add_tls(), and tls_select_handshake().

◆ tls_select_handshake()

static int tls_select_handshake ( struct tls_connection tls,
struct digest_algorithm digest 
)
static

Select handshake digest algorithm.

Parameters
tlsTLS connection
digestHandshake digest algorithm
Return values
rcReturn status code

Definition at line 794 of file tls.c.

795  {
796 
797  /* Clear existing handshake digest */
798  tls_clear_handshake ( tls );
799 
800  /* Allocate and initialise context */
801  tls->handshake_ctx = malloc ( digest->ctxsize );
802  if ( ! tls->handshake_ctx )
803  return -ENOMEM;
804  tls->handshake_digest = digest;
805  digest_init ( digest, tls->handshake_ctx );
806 
807  return 0;
808 }
#define ENOMEM
Not enough space.
Definition: errno.h:534
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:457
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:196
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
size_t ctxsize
Context size.
Definition: crypto.h:22
static void tls_clear_handshake(struct tls_connection *tls)
Clear handshake digest algorithm.
Definition: tls.c:777

References digest_algorithm::ctxsize, digest_init(), ENOMEM, tls_connection::handshake_ctx, tls_connection::handshake_digest, malloc(), and tls_clear_handshake().

Referenced by tls_select_cipher().

◆ tls_add_handshake()

static 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 818 of file tls.c.

819  {
820  struct digest_algorithm *digest = tls->handshake_digest;
821 
822  digest_update ( digest, tls->handshake_ctx, data, len );
823  return 0;
824 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:201
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:457
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References data, digest_update(), tls_connection::handshake_ctx, tls_connection::handshake_digest, and len.

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

◆ tls_find_cipher_suite()

static 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 867 of file tls.c.

867  {
868  struct tls_cipher_suite *suite;
869 
870  /* Identify cipher suite */
872  if ( suite->code == cipher_suite )
873  return suite;
874  }
875 
876  return NULL;
877 }
A TLS cipher suite.
Definition: tls.h:192
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:216
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:204

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

Referenced by tls_select_cipher().

◆ tls_clear_cipher() [2/2]

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

Clear cipher suite.

Parameters
cipherspecTLS cipher specification

Definition at line 884 of file tls.c.

885  {
886 
887  free ( cipherspec->dynamic );
888  memset ( cipherspec, 0, sizeof ( *cipherspec ) );
889  cipherspec->suite = &tls_cipher_suite_null;
890 }
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:850
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:254
void * memset(void *dest, int character, size_t len) __nonnull

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

◆ tls_set_cipher()

static 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 900 of file tls.c.

902  {
903  struct cipher_algorithm *cipher = suite->cipher;
904  size_t total;
905  void *dynamic;
906 
907  /* Clear out old cipher contents, if any */
908  tls_clear_cipher ( tls, cipherspec );
909 
910  /* Allocate dynamic storage */
911  total = ( cipher->ctxsize + suite->mac_len + suite->fixed_iv_len );
912  dynamic = zalloc ( total );
913  if ( ! dynamic ) {
914  DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto "
915  "context\n", tls, total );
916  return -ENOMEM_CONTEXT;
917  }
918 
919  /* Assign storage */
920  cipherspec->dynamic = dynamic;
921  cipherspec->cipher_ctx = dynamic; dynamic += cipher->ctxsize;
922  cipherspec->mac_secret = dynamic; dynamic += suite->mac_len;
923  cipherspec->fixed_iv = dynamic; dynamic += suite->fixed_iv_len;
924  assert ( ( cipherspec->dynamic + total ) == dynamic );
925 
926  /* Store parameters */
927  cipherspec->suite = suite;
928 
929  return 0;
930 }
#define DBGC(...)
Definition: compiler.h:505
#define ENOMEM_CONTEXT
Definition: tls.c:118
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:256
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:208
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
uint8_t mac_len
MAC length.
Definition: tls.h:212
size_t ctxsize
Context size.
Definition: crypto.h:54
A cipher algorithm.
Definition: crypto.h:50
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:198
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:254
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:260
void * mac_secret
MAC secret.
Definition: tls.h:258

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()

static 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 939 of file tls.c.

940  {
941  struct tls_cipher_suite *suite;
942  struct digest_algorithm *digest;
943  int rc;
944 
945  /* Identify cipher suite */
946  suite = tls_find_cipher_suite ( cipher_suite );
947  if ( ! suite ) {
948  DBGC ( tls, "TLS %p does not support cipher %04x\n",
949  tls, ntohs ( cipher_suite ) );
950  return -ENOTSUP_CIPHER;
951  }
952 
953  /* Set handshake digest algorithm */
954  digest = ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ?
955  suite->handshake : &md5_sha1_algorithm );
956  if ( ( rc = tls_select_handshake ( tls, digest ) ) != 0 )
957  return rc;
958 
959  /* Set ciphers */
960  if ( ( rc = tls_set_cipher ( tls, &tls->tx.cipherspec.pending,
961  suite ) ) != 0 )
962  return rc;
963  if ( ( rc = tls_set_cipher ( tls, &tls->rx.cipherspec.pending,
964  suite ) ) != 0 )
965  return rc;
966 
967  DBGC ( tls, "TLS %p selected %s-%s-%s-%d-%s\n", tls,
968  suite->exchange->name, suite->pubkey->name,
969  suite->cipher->name, ( suite->key_len * 8 ),
970  suite->digest->name );
971 
972  return 0;
973 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:194
static struct tls_cipher_suite * tls_find_cipher_suite(unsigned int cipher_suite)
Identify cipher suite.
Definition: tls.c:867
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:378
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
#define ntohs(value)
Definition: byteswap.h:136
const char * name
Algorithm name.
Definition: tls.h:181
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:196
#define ENOTSUP_CIPHER
Definition: tls.c:146
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:200
A TLS cipher suite.
Definition: tls.h:192
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:329
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:268
struct tls_rx rx
Receive state.
Definition: tls.h:468
struct tls_tx tx
Transmit state.
Definition: tls.h:466
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:276
const char * name
Algorithm name.
Definition: crypto.h:20
struct digest_algorithm * handshake
Handshake digest algorithm (for TLSv1.2 and above)
Definition: tls.h:202
A message digest algorithm.
Definition: crypto.h:18
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:198
const char * name
Algorithm name.
Definition: crypto.h:52
static int tls_set_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
Set cipher suite.
Definition: tls.c:900
static int tls_select_handshake(struct tls_connection *tls, struct digest_algorithm *digest)
Select handshake digest algorithm.
Definition: tls.c:794
const char * name
Algorithm name.
Definition: crypto.h:123
uint8_t key_len
Key length.
Definition: tls.h:206

References tls_cipher_suite::cipher, tls_tx::cipherspec, tls_rx::cipherspec, DBGC, tls_cipher_suite::digest, ENOTSUP_CIPHER, tls_cipher_suite::exchange, tls_cipher_suite::handshake, tls_cipher_suite::key_len, md5_sha1_algorithm, digest_algorithm::name, cipher_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_select_handshake(), tls_set_cipher(), tls_version(), TLS_VERSION_TLS_1_2, and tls_connection::tx.

Referenced by tls_new_server_hello().

◆ tls_change_cipher()

static 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 982 of file tls.c.

983  {
984 
985  /* Sanity check */
986  if ( pair->pending.suite == &tls_cipher_suite_null ) {
987  DBGC ( tls, "TLS %p refusing to use null cipher\n", tls );
988  return -ENOTSUP_NULL;
989  }
990 
991  tls_clear_cipher ( tls, &pair->active );
992  memswap ( &pair->active, &pair->pending, sizeof ( pair->active ) );
993  return 0;
994 }
void * memswap(void *first, void *second, size_t len)
Swap memory regions.
Definition: string.c:153
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:850
#define DBGC(...)
Definition: compiler.h:505
#define ENOTSUP_NULL
Definition: tls.c:150
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:268
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:266
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)

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()

static 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 1015 of file tls.c.

1016  {
1017  struct tls_signature_hash_algorithm *sig_hash;
1018 
1019  /* Identify signature and hash algorithm */
1021  if ( ( sig_hash->pubkey == pubkey ) &&
1022  ( sig_hash->digest == digest ) ) {
1023  return sig_hash;
1024  }
1025  }
1026 
1027  return NULL;
1028 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:282
A TLS signature algorithm.
Definition: tls.h:280
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:294
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:284
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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_signature_hash_pubkey()

static struct pubkey_algorithm* tls_signature_hash_pubkey ( struct tls_signature_hash_id  code)
static

Find TLS signature algorithm.

Parameters
codeSignature and hash algorithm identifier
Return values
pubkeyPublic key algorithm, or NULL

Definition at line 1037 of file tls.c.

1037  {
1038  struct tls_signature_hash_algorithm *sig_hash;
1039 
1040  /* Identify signature and hash algorithm */
1042  if ( sig_hash->code.signature == code.signature )
1043  return sig_hash->pubkey;
1044  }
1045 
1046  return NULL;
1047 }
static unsigned int code
Response code.
Definition: hyperv.h:26
A TLS signature algorithm.
Definition: tls.h:280
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
uint8_t signature
Signature algorithm.
Definition: tls.h:276
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:294
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:286
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:284
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References code, tls_signature_hash_algorithm::code, for_each_table_entry, NULL, tls_signature_hash_algorithm::pubkey, tls_signature_hash_id::signature, and TLS_SIG_HASH_ALGORITHMS.

Referenced by tls_verify_dh_params().

◆ tls_signature_hash_digest()

static struct digest_algorithm* tls_signature_hash_digest ( struct tls_signature_hash_id  code)
static

Find TLS hash algorithm.

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

Definition at line 1056 of file tls.c.

1056  {
1057  struct tls_signature_hash_algorithm *sig_hash;
1058 
1059  /* Identify signature and hash algorithm */
1061  if ( sig_hash->code.hash == code.hash )
1062  return sig_hash->digest;
1063  }
1064 
1065  return NULL;
1066 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:282
static unsigned int code
Response code.
Definition: hyperv.h:26
A TLS signature algorithm.
Definition: tls.h:280
uint8_t hash
Hash algorithm.
Definition: tls.h:274
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:294
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:286
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References code, tls_signature_hash_algorithm::code, tls_signature_hash_algorithm::digest, for_each_table_entry, tls_signature_hash_id::hash, NULL, and TLS_SIG_HASH_ALGORITHMS.

Referenced by tls_verify_dh_params().

◆ tls_find_named_curve()

static struct tls_named_curve* tls_find_named_curve ( unsigned int  named_curve)
static

Identify named curve.

Parameters
named_curveNamed curve specification
Return values
curveNamed curve, or NULL

Definition at line 1085 of file tls.c.

1085  {
1086  struct tls_named_curve *curve;
1087 
1088  /* Identify named curve */
1090  if ( curve->code == named_curve )
1091  return curve;
1092  }
1093 
1094  return NULL;
1095 }
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:242
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:232
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
A TLS named curve.
Definition: tls.h:230
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References tls_named_curve::curve, for_each_table_entry, NULL, and TLS_NAMED_CURVES.

Referenced by tls_send_client_key_exchange_ecdhe().

◆ tls_tx_resume()

static void tls_tx_resume ( struct tls_connection tls)
static

Resume TX state machine.

Parameters
tlsTLS connection

Definition at line 1109 of file tls.c.

1109  {
1110  process_add ( &tls->tx.process );
1111 }
struct process process
Transmit process.
Definition: tls.h:372
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
struct tls_tx tx
Transmit state.
Definition: tls.h:466

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()

static void tls_restart ( struct tls_connection tls)
static

Restart negotiation.

Parameters
tlsTLS connection

Definition at line 1130 of file tls.c.

1130  {
1131 
1132  /* Sanity check */
1133  assert ( ! tls->tx.pending );
1134  assert ( ! is_pending ( &tls->client.negotiation ) );
1135  assert ( ! is_pending ( &tls->server.negotiation ) );
1136  assert ( ! is_pending ( &tls->server.validation ) );
1137 
1138  /* (Re)start negotiation */
1140  tls_tx_resume ( tls );
1141  pending_get ( &tls->client.negotiation );
1142  pending_get ( &tls->server.negotiation );
1143 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1109
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:402
struct tls_server server
Server state.
Definition: tls.h:472
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:470
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:424
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:422
unsigned int pending
Pending transmissions.
Definition: tls.h:370
struct tls_tx tx
Transmit state.
Definition: tls.h:466
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45

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

Referenced by add_tls(), and tls_new_hello_request().

◆ tls_send_handshake()

static 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 1153 of file tls.c.

1154  {
1155 
1156  /* Send record */
1157  return tls_send_plaintext ( tls, TLS_TYPE_HANDSHAKE, data, len );
1158 }
ring len
Length.
Definition: dwmac.h:231
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:3195
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:62
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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_client_hello()

static int tls_client_hello ( struct tls_connection tls,
int(*)(struct tls_connection *tls, const void *data, size_t len action 
)
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 1167 of file tls.c.

1170  {
1171  struct tls_session *session = tls->session;
1172  size_t name_len = strlen ( session->name );
1173  struct {
1174  uint16_t type;
1175  uint16_t len;
1176  struct {
1177  uint16_t len;
1178  struct {
1179  uint8_t type;
1180  uint16_t len;
1181  uint8_t name[name_len];
1182  } __attribute__ (( packed )) list[1];
1183  } __attribute__ (( packed )) data;
1184  } __attribute__ (( packed )) *server_name_ext;
1185  struct {
1186  uint16_t type;
1187  uint16_t len;
1188  struct {
1189  uint8_t max;
1190  } __attribute__ (( packed )) data;
1191  } __attribute__ (( packed )) *max_fragment_length_ext;
1192  struct {
1193  uint16_t type;
1194  uint16_t len;
1195  struct {
1196  uint16_t len;
1197  struct tls_signature_hash_id
1199  } __attribute__ (( packed )) data;
1200  } __attribute__ (( packed )) *signature_algorithms_ext;
1201  struct {
1202  uint16_t type;
1203  uint16_t len;
1204  struct {
1205  uint8_t len;
1207  sizeof ( tls->verify.client ) :0 ];
1208  } __attribute__ (( packed )) data;
1209  } __attribute__ (( packed )) *renegotiation_info_ext;
1210  struct {
1211  uint16_t type;
1212  uint16_t len;
1213  struct {
1214  uint8_t data[session->ticket_len];
1215  } __attribute__ (( packed )) data;
1216  } __attribute__ (( packed )) *session_ticket_ext;
1217  struct {
1218  uint16_t type;
1219  uint16_t len;
1220  struct {
1221  uint16_t len;
1223  } __attribute__ (( packed )) data;
1224  } __attribute__ (( packed )) *named_curve_ext;
1225  struct {
1226  uint16_t type;
1227  uint16_t len;
1228  } __attribute__ (( packed )) *extended_master_secret_ext;
1229  struct {
1230  typeof ( *server_name_ext ) server_name;
1231  typeof ( *max_fragment_length_ext ) max_fragment_length;
1232  typeof ( *signature_algorithms_ext ) signature_algorithms;
1233  typeof ( *renegotiation_info_ext ) renegotiation_info;
1234  typeof ( *session_ticket_ext ) session_ticket;
1235  typeof ( *extended_master_secret_ext ) extended_master_secret;
1236  typeof ( *named_curve_ext )
1237  named_curve[TLS_NUM_NAMED_CURVES ? 1 : 0];
1238  } __attribute__ (( packed )) *extensions;
1239  struct {
1240  uint32_t type_length;
1241  uint16_t version;
1242  uint8_t random[32];
1243  uint8_t session_id_len;
1244  uint8_t session_id[tls->session_id_len];
1245  uint16_t cipher_suite_len;
1246  uint16_t cipher_suites[TLS_NUM_CIPHER_SUITES];
1247  uint8_t compression_methods_len;
1248  uint8_t compression_methods[1];
1249  uint16_t extensions_len;
1250  typeof ( *extensions ) extensions;
1251  } __attribute__ (( packed )) hello;
1252  struct tls_cipher_suite *suite;
1253  struct tls_signature_hash_algorithm *sighash;
1254  struct tls_named_curve *curve;
1255  unsigned int i;
1256 
1257  /* Construct record */
1258  memset ( &hello, 0, sizeof ( hello ) );
1259  hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) |
1260  htonl ( sizeof ( hello ) -
1261  sizeof ( hello.type_length ) ) );
1262  hello.version = htons ( TLS_VERSION_MAX );
1263  memcpy ( &hello.random, &tls->client.random, sizeof ( hello.random ) );
1264  hello.session_id_len = tls->session_id_len;
1265  memcpy ( hello.session_id, tls->session_id,
1266  sizeof ( hello.session_id ) );
1267  hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) );
1268  i = 0 ; for_each_table_entry ( suite, TLS_CIPHER_SUITES )
1269  hello.cipher_suites[i++] = suite->code;
1270  hello.compression_methods_len = sizeof ( hello.compression_methods );
1271  hello.extensions_len = htons ( sizeof ( hello.extensions ) );
1272  extensions = &hello.extensions;
1273 
1274  /* Construct server name extension */
1275  server_name_ext = &extensions->server_name;
1276  server_name_ext->type = htons ( TLS_SERVER_NAME );
1277  server_name_ext->len = htons ( sizeof ( server_name_ext->data ) );
1278  server_name_ext->data.len
1279  = htons ( sizeof ( server_name_ext->data.list ) );
1280  server_name_ext->data.list[0].type = TLS_SERVER_NAME_HOST_NAME;
1281  server_name_ext->data.list[0].len
1282  = htons ( sizeof ( server_name_ext->data.list[0].name ) );
1283  memcpy ( server_name_ext->data.list[0].name, session->name,
1284  sizeof ( server_name_ext->data.list[0].name ) );
1285 
1286  /* Construct maximum fragment length extension */
1287  max_fragment_length_ext = &extensions->max_fragment_length;
1288  max_fragment_length_ext->type = htons ( TLS_MAX_FRAGMENT_LENGTH );
1289  max_fragment_length_ext->len
1290  = htons ( sizeof ( max_fragment_length_ext->data ) );
1291  max_fragment_length_ext->data.max = TLS_MAX_FRAGMENT_LENGTH_VALUE;
1292 
1293  /* Construct supported signature algorithms extension */
1294  signature_algorithms_ext = &extensions->signature_algorithms;
1295  signature_algorithms_ext->type = htons ( TLS_SIGNATURE_ALGORITHMS );
1296  signature_algorithms_ext->len
1297  = htons ( sizeof ( signature_algorithms_ext->data ) );
1298  signature_algorithms_ext->data.len
1299  = htons ( sizeof ( signature_algorithms_ext->data.code ) );
1300  i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
1301  signature_algorithms_ext->data.code[i++] = sighash->code;
1302 
1303  /* Construct renegotiation information extension */
1304  renegotiation_info_ext = &extensions->renegotiation_info;
1305  renegotiation_info_ext->type = htons ( TLS_RENEGOTIATION_INFO );
1306  renegotiation_info_ext->len
1307  = htons ( sizeof ( renegotiation_info_ext->data ) );
1308  renegotiation_info_ext->data.len
1309  = sizeof ( renegotiation_info_ext->data.data );
1310  memcpy ( renegotiation_info_ext->data.data, tls->verify.client,
1311  sizeof ( renegotiation_info_ext->data.data ) );
1312 
1313  /* Construct session ticket extension */
1314  session_ticket_ext = &extensions->session_ticket;
1315  session_ticket_ext->type = htons ( TLS_SESSION_TICKET );
1316  session_ticket_ext->len
1317  = htons ( sizeof ( session_ticket_ext->data ) );
1318  memcpy ( session_ticket_ext->data.data, session->ticket,
1319  sizeof ( session_ticket_ext->data.data ) );
1320 
1321  /* Construct extended master secret extension */
1322  extended_master_secret_ext = &extensions->extended_master_secret;
1323  extended_master_secret_ext->type
1325  extended_master_secret_ext->len = 0;
1326 
1327  /* Construct named curves extension, if applicable */
1328  if ( sizeof ( extensions->named_curve ) ) {
1329  named_curve_ext = &extensions->named_curve[0];
1330  named_curve_ext->type = htons ( TLS_NAMED_CURVE );
1331  named_curve_ext->len
1332  = htons ( sizeof ( named_curve_ext->data ) );
1333  named_curve_ext->data.len
1334  = htons ( sizeof ( named_curve_ext->data.code ) );
1336  named_curve_ext->data.code[i++] = curve->code;
1337  }
1338 
1339  return action ( tls, &hello, sizeof ( hello ) );
1340 }
#define TLS_MAX_FRAGMENT_LENGTH_VALUE
Advertised maximum fragment length.
Definition: tls.h:476
struct tls_verify_data verify
Verification data.
Definition: tls.h:463
#define __attribute__(x)
Definition: compiler.h:10
unsigned short uint16_t
Definition: stdint.h:11
#define TLS_NUM_CIPHER_SUITES
Number of supported cipher suites.
Definition: tls.c:858
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:144
#define max(x, y)
Definition: ath.h:40
struct tls_session * session
Session.
Definition: tls.h:433
#define TLS_NUM_NAMED_CURVES
Number of supported named curves.
Definition: tls.c:1076
uint32_t type
Operating system type.
Definition: ena.h:12
#define TLS_CLIENT_HELLO
Definition: tls.h:69
uint8_t session_id[32]
Session ID.
Definition: tls.h:437
static unsigned int code
Response code.
Definition: hyperv.h:26
#define htonl(value)
Definition: byteswap.h:133
#define TLS_MAX_FRAGMENT_LENGTH
Definition: tls.h:122
#define TLS_NAMED_CURVE
Definition: tls.h:129
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Driver version.
Definition: ath9k_hw.c:1983
struct tls_client client
Client state.
Definition: tls.h:470
#define TLS_SESSION_TICKET
Definition: tls.h:141
ring len
Length.
Definition: dwmac.h:231
A TLS cipher suite.
Definition: tls.h:192
#define TLS_SERVER_NAME
Definition: tls.h:118
A TLS signature algorithm.
Definition: tls.h:280
size_t ticket_len
Length of session ticket.
Definition: tls.h:353
struct list_head list
List of sessions.
Definition: tls.h:337
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:242
#define TLS_NUM_SIG_HASH_ALGORITHMS
Number of supported signature and hash algorithms.
Definition: tls.c:1004
void * ticket
Session ticket.
Definition: tls.h:351
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:232
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:294
uint16_t hello
Hello time.
Definition: stp.h:38
unsigned int uint32_t
Definition: stdint.h:12
#define TLS_EXTENDED_MASTER_SECRET
Definition: tls.h:138
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:286
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
#define TLS_SERVER_NAME_HOST_NAME
Definition: tls.h:119
uint8_t client[12]
Client verification data.
Definition: tls.h:157
A TLS session.
Definition: tls.h:333
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct tls_client_random random
Random bytes.
Definition: tls.h:396
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:459
A TLS named curve.
Definition: tls.h:230
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:47
const char * name
Server name.
Definition: tls.h:340
A TLS signature and hash algorithm identifier.
Definition: tls.h:272
size_t session_id_len
Length of session ID.
Definition: tls.h:439
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:216
#define htons(value)
Definition: byteswap.h:135
#define TLS_SIGNATURE_ALGORITHMS
Definition: tls.h:135
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:204
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, tls_verify_data::client, tls_connection::client, code, tls_cipher_suite::code, tls_signature_hash_algorithm::code, cpu_to_le32, tls_named_curve::curve, data, for_each_table_entry, hello, htonl, htons, len, tls_session::list, max, memcpy(), memset(), 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_CURVE, TLS_NAMED_CURVES, TLS_NUM_CIPHER_SUITES, TLS_NUM_NAMED_CURVES, 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()

static 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 1348 of file tls.c.

1348  {
1349 
1350  return tls_client_hello ( tls, tls_send_handshake );
1351 }
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1153
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:1167

References tls_client_hello(), and tls_send_handshake().

Referenced by tls_tx_step().

◆ tls_send_certificate()

static int tls_send_certificate ( struct tls_connection tls)
static

Transmit Certificate record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1359 of file tls.c.

1359  {
1360  struct {
1361  tls24_t length;
1362  uint8_t data[0];
1363  } __attribute__ (( packed )) *certificate;
1364  struct {
1365  uint32_t type_length;
1366  tls24_t length;
1367  typeof ( *certificate ) certificates[0];
1368  } __attribute__ (( packed )) *certificates;
1369  struct x509_link *link;
1370  struct x509_certificate *cert;
1371  struct io_buffer *iobuf;
1372  size_t len;
1373 
1374  /* Calculate length of client certificates */
1375  len = 0;
1377  cert = link->cert;
1378  len += ( sizeof ( *certificate ) + cert->raw.len );
1379  DBGC ( tls, "TLS %p sending client certificate %s\n",
1380  tls, x509_name ( cert ) );
1381  }
1382 
1383  /* Allocate storage for Certificate record (which may be too
1384  * large for the stack).
1385  */
1386  iobuf = tls_alloc_iob ( tls, ( sizeof ( *certificates ) + len ) );
1387  if ( ! iobuf )
1388  return -ENOMEM_CERTIFICATE;
1389 
1390  /* Populate record */
1391  certificates = iob_put ( iobuf, sizeof ( *certificates ) );
1392  certificates->type_length =
1394  htonl ( sizeof ( *certificates ) + len -
1395  sizeof ( certificates->type_length ) ) );
1396  tls_set_uint24 ( &certificates->length, len );
1398  cert = link->cert;
1399  certificate = iob_put ( iobuf, sizeof ( *certificate ) );
1400  tls_set_uint24 ( &certificate->length, cert->raw.len );
1401  memcpy ( iob_put ( iobuf, cert->raw.len ), cert->raw.data,
1402  cert->raw.len );
1403  }
1404 
1405  /* Transmit record */
1406  return tls_send_record ( tls, TLS_TYPE_HANDSHAKE,
1407  iob_disown ( iobuf ) );
1408 }
#define __attribute__(x)
Definition: compiler.h:10
u16 length
Definition: sky2.h:9
static int tls_send_record(struct tls_connection *tls, unsigned int type, struct io_buffer *iobuf)
Send plaintext record(s)
Definition: tls.c:3052
#define iob_put(iobuf, len)
Definition: iobuf.h:124
struct list_head links
List of links.
Definition: x509.h:204
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:72
#define htonl(value)
Definition: byteswap.h:133
size_t len
Length of data.
Definition: asn1.h:24
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:216
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct tls_client client
Client state.
Definition: tls.h:470
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
ring len
Length.
Definition: dwmac.h:231
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
#define cpu_to_le32(value)
Definition: byteswap.h:107
An X.509 certificate.
Definition: x509.h:215
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:62
A TLS 24-bit integer.
Definition: tls.c:221
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:146
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
#define ENOMEM_CERTIFICATE
Definition: tls.c:122
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:400
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static void tls_set_uint24(tls24_t *field24, unsigned long value)
Set 24-bit field value.
Definition: tls.c:247
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:47
struct asn1_cursor raw
Raw certificate.
Definition: x509.h:230
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:3025
A persistent I/O buffer.
Definition: iobuf.h:37

References __attribute__, tls_client::chain, tls_connection::client, cpu_to_le32, data, asn1_cursor::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_pubkey()

static 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 1416 of file tls.c.

1416  {
1417  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1418  struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1419  struct {
1420  uint16_t version;
1421  uint8_t random[46];
1422  } __attribute__ (( packed )) pre_master_secret;
1423  struct asn1_cursor cursor = {
1424  .data = &pre_master_secret,
1425  .len = sizeof ( pre_master_secret ),
1426  };
1427  struct asn1_builder builder = { NULL, 0 };
1428  int rc;
1429 
1430  /* Generate pre-master secret */
1431  pre_master_secret.version = htons ( TLS_VERSION_MAX );
1432  if ( ( rc = tls_generate_random ( tls, &pre_master_secret.random,
1433  ( sizeof ( pre_master_secret.random ) ) ) ) != 0 ) {
1434  goto err_random;
1435  }
1436 
1437  /* Encrypt pre-master secret using server's public key */
1438  if ( ( rc = pubkey_encrypt ( pubkey, &tls->server.key, &cursor,
1439  &builder ) ) != 0 ) {
1440  DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
1441  tls, strerror ( rc ) );
1442  goto err_encrypt;
1443  }
1444 
1445  /* Construct Client Key Exchange record */
1446  {
1447  struct {
1448  uint32_t type_length;
1449  uint16_t encrypted_pre_master_secret_len;
1450  } __attribute__ (( packed )) header;
1451 
1452  header.type_length =
1454  htonl ( builder.len + sizeof ( header ) -
1455  sizeof ( header.type_length ) ) );
1456  header.encrypted_pre_master_secret_len = htons ( builder.len );
1457 
1458  if ( ( rc = asn1_prepend_raw ( &builder, &header,
1459  sizeof ( header ) ) ) != 0 ) {
1460  DBGC ( tls, "TLS %p could not construct Client Key "
1461  "Exchange: %s\n", tls, strerror ( rc ) );
1462  goto err_prepend;
1463  }
1464  }
1465 
1466  /* Transmit Client Key Exchange record */
1467  if ( ( rc = tls_send_handshake ( tls, builder.data,
1468  builder.len ) ) != 0 ) {
1469  goto err_send;
1470  }
1471 
1472  /* Generate master secret */
1473  tls_generate_master_secret ( tls, &pre_master_secret,
1474  sizeof ( pre_master_secret ) );
1475 
1476  err_random:
1477  err_encrypt:
1478  err_prepend:
1479  err_send:
1480  free ( builder.data );
1481  return rc;
1482 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:418
void * data
Data.
Definition: asn1.h:35
static void tls_generate_master_secret(struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
Generate master secret.
Definition: tls.c:642
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition: asn1.c:936
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:250
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:196
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1153
struct tls_server server
Server state.
Definition: tls.h:472
u32 version
Driver version.
Definition: ath9k_hw.c:1983
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
An ASN.1 object builder.
Definition: asn1.h:28
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:268
unsigned int uint32_t
Definition: stdint.h:12
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
struct tls_tx tx
Transmit state.
Definition: tls.h:466
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:264
struct ena_llq_option header
Header locations.
Definition: ena.h:16
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:459
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
size_t len
Length of data.
Definition: asn1.h:37
An ASN.1 object cursor.
Definition: asn1.h:20
A public key algorithm.
Definition: crypto.h:121
#define htons(value)
Definition: byteswap.h:135
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:77

References __attribute__, asn1_prepend_raw(), tls_tx::cipherspec, cpu_to_le32, asn1_cursor::data, asn1_builder::data, DBGC, free, header, htonl, htons, tls_server::key, asn1_builder::len, NULL, tls_cipherspec_pair::pending, tls_cipher_suite::pubkey, pubkey_encrypt(), random(), rc, tls_connection::server, strerror(), tls_cipherspec::suite, TLS_CLIENT_KEY_EXCHANGE, tls_generate_master_secret(), tls_generate_random(), tls_send_handshake(), TLS_VERSION_MAX, tls_connection::tx, and version.

◆ tls_verify_dh_params()

static int tls_verify_dh_params ( struct tls_connection tls,
size_t  param_len 
)
static

Verify Diffie-Hellman parameter signature.

Parameters
tlsTLS connection
param_lenDiffie-Hellman parameter length
Return values
rcReturn status code

Definition at line 1497 of file tls.c.

1498  {
1499  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1500  struct pubkey_algorithm *pubkey;
1501  struct digest_algorithm *digest;
1502  int use_sig_hash = tls_version ( tls, TLS_VERSION_TLS_1_2 );
1503  const struct {
1504  struct tls_signature_hash_id sig_hash[use_sig_hash];
1505  uint16_t signature_len;
1506  uint8_t signature[0];
1507  } __attribute__ (( packed )) *sig;
1508  struct asn1_cursor signature;
1509  const void *data;
1510  size_t remaining;
1511  int rc;
1512 
1513  /* Signature follows parameters */
1514  assert ( param_len <= tls->server.exchange_len );
1515  data = ( tls->server.exchange + param_len );
1516  remaining = ( tls->server.exchange_len - param_len );
1517 
1518  /* Parse signature from ServerKeyExchange */
1519  sig = data;
1520  if ( ( sizeof ( *sig ) > remaining ) ||
1521  ( ntohs ( sig->signature_len ) > ( remaining -
1522  sizeof ( *sig ) ) ) ) {
1523  DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1524  tls );
1525  DBGC_HDA ( tls, 0, tls->server.exchange,
1526  tls->server.exchange_len );
1527  return -EINVAL_KEY_EXCHANGE;
1528  }
1529  signature.data = sig->signature;
1530  signature.len = ntohs ( sig->signature_len );
1531 
1532  /* Identify signature and hash algorithm */
1533  if ( use_sig_hash ) {
1534  pubkey = tls_signature_hash_pubkey ( sig->sig_hash[0] );
1535  digest = tls_signature_hash_digest ( sig->sig_hash[0] );
1536  if ( ( ! pubkey ) || ( ! digest ) ) {
1537  DBGC ( tls, "TLS %p ServerKeyExchange unsupported "
1538  "signature and hash algorithm\n", tls );
1539  return -ENOTSUP_SIG_HASH;
1540  }
1541  if ( pubkey != cipherspec->suite->pubkey ) {
1542  DBGC ( tls, "TLS %p ServerKeyExchange incorrect "
1543  "signature algorithm %s (expected %s)\n", tls,
1544  pubkey->name, cipherspec->suite->pubkey->name );
1545  return -EPERM_KEY_EXCHANGE;
1546  }
1547  } else {
1548  pubkey = cipherspec->suite->pubkey;
1549  digest = &md5_sha1_algorithm;
1550  }
1551 
1552  /* Verify signature */
1553  {
1554  uint8_t ctx[digest->ctxsize];
1555  uint8_t hash[digest->digestsize];
1556 
1557  /* Calculate digest */
1558  digest_init ( digest, ctx );
1559  digest_update ( digest, ctx, &tls->client.random,
1560  sizeof ( tls->client.random ) );
1561  digest_update ( digest, ctx, tls->server.random,
1562  sizeof ( tls->server.random ) );
1563  digest_update ( digest, ctx, tls->server.exchange, param_len );
1564  digest_final ( digest, ctx, hash );
1565 
1566  /* Verify signature */
1567  if ( ( rc = pubkey_verify ( pubkey, &tls->server.key, digest,
1568  hash, &signature ) ) != 0 ) {
1569  DBGC ( tls, "TLS %p ServerKeyExchange failed "
1570  "verification\n", tls );
1571  DBGC_HDA ( tls, 0, tls->server.exchange,
1572  tls->server.exchange_len );
1573  return -EPERM_KEY_EXCHANGE;
1574  }
1575  }
1576 
1577  return 0;
1578 }
#define __attribute__(x)
Definition: compiler.h:10
uint8_t random[32]
Random bytes.
Definition: tls.h:408
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
pseudo_bit_t hash[0x00010]
Definition: arbel.h:13
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:201
unsigned short uint16_t
Definition: stdint.h:11
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:418
static struct pubkey_algorithm * tls_signature_hash_pubkey(struct tls_signature_hash_id code)
Find TLS signature algorithm.
Definition: tls.c:1037
u8 sig
Definition: CIB_PRM.h:43
#define EPERM_KEY_EXCHANGE
Definition: tls.c:182
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:207
#define DBGC(...)
Definition: compiler.h:505
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:410
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
static struct digest_algorithm * tls_signature_hash_digest(struct tls_signature_hash_id code)
Find TLS hash algorithm.
Definition: tls.c:1056
#define ntohs(value)
Definition: byteswap.h:136
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
A TLS cipher specification.
Definition: tls.h:250
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:196
struct tls_server server
Server state.
Definition: tls.h:472
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:470
#define DBGC_HDA(...)
Definition: compiler.h:506
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:329
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:196
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:268
struct tls_tx tx
Transmit state.
Definition: tls.h:466
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:276
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:285
size_t ctxsize
Context size.
Definition: crypto.h:22
size_t digestsize
Digest size.
Definition: crypto.h:26
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct tls_client_random random
Random bytes.
Definition: tls.h:396
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:110
A TLS signature and hash algorithm identifier.
Definition: tls.h:272
#define ENOTSUP_SIG_HASH
Definition: tls.c:154
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:412
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
An ASN.1 object cursor.
Definition: asn1.h:20
A public key algorithm.
Definition: crypto.h:121
const char * name
Algorithm name.
Definition: crypto.h:123

References __attribute__, assert(), tls_tx::cipherspec, tls_connection::client, ctx, digest_algorithm::ctxsize, data, DBGC, DBGC_HDA, digest_final(), digest_init(), digest_update(), digest_algorithm::digestsize, EINVAL_KEY_EXCHANGE, ENOTSUP_SIG_HASH, EPERM_KEY_EXCHANGE, tls_server::exchange, tls_server::exchange_len, hash, tls_server::key, md5_sha1_algorithm, pubkey_algorithm::name, ntohs, tls_cipherspec_pair::pending, tls_cipher_suite::pubkey, pubkey_verify(), tls_client::random, tls_server::random, rc, tls_connection::server, sig, signature, tls_cipherspec::suite, tls_signature_hash_digest(), tls_signature_hash_pubkey(), tls_version(), TLS_VERSION_TLS_1_2, and tls_connection::tx.

Referenced by tls_send_client_key_exchange_dhe(), and tls_send_client_key_exchange_ecdhe().

◆ tls_send_client_key_exchange_dhe()

static 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 1586 of file tls.c.

1586  {
1587  uint8_t private[ sizeof ( tls->client.random.random ) ];
1588  const struct {
1589  uint16_t len;
1590  uint8_t data[0];
1591  } __attribute__ (( packed )) *dh_val[3];
1592  const void *data;
1593  size_t remaining;
1594  size_t frag_len;
1595  size_t param_len;
1596  unsigned int i;
1597  int rc;
1598 
1599  /* Parse ServerKeyExchange */
1600  data = tls->server.exchange;
1601  remaining = tls->server.exchange_len;
1602  for ( i = 0 ; i < ( sizeof ( dh_val ) / sizeof ( dh_val[0] ) ) ; i++ ){
1603  dh_val[i] = data;
1604  if ( ( sizeof ( *dh_val[i] ) > remaining ) ||
1605  ( ntohs ( dh_val[i]->len ) > ( remaining -
1606  sizeof ( *dh_val[i] ) ) )){
1607  DBGC ( tls, "TLS %p received underlength "
1608  "ServerKeyExchange\n", tls );
1609  DBGC_HDA ( tls, 0, tls->server.exchange,
1610  tls->server.exchange_len );
1612  goto err_header;
1613  }
1614  frag_len = ( sizeof ( *dh_val[i] ) + ntohs ( dh_val[i]->len ));
1615  data += frag_len;
1616  remaining -= frag_len;
1617  }
1618  param_len = ( tls->server.exchange_len - remaining );
1619 
1620  /* Verify parameter signature */
1621  if ( ( rc = tls_verify_dh_params ( tls, param_len ) ) != 0 )
1622  goto err_verify;
1623 
1624  /* Generate Diffie-Hellman private key */
1625  if ( ( rc = tls_generate_random ( tls, private,
1626  sizeof ( private ) ) ) != 0 ) {
1627  goto err_random;
1628  }
1629 
1630  /* Construct pre-master secret and ClientKeyExchange record */
1631  {
1632  typeof ( dh_val[0] ) dh_p = dh_val[0];
1633  typeof ( dh_val[1] ) dh_g = dh_val[1];
1634  typeof ( dh_val[2] ) dh_ys = dh_val[2];
1635  size_t len = ntohs ( dh_p->len );
1636  struct {
1637  uint32_t type_length;
1638  uint16_t dh_xs_len;
1639  uint8_t dh_xs[len];
1640  } __attribute__ (( packed )) *key_xchg;
1641  struct {
1642  uint8_t pre_master_secret[len];
1643  typeof ( *key_xchg ) key_xchg;
1644  } *dynamic;
1645  uint8_t *pre_master_secret;
1646 
1647  /* Allocate space */
1648  dynamic = malloc ( sizeof ( *dynamic ) );
1649  if ( ! dynamic ) {
1650  rc = -ENOMEM;
1651  goto err_alloc;
1652  }
1653  pre_master_secret = dynamic->pre_master_secret;
1654  key_xchg = &dynamic->key_xchg;
1655  key_xchg->type_length =
1657  htonl ( sizeof ( *key_xchg ) -
1658  sizeof ( key_xchg->type_length ) ) );
1659  key_xchg->dh_xs_len = htons ( len );
1660 
1661  /* Calculate pre-master secret and client public value */
1662  if ( ( rc = dhe_key ( dh_p->data, len,
1663  dh_g->data, ntohs ( dh_g->len ),
1664  dh_ys->data, ntohs ( dh_ys->len ),
1665  private, sizeof ( private ),
1666  key_xchg->dh_xs,
1667  pre_master_secret ) ) != 0 ) {
1668  DBGC ( tls, "TLS %p could not calculate DHE key: %s\n",
1669  tls, strerror ( rc ) );
1670  goto err_dhe_key;
1671  }
1672 
1673  /* Strip leading zeroes from pre-master secret */
1674  while ( len && ( ! *pre_master_secret ) ) {
1675  pre_master_secret++;
1676  len--;
1677  }
1678 
1679  /* Transmit Client Key Exchange record */
1680  if ( ( rc = tls_send_handshake ( tls, key_xchg,
1681  sizeof ( *key_xchg ) ) ) !=0){
1682  goto err_send_handshake;
1683  }
1684 
1685  /* Generate master secret */
1686  tls_generate_master_secret ( tls, pre_master_secret, len );
1687 
1688  err_send_handshake:
1689  err_dhe_key:
1690  free ( dynamic );
1691  }
1692  err_alloc:
1693  err_random:
1694  err_verify:
1695  err_header:
1696  return rc;
1697 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
int dhe_key(const void *modulus, size_t len, const void *generator, size_t generator_len, const void *partner, size_t partner_len, const void *private, size_t private_len, void *public, void *shared)
Calculate Diffie-Hellman key.
Definition: dhe.c:53
static void tls_generate_master_secret(struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
Generate master secret.
Definition: tls.c:642
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:410
#define ntohs(value)
Definition: byteswap.h:136
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1153
size_t len
Length of data.
Definition: asn1.h:24
struct tls_server server
Server state.
Definition: tls.h:472
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct tls_client client
Client state.
Definition: tls.h:470
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static int tls_verify_dh_params(struct tls_connection *tls, size_t param_len)
Verify Diffie-Hellman parameter signature.
Definition: tls.c:1497
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
uint8_t random[28]
Random data.
Definition: tls.h:307
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct tls_client_random random
Random bytes.
Definition: tls.h:396
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:47
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:110
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:459
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:412
#define htons(value)
Definition: byteswap.h:135
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:77

References __attribute__, tls_connection::client, cpu_to_le32, asn1_cursor::data, data, DBGC, DBGC_HDA, dhe_key(), EINVAL_KEY_EXCHANGE, ENOMEM, tls_server::exchange, tls_server::exchange_len, free, htonl, htons, asn1_cursor::len, len, malloc(), ntohs, tls_client_random::random, tls_client::random, rc, tls_connection::server, strerror(), TLS_CLIENT_KEY_EXCHANGE, tls_generate_master_secret(), tls_generate_random(), tls_send_handshake(), tls_verify_dh_params(), and typeof().

◆ tls_send_client_key_exchange_ecdhe()

static 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 1711 of file tls.c.

1711  {
1712  struct tls_named_curve *curve;
1713  const struct {
1714  uint8_t curve_type;
1715  uint16_t named_curve;
1716  uint8_t public_len;
1717  uint8_t public[0];
1718  } __attribute__ (( packed )) *ecdh;
1719  size_t param_len;
1720  size_t pointsize;
1721  size_t keysize;
1722  size_t offset;
1723  int rc;
1724 
1725  /* Parse ServerKeyExchange record */
1726  ecdh = tls->server.exchange;
1727  if ( ( sizeof ( *ecdh ) > tls->server.exchange_len ) ||
1728  ( ecdh->public_len > ( tls->server.exchange_len -
1729  sizeof ( *ecdh ) ) ) ) {
1730  DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1731  tls );
1732  DBGC_HDA ( tls, 0, tls->server.exchange,
1733  tls->server.exchange_len );
1734  return -EINVAL_KEY_EXCHANGE;
1735  }
1736  param_len = ( sizeof ( *ecdh ) + ecdh->public_len );
1737 
1738  /* Verify parameter signature */
1739  if ( ( rc = tls_verify_dh_params ( tls, param_len ) ) != 0 )
1740  return rc;
1741 
1742  /* Identify named curve */
1743  if ( ecdh->curve_type != TLS_NAMED_CURVE_TYPE ) {
1744  DBGC ( tls, "TLS %p unsupported curve type %d\n",
1745  tls, ecdh->curve_type );
1746  DBGC_HDA ( tls, 0, tls->server.exchange,
1747  tls->server.exchange_len );
1748  return -ENOTSUP_CURVE;
1749  }
1750  curve = tls_find_named_curve ( ecdh->named_curve );
1751  if ( ! curve ) {
1752  DBGC ( tls, "TLS %p unsupported named curve %d\n",
1753  tls, ntohs ( ecdh->named_curve ) );
1754  DBGC_HDA ( tls, 0, tls->server.exchange,
1755  tls->server.exchange_len );
1756  return -ENOTSUP_CURVE;
1757  }
1758  DBGC ( tls, "TLS %p using named curve %s\n", tls, curve->curve->name );
1759  pointsize = curve->curve->pointsize;
1760  keysize = curve->curve->keysize;
1761  offset = ( curve->format ? 1 : 0 );
1762 
1763  /* Check key length */
1764  if ( ecdh->public_len != ( offset + pointsize ) ) {
1765  DBGC ( tls, "TLS %p invalid %s key\n",
1766  tls, curve->curve->name );
1767  DBGC_HDA ( tls, 0, tls->server.exchange,
1768  tls->server.exchange_len );
1769  return -EINVAL_KEY_EXCHANGE;
1770  }
1771 
1772  /* Check curve point format byte (if present) */
1773  if ( curve->format && ( ecdh->public[0] != curve->format ) ) {
1774  DBGC ( tls, "TLS %p invalid %s curve point format\n",
1775  tls, curve->curve->name );
1776  DBGC_HDA ( tls, 0, tls->server.exchange,
1777  tls->server.exchange_len );
1778  return -EINVAL_KEY_EXCHANGE;
1779  }
1780 
1781  /* Construct pre-master secret and ClientKeyExchange record */
1782  {
1783  uint8_t private[keysize];
1784  uint8_t pre_master_secret[pointsize];
1785  struct {
1786  uint32_t type_length;
1787  uint8_t public_len;
1788  uint8_t public[ecdh->public_len];
1789  } __attribute__ (( packed )) key_xchg;
1790 
1791  /* Generate ephemeral private key */
1792  if ( ( rc = tls_generate_random ( tls, private,
1793  sizeof ( private ) ) ) != 0){
1794  return rc;
1795  }
1796 
1797  /* Exchange keys */
1798  if ( ( rc = ecdhe_key ( curve->curve, ( ecdh->public + offset ),
1799  private, ( key_xchg.public + offset ),
1800  pre_master_secret ) ) != 0 ) {
1801  DBGC ( tls, "TLS %p could not exchange ECDHE key: %s\n",
1802  tls, strerror ( rc ) );
1803  return rc;
1804  }
1805 
1806  /* Generate Client Key Exchange record */
1807  key_xchg.type_length =
1809  htonl ( sizeof ( key_xchg ) -
1810  sizeof ( key_xchg.type_length ) ) );
1811  key_xchg.public_len = sizeof ( key_xchg.public );
1812  if ( curve->format )
1813  key_xchg.public[0] = curve->format;
1814 
1815  /* Transmit Client Key Exchange record */
1816  if ( ( rc = tls_send_handshake ( tls, &key_xchg,
1817  sizeof ( key_xchg ) ) ) !=0){
1818  return rc;
1819  }
1820 
1821  /* Generate master secret */
1822  tls_generate_master_secret ( tls, pre_master_secret,
1823  curve->pre_master_secret_len );
1824  }
1825 
1826  return 0;
1827 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static struct tls_named_curve * tls_find_named_curve(unsigned int named_curve)
Identify named curve.
Definition: tls.c:1085
#define ENOTSUP_CURVE
Definition: tls.c:162
static void tls_generate_master_secret(struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
Generate master secret.
Definition: tls.c:642
#define DBGC(...)
Definition: compiler.h:505
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:410
#define ntohs(value)
Definition: byteswap.h:136
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1153
struct tls_server server
Server state.
Definition: tls.h:472
#define TLS_NAMED_CURVE_TYPE
TLS named curved type.
Definition: tls.h:224
#define DBGC_HDA(...)
Definition: compiler.h:506
const char * name
Curve name.
Definition: crypto.h:179
#define cpu_to_le32(value)
Definition: byteswap.h:107
int ecdhe_key(struct elliptic_curve *curve, const void *partner, const void *private, void *public, void *shared)
Calculate ECDHE key.
Definition: ecdhe.c:45
uint8_t pre_master_secret_len
Pre-master secret length.
Definition: tls.h:238
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:183
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:232
static int tls_verify_dh_params(struct tls_connection *tls, size_t param_len)
Verify Diffie-Hellman parameter signature.
Definition: tls.c:1497
unsigned char uint8_t
Definition: stdint.h:10
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
unsigned int uint32_t
Definition: stdint.h:12
A TLS named curve.
Definition: tls.h:230
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:110
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:459
size_t pointsize
Point (and public key) size.
Definition: crypto.h:181
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:412
uint8_t format
Curve point format byte (if any)
Definition: tls.h:236
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:77

References __attribute__, cpu_to_le32, tls_named_curve::curve, DBGC, DBGC_HDA, ecdhe_key(), EINVAL_KEY_EXCHANGE, ENOTSUP_CURVE, tls_server::exchange, tls_server::exchange_len, tls_named_curve::format, htonl, keysize, elliptic_curve::keysize, elliptic_curve::name, ntohs, offset, elliptic_curve::pointsize, tls_named_curve::pre_master_secret_len, rc, tls_connection::server, strerror(), TLS_CLIENT_KEY_EXCHANGE, tls_find_named_curve(), tls_generate_master_secret(), tls_generate_random(), TLS_NAMED_CURVE_TYPE, tls_send_handshake(), and tls_verify_dh_params().

◆ tls_send_client_key_exchange()

static 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 1841 of file tls.c.

1841  {
1842  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1843  struct tls_cipher_suite *suite = cipherspec->suite;
1844  int rc;
1845 
1846  /* Transmit Client Key Exchange record via key exchange algorithm */
1847  if ( ( rc = suite->exchange->exchange ( tls ) ) != 0 ) {
1848  DBGC ( tls, "TLS %p could not exchange keys: %s\n",
1849  tls, strerror ( rc ) );
1850  return rc;
1851  }
1852 
1853  /* Generate keys from master secret */
1854  if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
1855  DBGC ( tls, "TLS %p could not generate keys: %s\n",
1856  tls, strerror ( rc ) );
1857  return rc;
1858  }
1859 
1860  return 0;
1861 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:194
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:250
int(* exchange)(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition: tls.h:188
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
A TLS cipher suite.
Definition: tls.h:192
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:268
struct tls_tx tx
Transmit state.
Definition: tls.h:466
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:692

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

Referenced by tls_tx_step().

◆ tls_send_certificate_verify()

static 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 1869 of file tls.c.

1869  {
1870  struct digest_algorithm *digest = tls->handshake_digest;
1871  struct x509_certificate *cert = x509_first ( tls->client.chain );
1872  struct pubkey_algorithm *pubkey = cert->signature_algorithm->pubkey;
1873  struct asn1_cursor *key = privkey_cursor ( tls->client.key );
1874  uint8_t digest_out[ digest->digestsize ];
1875  struct tls_signature_hash_algorithm *sig_hash = NULL;
1876  struct asn1_builder builder = { NULL, 0 };
1877  int rc;
1878 
1879  /* Generate digest to be signed */
1880  tls_verify_handshake ( tls, digest_out );
1881 
1882  /* TLSv1.2 and later use explicit algorithm identifiers */
1883  if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
1884  sig_hash = tls_signature_hash_algorithm ( pubkey, digest );
1885  if ( ! sig_hash ) {
1886  DBGC ( tls, "TLS %p could not identify (%s,%s) "
1887  "signature and hash algorithm\n", tls,
1888  pubkey->name, digest->name );
1889  rc = -ENOTSUP_SIG_HASH;
1890  goto err_sig_hash;
1891  }
1892  }
1893 
1894  /* Sign digest */
1895  if ( ( rc = pubkey_sign ( pubkey, key, digest, digest_out,
1896  &builder ) ) != 0 ) {
1897  DBGC ( tls, "TLS %p could not sign %s digest using %s client "
1898  "private key: %s\n", tls, digest->name, pubkey->name,
1899  strerror ( rc ) );
1900  goto err_pubkey_sign;
1901  }
1902 
1903  /* Construct Certificate Verify record */
1904  {
1905  int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
1906  struct {
1907  uint32_t type_length;
1908  struct tls_signature_hash_id sig_hash[use_sig_hash];
1909  uint16_t signature_len;
1910  } __attribute__ (( packed )) header;
1911 
1912  header.type_length = ( cpu_to_le32 ( TLS_CERTIFICATE_VERIFY ) |
1913  htonl ( builder.len +
1914  sizeof ( header ) -
1915  sizeof ( header.type_length )));
1916  if ( use_sig_hash ) {
1917  memcpy ( &header.sig_hash[0], &sig_hash->code,
1918  sizeof ( header.sig_hash[0] ) );
1919  }
1920  header.signature_len = htons ( builder.len );
1921 
1922  if ( ( rc = asn1_prepend_raw ( &builder, &header,
1923  sizeof ( header ) ) ) != 0 ) {
1924  DBGC ( tls, "TLS %p could not construct Certificate "
1925  "Verify: %s\n", tls, strerror ( rc ) );
1926  goto err_prepend;
1927  }
1928  }
1929 
1930  /* Transmit record */
1931  if ( ( rc = tls_send_handshake ( tls, builder.data,
1932  builder.len ) ) != 0 ) {
1933  goto err_send;
1934  }
1935 
1936  err_send:
1937  err_prepend:
1938  err_pubkey_sign:
1939  err_sig_hash:
1940  free ( builder.data );
1941  return rc;
1942 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
void * data
Data.
Definition: asn1.h:35
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:834
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition: asn1.c:936
struct asn1_algorithm * signature_algorithm
Signature algorithm.
Definition: x509.h:238
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1153
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition: privkey.h:52
struct private_key * key
Private key (if used)
Definition: tls.h:398
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:389
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:278
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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:1015
struct tls_client client
Client state.
Definition: tls.h:470
A TLS signature algorithm.
Definition: tls.h:280
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:215
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
An ASN.1 object builder.
Definition: asn1.h:28
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:286
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:276
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
size_t digestsize
Digest size.
Definition: crypto.h:26
const char * name
Algorithm name.
Definition: crypto.h:20
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:310
struct ena_llq_option header
Header locations.
Definition: ena.h:16
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:400
A message digest algorithm.
Definition: crypto.h:18
A TLS signature and hash algorithm identifier.
Definition: tls.h:272
#define TLS_CERTIFICATE_VERIFY
Definition: tls.h:76
#define ENOTSUP_SIG_HASH
Definition: tls.c:154
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
size_t len
Length of data.
Definition: asn1.h:37
An ASN.1 object cursor.
Definition: asn1.h:20
A public key algorithm.
Definition: crypto.h:121
#define htons(value)
Definition: byteswap.h:135
union @391 key
Sense key.
Definition: scsi.h:17
const char * name
Algorithm name.
Definition: crypto.h:123

References __attribute__, asn1_prepend_raw(), tls_client::chain, tls_connection::client, tls_signature_hash_algorithm::code, cpu_to_le32, asn1_builder::data, DBGC, digest_algorithm::digestsize, ENOTSUP_SIG_HASH, free, tls_connection::handshake_digest, header, htonl, htons, key, tls_client::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, and x509_first().

Referenced by tls_tx_step().

◆ tls_send_change_cipher()

static 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 1950 of file tls.c.

1950  {
1951  static const struct {
1952  uint8_t spec;
1953  } __attribute__ (( packed )) change_cipher = {
1954  .spec = TLS_CHANGE_CIPHER_SPEC,
1955  };
1956 
1958  &change_cipher, sizeof ( change_cipher ) );
1959 }
#define __attribute__(x)
Definition: compiler.h:10
uint16_t spec
ENA specification version.
Definition: ena.h:26
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
Definition: tls.h:53
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:3195
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_CHANGE_CIPHER_SPEC
Change cipher spec magic byte.
Definition: tls.h:56

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

Referenced by tls_tx_step().

◆ tls_send_finished()

static int tls_send_finished ( struct tls_connection tls)
static

Transmit Finished record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1967 of file tls.c.

1967  {
1968  struct digest_algorithm *digest = tls->handshake_digest;
1969  struct {
1970  uint32_t type_length;
1971  uint8_t verify_data[ sizeof ( tls->verify.client ) ];
1972  } __attribute__ (( packed )) finished;
1973  uint8_t digest_out[ digest->digestsize ];
1974  int rc;
1975 
1976  /* Construct client verification data */
1977  tls_verify_handshake ( tls, digest_out );
1978  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
1979  tls->verify.client, sizeof ( tls->verify.client ),
1980  "client finished", digest_out, sizeof ( digest_out ) );
1981 
1982  /* Construct record */
1983  memset ( &finished, 0, sizeof ( finished ) );
1984  finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
1985  htonl ( sizeof ( finished ) -
1986  sizeof ( finished.type_length ) ) );
1987  memcpy ( finished.verify_data, tls->verify.client,
1988  sizeof ( finished.verify_data ) );
1989 
1990  /* Transmit record */
1991  if ( ( rc = tls_send_handshake ( tls, &finished,
1992  sizeof ( finished ) ) ) != 0 )
1993  return rc;
1994 
1995  /* Mark client as finished */
1996  pending_put ( &tls->client.negotiation );
1997 
1998  return 0;
1999 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:463
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:402
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:834
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1153
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct tls_client client
Client state.
Definition: tls.h:470
uint8_t master_secret[48]
Master secret.
Definition: tls.h:453
#define cpu_to_le32(value)
Definition: byteswap.h:107
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
uint8_t client[12]
Client verification data.
Definition: tls.h:157
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
size_t digestsize
Digest size.
Definition: crypto.h:26
A message digest algorithm.
Definition: crypto.h:18
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:622
#define TLS_FINISHED
Definition: tls.h:78
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, tls_verify_data::client, tls_connection::client, cpu_to_le32, digest_algorithm::digestsize, tls_connection::handshake_digest, htonl, tls_connection::master_secret, memcpy(), memset(), tls_client::negotiation, pending_put(), rc, TLS_FINISHED, tls_prf_label, tls_send_handshake(), tls_verify_handshake(), and tls_connection::verify.

Referenced by tls_tx_step().

◆ tls_new_change_cipher()

static 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 2008 of file tls.c.

2009  {
2010  const struct {
2011  uint8_t spec;
2012  } __attribute__ (( packed )) *change_cipher = iobuf->data;
2013  size_t len = iob_len ( iobuf );
2014  int rc;
2015 
2016  /* Sanity check */
2017  if ( ( sizeof ( *change_cipher ) != len ) ||
2018  ( change_cipher->spec != TLS_CHANGE_CIPHER_SPEC ) ) {
2019  DBGC ( tls, "TLS %p received invalid Change Cipher\n", tls );
2020  DBGC_HD ( tls, change_cipher, len );
2021  return -EINVAL_CHANGE_CIPHER;
2022  }
2023  iob_pull ( iobuf, sizeof ( *change_cipher ) );
2024 
2025  /* Change receive cipher spec */
2026  if ( ( rc = tls_change_cipher ( tls, &tls->rx.cipherspec ) ) != 0 ) {
2027  DBGC ( tls, "TLS %p could not activate RX cipher: %s\n",
2028  tls, strerror ( rc ) );
2029  return rc;
2030  }
2031  tls->rx.seq = ~( ( uint64_t ) 0 );
2032 
2033  return 0;
2034 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec_pair *pair)
Activate next cipher suite.
Definition: tls.c:982
uint16_t spec
ENA specification version.
Definition: ena.h:26
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:378
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
#define EINVAL_CHANGE_CIPHER
Definition: tls.c:58
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
struct tls_rx rx
Receive state.
Definition: tls.h:468
uint64_t seq
Sequence number.
Definition: tls.h:380
void * data
Start of data.
Definition: iobuf.h:52
#define TLS_CHANGE_CIPHER_SPEC
Change cipher spec magic byte.
Definition: tls.h:56

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()

static 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 2043 of file tls.c.

2044  {
2045  const struct {
2046  uint8_t level;
2047  uint8_t description;
2048  char next[0];
2049  } __attribute__ (( packed )) *alert = iobuf->data;
2050  size_t len = iob_len ( iobuf );
2051 
2052  /* Sanity check */
2053  if ( sizeof ( *alert ) != len ) {
2054  DBGC ( tls, "TLS %p received overlength Alert\n", tls );
2055  DBGC_HD ( tls, alert, len );
2056  return -EINVAL_ALERT;
2057  }
2058  iob_pull ( iobuf, sizeof ( *alert ) );
2059 
2060  /* Handle alert */
2061  switch ( alert->level ) {
2062  case TLS_ALERT_WARNING:
2063  DBGC ( tls, "TLS %p received warning alert %d\n",
2064  tls, alert->description );
2065  return 0;
2066  case TLS_ALERT_FATAL:
2067  DBGC ( tls, "TLS %p received fatal alert %d\n",
2068  tls, alert->description );
2069  return -EPERM_ALERT;
2070  default:
2071  DBGC ( tls, "TLS %p received unknown alert level %d"
2072  "(alert %d)\n", tls, alert->level, alert->description );
2073  return -EIO_ALERT;
2074  }
2075 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
#define __attribute__(x)
Definition: compiler.h:10
#define DBGC(...)
Definition: compiler.h:505
void alert(unsigned int row, const char *fmt,...)
Show alert message.
Definition: message.c:103
#define EIO_ALERT
Definition: tls.c:114
ring len
Length.
Definition: dwmac.h:231
#define TLS_ALERT_WARNING
Definition: tls.h:81
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
#define EINVAL_ALERT
Definition: tls.c:62
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_ALERT_FATAL
Definition: tls.h:82
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
void * data
Start of data.
Definition: iobuf.h:52
#define EPERM_ALERT
Definition: tls.c:166

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

Referenced by tls_new_record().

◆ tls_new_hello_request()

static 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 2085 of file tls.c.

2087  {
2088 
2089  /* Ignore if a handshake is in progress */
2090  if ( ! tls_ready ( tls ) ) {
2091  DBGC ( tls, "TLS %p ignoring Hello Request\n", tls );
2092  return 0;
2093  }
2094 
2095  /* Fail unless server supports secure renegotiation */
2096  if ( ! ( tls->secure_renegotiation && tls->extended_master_secret ) ) {
2097  DBGC ( tls, "TLS %p refusing to renegotiate insecurely\n",
2098  tls );
2099  return -EPERM_RENEG_INSECURE;
2100  }
2101 
2102  /* Restart negotiation */
2103  tls_restart ( tls );
2104 
2105  return 0;
2106 }
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition: tls.c:1130
#define DBGC(...)
Definition: compiler.h:505
int extended_master_secret
Extended master secret flag.
Definition: tls.h:461
#define EPERM_RENEG_INSECURE
Definition: tls.c:174
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:459
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:259

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

Referenced by tls_new_handshake().

◆ tls_new_server_hello()

static 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 2116 of file tls.c.

2117  {
2118  const struct {
2119  uint16_t version;
2120  uint8_t random[32];
2121  uint8_t session_id_len;
2122  uint8_t session_id[0];
2123  } __attribute__ (( packed )) *hello_a = data;
2124  const uint8_t *session_id;
2125  const struct {
2126  uint16_t cipher_suite;
2127  uint8_t compression_method;
2128  char next[0];
2129  } __attribute__ (( packed )) *hello_b;
2130  const struct {
2131  uint16_t len;
2132  uint8_t data[0];
2133  } __attribute__ (( packed )) *exts;
2134  const struct {
2135  uint16_t type;
2136  uint16_t len;
2137  uint8_t data[0];
2138  } __attribute__ (( packed )) *ext;
2139  const struct {
2140  uint8_t len;
2141  uint8_t data[0];
2142  } __attribute__ (( packed )) *reneg = NULL;
2143  const struct {
2144  uint8_t data[0];
2145  } __attribute__ (( packed )) *ems = NULL;
2146  uint16_t version;
2147  size_t exts_len;
2148  size_t ext_len;
2149  size_t remaining;
2150  int rc;
2151 
2152  /* Parse header */
2153  if ( ( sizeof ( *hello_a ) > len ) ||
2154  ( hello_a->session_id_len > ( len - sizeof ( *hello_a ) ) ) ||
2155  ( sizeof ( *hello_b ) > ( len - sizeof ( *hello_a ) -
2156  hello_a->session_id_len ) ) ) {
2157  DBGC ( tls, "TLS %p received underlength Server Hello\n", tls );
2158  DBGC_HD ( tls, data, len );
2159  return -EINVAL_HELLO;
2160  }
2161  session_id = hello_a->session_id;
2162  hello_b = ( ( void * ) ( session_id + hello_a->session_id_len ) );
2163 
2164  /* Parse extensions, if present */
2165  remaining = ( len - sizeof ( *hello_a ) - hello_a->session_id_len -
2166  sizeof ( *hello_b ) );
2167  if ( remaining ) {
2168 
2169  /* Parse extensions length */
2170  exts = ( ( void * ) hello_b->next );
2171  if ( ( sizeof ( *exts ) > remaining ) ||
2172  ( ( exts_len = ntohs ( exts->len ) ) >
2173  ( remaining - sizeof ( *exts ) ) ) ) {
2174  DBGC ( tls, "TLS %p received underlength extensions\n",
2175  tls );
2176  DBGC_HD ( tls, data, len );
2177  return -EINVAL_HELLO;
2178  }
2179 
2180  /* Parse extensions */
2181  for ( ext = ( ( void * ) exts->data ), remaining = exts_len ;
2182  remaining ;
2183  ext = ( ( ( void * ) ext ) + sizeof ( *ext ) + ext_len ),
2184  remaining -= ( sizeof ( *ext ) + ext_len ) ) {
2185 
2186  /* Parse extension length */
2187  if ( ( sizeof ( *ext ) > remaining ) ||
2188  ( ( ext_len = ntohs ( ext->len ) ) >
2189  ( remaining - sizeof ( *ext ) ) ) ) {
2190  DBGC ( tls, "TLS %p received underlength "
2191  "extension\n", tls );
2192  DBGC_HD ( tls, data, len );
2193  return -EINVAL_HELLO;
2194  }
2195 
2196  /* Record known extensions */
2197  switch ( ext->type ) {
2198  case htons ( TLS_RENEGOTIATION_INFO ) :
2199  reneg = ( ( void * ) ext->data );
2200  if ( ( sizeof ( *reneg ) > ext_len ) ||
2201  ( reneg->len >
2202  ( ext_len - sizeof ( *reneg ) ) ) ) {
2203  DBGC ( tls, "TLS %p received "
2204  "underlength renegotiation "
2205  "info\n", tls );
2206  DBGC_HD ( tls, data, len );
2207  return -EINVAL_HELLO;
2208  }
2209  break;
2211  ems = ( ( void * ) ext->data );
2212  break;
2213  }
2214  }
2215  }
2216 
2217  /* Check and store protocol version */
2218  version = ntohs ( hello_a->version );
2219  if ( version < TLS_VERSION_MIN ) {
2220  DBGC ( tls, "TLS %p does not support protocol version %d.%d\n",
2221  tls, ( version >> 8 ), ( version & 0xff ) );
2222  return -ENOTSUP_VERSION;
2223  }
2224  if ( version > tls->version ) {
2225  DBGC ( tls, "TLS %p server attempted to illegally upgrade to "
2226  "protocol version %d.%d\n",
2227  tls, ( version >> 8 ), ( version & 0xff ) );
2228  return -EPROTO_VERSION;
2229  }
2230  tls->version = version;
2231  DBGC ( tls, "TLS %p using protocol version %d.%d\n",
2232  tls, ( version >> 8 ), ( version & 0xff ) );
2233 
2234  /* Select cipher suite */
2235  if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 )
2236  return rc;
2237 
2238  /* Add preceding Client Hello to handshake digest */
2239  if ( ( rc = tls_client_hello ( tls, tls_add_handshake ) ) != 0 )
2240  return rc;
2241 
2242  /* Copy out server random bytes */
2243  memcpy ( &tls->server.random, &hello_a->random,
2244  sizeof ( tls->server.random ) );
2245 
2246  /* Handle extended master secret */
2247  tls->extended_master_secret = ( !! ems );
2248 
2249  /* Check session ID */
2250  if ( hello_a->session_id_len &&
2251  ( hello_a->session_id_len == tls->session_id_len ) &&
2252  ( memcmp ( session_id, tls->session_id,
2253  tls->session_id_len ) == 0 ) ) {
2254 
2255  /* Session ID match: reuse master secret */
2256  DBGC ( tls, "TLS %p resuming session ID:\n", tls );
2257  DBGC_HDA ( tls, 0, tls->session_id, tls->session_id_len );
2258  if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
2259  return rc;
2260 
2261  /* Ensure master secret generation method matches */
2262  if ( tls->extended_master_secret !=
2264  DBGC ( tls, "TLS %p mismatched extended master secret "
2265  "extension\n", tls );
2266  return -EPERM_EMS;
2267  }
2268 
2269  } else {
2270 
2271  /* Record new session ID, if present */
2272  if ( hello_a->session_id_len &&
2273  ( hello_a->session_id_len <= sizeof ( tls->session_id ))){
2274  tls->session_id_len = hello_a->session_id_len;
2275  memcpy ( tls->session_id, session_id,
2276  tls->session_id_len );
2277  DBGC ( tls, "TLS %p new session ID:\n", tls );
2278  DBGC_HDA ( tls, 0, tls->session_id,
2279  tls->session_id_len );
2280  }
2281  }
2282 
2283  /* Handle secure renegotiation */
2284  if ( tls->secure_renegotiation ) {
2285 
2286  /* Secure renegotiation is expected; verify data */
2287  if ( ( reneg == NULL ) ||
2288  ( reneg->len != sizeof ( tls->verify ) ) ||
2289  ( memcmp ( reneg->data, &tls->verify,
2290  sizeof ( tls->verify ) ) != 0 ) ) {
2291  DBGC ( tls, "TLS %p server failed secure "
2292  "renegotiation\n", tls );
2293  return -EPERM_RENEG_VERIFY;
2294  }
2295 
2296  } else if ( reneg != NULL ) {
2297 
2298  /* Secure renegotiation is being enabled */
2299  if ( reneg->len != 0 ) {
2300  DBGC ( tls, "TLS %p server provided non-empty initial "
2301  "renegotiation\n", tls );
2302  return -EPERM_RENEG_VERIFY;
2303  }
2304  tls->secure_renegotiation = 1;
2305  }
2306 
2307  return 0;
2308 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:463
#define __attribute__(x)
Definition: compiler.h:10
int extended_master_secret
Extended master secret flag.
Definition: tls.h:357
uint8_t random[32]
Random bytes.
Definition: tls.h:408
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static int tls_select_cipher(struct tls_connection *tls, unsigned int cipher_suite)
Select next cipher suite.
Definition: tls.c:939
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:144
struct tls_session * session
Session.
Definition: tls.h:433
#define EINVAL_HELLO
Definition: tls.c:66
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:818
uint32_t type
Operating system type.
Definition: ena.h:12
#define ENOTSUP_VERSION
Definition: tls.c:158
#define DBGC(...)
Definition: compiler.h:505
uint8_t session_id[32]
Session ID.
Definition: tls.h:437
#define EPROTO_VERSION
Definition: tls.c:190
#define ntohs(value)
Definition: byteswap.h:136
struct tls_server server
Server state.
Definition: tls.h:472
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Driver version.
Definition: ath9k_hw.c:1983
int extended_master_secret
Extended master secret flag.
Definition: tls.h:461
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
#define EPERM_EMS
Definition: tls.c:186
#define DBGC_HD(...)
Definition: compiler.h:507
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
unsigned char uint8_t
Definition: stdint.h:10
#define EPERM_RENEG_VERIFY
Definition: tls.c:178
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
#define TLS_EXTENDED_MASTER_SECRET
Definition: tls.h:138
uint16_t ext
Extended status.
Definition: ena.h:20
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:692
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:1167
uint16_t version
Protocol version.
Definition: tls.h:451
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:459
size_t session_id_len
Length of session ID.
Definition: tls.h:439
#define TLS_VERSION_MIN
Minimum TLS version.
Definition: crypto.h:13
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135

References __attribute__, data, DBGC, DBGC_HD, DBGC_HDA, EINVAL_HELLO, ENOTSUP_VERSION, EPERM_EMS, EPERM_RENEG_VERIFY, EPROTO_VERSION, ext, tls_session::extended_master_secret, tls_connection::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_select_cipher(), TLS_VERSION_MIN, type, tls_connection::verify, tls_connection::version, and version.

Referenced by tls_new_handshake().

◆ tls_new_session_ticket()

static 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 2318 of file tls.c.

2319  {
2320  const struct {
2322  uint16_t len;
2323  uint8_t ticket[0];
2324  } __attribute__ (( packed )) *new_session_ticket = data;
2325  size_t ticket_len;
2326 
2327  /* Parse header */
2328  if ( sizeof ( *new_session_ticket ) > len ) {
2329  DBGC ( tls, "TLS %p received underlength New Session Ticket\n",
2330  tls );
2331  DBGC_HD ( tls, data, len );
2332  return -EINVAL_TICKET;
2333  }
2334  ticket_len = ntohs ( new_session_ticket->len );
2335  if ( ticket_len > ( len - sizeof ( *new_session_ticket ) ) ) {
2336  DBGC ( tls, "TLS %p received overlength New Session Ticket\n",
2337  tls );
2338  DBGC_HD ( tls, data, len );
2339  return -EINVAL_TICKET;
2340  }
2341 
2342  /* Free any unapplied new session ticket */
2343  free ( tls->new_session_ticket );
2344  tls->new_session_ticket = NULL;
2345  tls->new_session_ticket_len = 0;
2346 
2347  /* Record ticket */
2348  tls->new_session_ticket = malloc ( ticket_len );
2349  if ( ! tls->new_session_ticket )
2350  return -ENOMEM;
2351  memcpy ( tls->new_session_ticket, new_session_ticket->ticket,
2352  ticket_len );
2353  tls->new_session_ticket_len = ticket_len;
2354  DBGC ( tls, "TLS %p new session ticket:\n", tls );
2355  DBGC_HDA ( tls, 0, tls->new_session_ticket,
2356  tls->new_session_ticket_len );
2357 
2358  return 0;
2359 }
#define __attribute__(x)
Definition: compiler.h:10
unsigned short uint16_t
Definition: stdint.h:11
#define DBGC(...)
Definition: compiler.h:505
size_t new_session_ticket_len
Length of new session ticket.
Definition: tls.h:443
#define ntohs(value)
Definition: byteswap.h:136
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * new_session_ticket
New session ticket.
Definition: tls.h:441
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
Definition: wpa.h:54
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_TICKET
Definition: tls.c:106
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_new_handshake().

◆ tls_parse_chain()

static 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 2369 of file tls.c.

2370  {
2371  size_t remaining = len;
2372  int rc;
2373 
2374  /* Free any existing certificate chain */
2375  memset ( &tls->server.key, 0, sizeof ( tls->server.key ) );
2376  x509_chain_put ( tls->server.chain );
2377  tls->server.chain = NULL;
2378 
2379  /* Create certificate chain */
2380  tls->server.chain = x509_alloc_chain();
2381  if ( ! tls->server.chain ) {
2382  rc = -ENOMEM_CHAIN;
2383  goto err_alloc_chain;
2384  }
2385 
2386  /* Add certificates to chain */
2387  while ( remaining ) {
2388  const struct {
2389  tls24_t length;
2390  uint8_t data[0];
2391  } __attribute__ (( packed )) *certificate = data;
2392  size_t certificate_len;
2393  size_t record_len;
2394  struct x509_certificate *cert;
2395 
2396  /* Parse header */
2397  if ( sizeof ( *certificate ) > remaining ) {
2398  DBGC ( tls, "TLS %p underlength certificate:\n", tls );
2399  DBGC_HDA ( tls, 0, data, remaining );
2401  goto err_underlength;
2402  }
2403  certificate_len = tls_uint24 ( &certificate->length );
2404  if ( certificate_len > ( remaining - sizeof ( *certificate ) )){
2405  DBGC ( tls, "TLS %p overlength certificate:\n", tls );
2406  DBGC_HDA ( tls, 0, data, remaining );
2408  goto err_overlength;
2409  }
2410  record_len = ( sizeof ( *certificate ) + certificate_len );
2411 
2412  /* Add certificate to chain */
2413  if ( ( rc = x509_append_raw ( tls->server.chain,
2414  certificate->data,
2415  certificate_len ) ) != 0 ) {
2416  DBGC ( tls, "TLS %p could not append certificate: %s\n",
2417  tls, strerror ( rc ) );
2418  DBGC_HDA ( tls, 0, data, remaining );
2419  goto err_parse;
2420  }
2421  cert = x509_last ( tls->server.chain );
2422  DBGC ( tls, "TLS %p found certificate %s\n",
2423  tls, x509_name ( cert ) );
2424 
2425  /* Move to next certificate in list */
2426  data += record_len;
2427  remaining -= record_len;
2428  }
2429 
2430  return 0;
2431 
2432  err_parse:
2433  err_overlength:
2434  err_underlength:
2435  memset ( &tls->server.key, 0, sizeof ( tls->server.key ) );
2436  x509_chain_put ( tls->server.chain );
2437  tls->server.chain = NULL;
2438  err_alloc_chain:
2439  return rc;
2440 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:299
#define __attribute__(x)
Definition: compiler.h:10
u16 length
Definition: sky2.h:9
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:418
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:236
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:1673
#define DBGC(...)
Definition: compiler.h:505
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1614
#define ENOMEM_CHAIN
Definition: tls.c:126
#define EINVAL_CERTIFICATE
Definition: tls.c:70
struct tls_server server
Server state.
Definition: tls.h:472
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition: x509.h:324
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:215
struct x509_chain * chain
Certificate chain.
Definition: tls.h:416
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:221
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:146
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, tls_server::chain, data, DBGC, DBGC_HDA, EINVAL_CERTIFICATE, ENOMEM_CHAIN, tls_server::key, len, length, memset(), NULL, rc, tls_connection::server, strerror(), tls_uint24(), x509_alloc_chain(), x509_append_raw(), x509_chain_put(), x509_last(), and x509_name().

Referenced by tls_new_certificate().

◆ tls_new_certificate()

static 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 2450 of file tls.c.

2451  {
2452  const struct {
2453  tls24_t length;
2454  uint8_t certificates[0];
2455  } __attribute__ (( packed )) *certificate = data;
2456  size_t certificates_len;
2457  int rc;
2458 
2459  /* Parse header */
2460  if ( sizeof ( *certificate ) > len ) {
2461  DBGC ( tls, "TLS %p received underlength Server Certificate\n",
2462  tls );
2463  DBGC_HD ( tls, data, len );
2464  return -EINVAL_CERTIFICATES;
2465  }
2466  certificates_len = tls_uint24 ( &certificate->length );
2467  if ( certificates_len > ( len - sizeof ( *certificate ) ) ) {
2468  DBGC ( tls, "TLS %p received overlength Server Certificate\n",
2469  tls );
2470  DBGC_HD ( tls, data, len );
2471  return -EINVAL_CERTIFICATES;
2472  }
2473 
2474  /* Parse certificate chain */
2475  if ( ( rc = tls_parse_chain ( tls, certificate->certificates,
2476  certificates_len ) ) != 0 )
2477  return rc;
2478 
2479  return 0;
2480 }
#define __attribute__(x)
Definition: compiler.h:10
u16 length
Definition: sky2.h:9
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:236
#define DBGC(...)
Definition: compiler.h:505
ring len
Length.
Definition: dwmac.h:231
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:221
static int tls_parse_chain(struct tls_connection *tls, const void *data, size_t len)
Parse certificate chain.
Definition: tls.c:2369
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_CERTIFICATES
Definition: tls.c:74

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()

static 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 2490 of file tls.c.

2491  {
2492 
2493  /* Free any existing server key exchange record */
2494  free ( tls->server.exchange );
2495  tls->server.exchange_len = 0;
2496 
2497  /* Allocate copy of server key exchange record */
2498  tls->server.exchange = malloc ( len );
2499  if ( ! tls->server.exchange )
2500  return -ENOMEM;
2501 
2502  /* Store copy of server key exchange record for later
2503  * processing. We cannot verify the signature at this point
2504  * since the certificate validation will not yet have
2505  * completed.
2506  */
2507  memcpy ( tls->server.exchange, data, len );
2508  tls->server.exchange_len = len;
2509 
2510  return 0;
2511 }
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:410
struct tls_server server
Server state.
Definition: tls.h:472
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:412

References data, ENOMEM, tls_server::exchange, tls_server::exchange_len, free, len, malloc(), memcpy(), and tls_connection::server.

Referenced by tls_new_handshake().

◆ tls_new_certificate_request()

static 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 2521 of file tls.c.

2523  {
2524  struct x509_certificate *cert;
2525  int rc;
2526 
2527  /* We can only send a single certificate, so there is no point
2528  * in parsing the Certificate Request.
2529  */
2530 
2531  /* Free any existing client certificate chain */
2532  x509_chain_put ( tls->client.chain );
2533  tls->client.chain = NULL;
2534 
2535  /* Create client certificate chain */
2536  tls->client.chain = x509_alloc_chain();
2537  if ( ! tls->client.chain ) {
2538  rc = -ENOMEM;
2539  goto err_alloc;
2540  }
2541 
2542  /* Determine client certificate to be sent, if any */
2543  cert = x509_find_key ( NULL, tls->client.key );
2544  if ( cert ) {
2545  DBGC ( tls, "TLS %p selected client certificate %s\n",
2546  tls, x509_name ( cert ) );
2547 
2548  /* Append client certificate to chain */
2549  if ( ( rc = x509_append ( tls->client.chain, cert ) ) != 0 )
2550  goto err_append;
2551 
2552  /* Append any relevant issuer certificates */
2553  if ( ( rc = x509_auto_append ( tls->client.chain,
2554  &certstore ) ) != 0 )
2555  goto err_auto_append;
2556  } else {
2557 
2558  /* Send an empty certificate chain */
2559  DBGC ( tls, "TLS %p could not find certificate corresponding "
2560  "to private key\n", tls );
2561  }
2562 
2563  return 0;
2564 
2565  err_auto_append:
2566  err_append:
2567  x509_chain_put ( tls->client.chain );
2568  tls->client.chain = NULL;
2569  err_alloc:
2570  return rc;
2571 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:299
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_chain certstore
Certificate store.
Definition: certstore.c:89
#define DBGC(...)
Definition: compiler.h:505
int x509_append(struct x509_chain *chain, struct x509_certificate *cert)
Append X.509 certificate to X.509 certificate chain.
Definition: x509.c:1637
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1614
struct private_key * key
Private key (if used)
Definition: tls.h:398
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct tls_client client
Client state.
Definition: tls.h:470
int x509_auto_append(struct x509_chain *chain, struct x509_chain *store)
Append X.509 certificates to X.509 certificate chain.
Definition: x509.c:1867
An X.509 certificate.
Definition: x509.h:215
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:146
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:400
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:1834
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References certstore, tls_client::chain, tls_connection::client, DBGC, ENOMEM, tls_client::key, 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()

static 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 2581 of file tls.c.

2582  {
2583  const struct {
2584  char next[0];
2585  } __attribute__ (( packed )) *hello_done = data;
2586  int rc;
2587 
2588  /* Sanity check */
2589  if ( sizeof ( *hello_done ) != len ) {
2590  DBGC ( tls, "TLS %p received overlength Server Hello Done\n",
2591  tls );
2592  DBGC_HD ( tls, data, len );
2593  return -EINVAL_HELLO_DONE;
2594  }
2595 
2596  /* Begin certificate validation */
2597  if ( ( rc = create_validator ( &tls->server.validator,
2598  tls->server.chain,
2599  tls->server.root ) ) != 0 ) {
2600  DBGC ( tls, "TLS %p could not start certificate validation: "
2601  "%s\n", tls, strerror ( rc ) );
2602  return rc;
2603  }
2604  pending_get ( &tls->server.validation );
2605 
2606  return 0;
2607 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
#define EINVAL_HELLO_DONE
Definition: tls.c:78
struct tls_server server
Server state.
Definition: tls.h:472
int create_validator(struct interface *job, struct x509_chain *chain, struct x509_root *root)
Instantiate a certificate validator.
Definition: validator.c:759
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct x509_chain * chain
Certificate chain.
Definition: tls.h:416
#define DBGC_HD(...)
Definition: compiler.h:507
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:422
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
struct interface validator
Certificate validator.
Definition: tls.h:420
uint8_t data[48]
Additional event data.
Definition: ena.h:22
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45
struct x509_root * root
Root of trust.
Definition: tls.h:414

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()

static 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 2617 of file tls.c.

2618  {
2619  struct tls_session *session = tls->session;
2620  struct digest_algorithm *digest = tls->handshake_digest;
2621  const struct {
2622  uint8_t verify_data[ sizeof ( tls->verify.server ) ];
2623  char next[0];
2624  } __attribute__ (( packed )) *finished = data;
2625  uint8_t digest_out[ digest->digestsize ];
2626 
2627  /* Sanity check */
2628  if ( sizeof ( *finished ) != len ) {
2629  DBGC ( tls, "TLS %p received overlength Finished\n", tls );
2630  DBGC_HD ( tls, data, len );
2631  return -EINVAL_FINISHED;
2632  }
2633 
2634  /* Verify data */
2635  tls_verify_handshake ( tls, digest_out );
2636  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
2637  tls->verify.server, sizeof ( tls->verify.server ),
2638  "server finished", digest_out, sizeof ( digest_out ) );
2639  if ( memcmp ( tls->verify.server, finished->verify_data,
2640  sizeof ( tls->verify.server ) ) != 0 ) {
2641  DBGC ( tls, "TLS %p verification failed\n", tls );
2642  return -EPERM_VERIFY;
2643  }
2644 
2645  /* Mark server as finished */
2646  pending_put ( &tls->server.negotiation );
2647 
2648  /* If we are resuming a session (i.e. if the server Finished
2649  * arrives before the client Finished is sent), then schedule
2650  * transmission of Change Cipher and Finished.
2651  */
2652  if ( is_pending ( &tls->client.negotiation ) ) {
2654  tls_tx_resume ( tls );
2655  }
2656 
2657  /* Record session ID, ticket, and master secret, if applicable */
2658  if ( tls->session_id_len || tls->new_session_ticket_len ) {
2659  memcpy ( session->master_secret, tls->master_secret,
2660  sizeof ( session->master_secret ) );
2662  }
2663  if ( tls->session_id_len ) {
2664  session->id_len = tls->session_id_len;
2665  memcpy ( session->id, tls->session_id, sizeof ( session->id ) );
2666  }
2667  if ( tls->new_session_ticket_len ) {
2668  free ( session->ticket );
2669  session->ticket = tls->new_session_ticket;
2670  session->ticket_len = tls->new_session_ticket_len;
2671  tls->new_session_ticket = NULL;
2672  tls->new_session_ticket_len = 0;
2673  }
2674 
2675  /* Move to end of session's connection list and allow other
2676  * connections to start making progress.
2677  */
2678  list_del ( &tls->list );
2679  list_add_tail ( &tls->list, &session->conn );
2680  tls_tx_resume_all ( session );
2681 
2682  /* Send notification of a window change */
2683  xfer_window_changed ( &tls->plainstream );
2684 
2685  return 0;
2686 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:463
uint8_t id[32]
Session ID.
Definition: tls.h:347
#define __attribute__(x)
Definition: compiler.h:10
int extended_master_secret
Extended master secret flag.
Definition: tls.h:357
static void tls_tx_resume_all(struct tls_session *session)
Resume TX state machine for all connections within a session.
Definition: tls.c:1118
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1109
struct tls_session * session
Session.
Definition: tls.h:433
uint8_t master_secret[48]
Master secret.
Definition: tls.h:355
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:402
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:834
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
#define DBGC(...)
Definition: compiler.h:505
size_t new_session_ticket_len
Length of new session ticket.
Definition: tls.h:443
uint8_t session_id[32]
Session ID.
Definition: tls.h:437
struct tls_server server
Server state.
Definition: tls.h:472
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void * memcpy(void *dest, const void *src, size_t len) __nonnull
size_t id_len
Length of session ID.
Definition: tls.h:349
void * new_session_ticket
New session ticket.
Definition: tls.h:441
struct tls_client client
Client state.
Definition: tls.h:470
int extended_master_secret
Extended master secret flag.
Definition: tls.h:461
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
ring len
Length.
Definition: dwmac.h:231
#define EINVAL_FINISHED
Definition: tls.c:82
struct list_head list
List of connections within the same session.
Definition: tls.h:435
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
#define EPERM_VERIFY
Definition: tls.c:170
size_t ticket_len
Length of session ticket.
Definition: tls.h:353
uint8_t master_secret[48]
Master secret.
Definition: tls.h:453
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:424
void * ticket
Session ticket.
Definition: tls.h:351
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
unsigned int pending
Pending transmissions.
Definition: tls.h:370
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
struct tls_tx tx
Transmit state.
Definition: tls.h:466
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:455
A TLS session.
Definition: tls.h:333
size_t digestsize
Digest size.
Definition: crypto.h:26
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t server[12]
Server verification data.
Definition: tls.h:159
struct list_head conn
List of connections.
Definition: tls.h:360
size_t session_id_len
Length of session ID.
Definition: tls.h:439
struct interface plainstream
Plaintext stream.
Definition: tls.h:446
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:622

References __attribute__, tls_connection::client, tls_session::conn, data, DBGC, DBGC_HD, digest_algorithm::digestsize, EINVAL_FINISHED, EPERM_VERIFY, tls_session::extended_master_secret, tls_connection::extended_master_secret, free, tls_connection::handshake_digest, tls_session::id, tls_session::id_len, is_pending(), len, tls_connection::list, list_add_tail, list_del, tls_session::master_secret, tls_connection::master_secret, 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_verify_data::server, tls_connection::server, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, tls_session::ticket, tls_session::ticket_len, 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, and xfer_window_changed().

Referenced by tls_new_handshake().

◆ tls_new_handshake()

static 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 2695 of file tls.c.

2696  {
2697  size_t remaining;
2698  int rc;
2699 
2700  while ( ( remaining = iob_len ( iobuf ) ) ) {
2701  const struct {
2702  uint8_t type;
2703  tls24_t length;
2704  uint8_t payload[0];
2705  } __attribute__ (( packed )) *handshake = iobuf->data;
2706  const void *payload;
2707  size_t payload_len;
2708  size_t record_len;
2709 
2710  /* Parse header */
2711  if ( sizeof ( *handshake ) > remaining ) {
2712  /* Leave remaining fragment unconsumed */
2713  break;
2714  }
2715  payload_len = tls_uint24 ( &handshake->length );
2716  if ( payload_len > ( remaining - sizeof ( *handshake ) ) ) {
2717  /* Leave remaining fragment unconsumed */
2718  break;
2719  }
2720  payload = &handshake->payload;
2721  record_len = ( sizeof ( *handshake ) + payload_len );
2722 
2723  /* Handle payload */
2724  switch ( handshake->type ) {
2725  case TLS_HELLO_REQUEST:
2726  rc = tls_new_hello_request ( tls, payload,
2727  payload_len );
2728  break;
2729  case TLS_SERVER_HELLO:
2730  rc = tls_new_server_hello ( tls, payload, payload_len );
2731  break;
2733  rc = tls_new_session_ticket ( tls, payload,
2734  payload_len );
2735  break;
2736  case TLS_CERTIFICATE:
2737  rc = tls_new_certificate ( tls, payload, payload_len );
2738  break;
2740  rc = tls_new_server_key_exchange ( tls, payload,
2741  payload_len );
2742  break;
2744  rc = tls_new_certificate_request ( tls, payload,
2745  payload_len );
2746  break;
2747  case TLS_SERVER_HELLO_DONE:
2748  rc = tls_new_server_hello_done ( tls, payload,
2749  payload_len );
2750  break;
2751  case TLS_FINISHED:
2752  rc = tls_new_finished ( tls, payload, payload_len );
2753  break;
2754  default:
2755  DBGC ( tls, "TLS %p ignoring handshake type %d\n",
2756  tls, handshake->type );
2757  rc = 0;
2758  break;
2759  }
2760 
2761  /* Add to handshake digest (except for Hello Requests,
2762  * which are explicitly excluded).
2763  */
2764  if ( handshake->type != TLS_HELLO_REQUEST )
2765  tls_add_handshake ( tls, handshake, record_len );
2766 
2767  /* Abort on failure */
2768  if ( rc != 0 )
2769  return rc;
2770 
2771  /* Move to next handshake record */
2772  iob_pull ( iobuf, record_len );
2773  }
2774 
2775  return 0;
2776 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
#define __attribute__(x)
Definition: compiler.h:10
u16 length
Definition: sky2.h:9
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:236
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:818
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:72
#define TLS_SERVER_HELLO_DONE
Definition: tls.h:75
#define TLS_CERTIFICATE_REQUEST
Definition: tls.h:74
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:2085
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:2318
#define TLS_HELLO_REQUEST
Definition: tls.h:68
static int tls_new_finished(struct tls_connection *tls, const void *data, size_t len)
Receive new Finished handshake record.
Definition: tls.c:2617
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
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:2116
unsigned char uint8_t
Definition: stdint.h:10
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:2521
#define TLS_NEW_SESSION_TICKET
Definition: tls.h:71
A TLS 24-bit integer.
Definition: tls.c:221
#define TLS_SERVER_KEY_EXCHANGE
Definition: tls.h:73
void * data
Start of data.
Definition: iobuf.h:52
static int tls_new_certificate(struct tls_connection *tls, const void *data, size_t len)
Receive new Certificate handshake record.
Definition: tls.c:2450
#define TLS_SERVER_HELLO
Definition: tls.h:70
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:2581
#define TLS_FINISHED
Definition: tls.h:78
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:2490

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()

static 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 2785 of file tls.c.

2786  {
2787 
2788  /* RFC4346 says that we should just ignore unknown record types */
2789  iob_pull ( iobuf, iob_len ( iobuf ) );
2790  return 0;
2791 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159

References iob_len(), and iob_pull.

Referenced by tls_new_record().

◆ tls_new_data()

static 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 2800 of file tls.c.

2801  {
2802  struct io_buffer *iobuf;
2803  int rc;
2804 
2805  /* Fail unless we are ready to receive data */
2806  if ( ! tls_ready ( tls ) )
2807  return -ENOTCONN;
2808 
2809  /* Deliver each I/O buffer in turn */
2810  while ( ( iobuf = list_first_entry ( rx_data, struct io_buffer,
2811  list ) ) ) {
2812  list_del ( &iobuf->list );
2813  if ( ( rc = xfer_deliver_iob ( &tls->plainstream,
2814  iobuf ) ) != 0 ) {
2815  DBGC ( tls, "TLS %p could not deliver data: "
2816  "%s\n", tls, strerror ( rc ) );
2817  return rc;
2818  }
2819  }
2820 
2821  return 0;
2822 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:255
#define DBGC(...)
Definition: compiler.h:505
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:259
struct interface plainstream
Plaintext stream.
Definition: tls.h:446
A persistent I/O buffer.
Definition: iobuf.h:37

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()

static 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 2832 of file tls.c.

2833  {
2834  int ( * handler ) ( struct tls_connection *tls,
2835  struct io_buffer *iobuf );
2836  struct io_buffer *tmp = NULL;
2837  struct io_buffer **iobuf;
2838  int rc;
2839 
2840  /* Deliver data records as-is to the plainstream interface */
2841  if ( type == TLS_TYPE_DATA )
2842  return tls_new_data ( tls, rx_data );
2843 
2844  /* Determine handler and fragment buffer */
2845  iobuf = &tmp;
2846  switch ( type ) {
2848  handler = tls_new_change_cipher;
2849  break;
2850  case TLS_TYPE_ALERT:
2851  handler = tls_new_alert;
2852  break;
2853  case TLS_TYPE_HANDSHAKE:
2854  handler = tls_new_handshake;
2855  iobuf = &tls->rx.handshake;
2856  break;
2857  default:
2858  DBGC ( tls, "TLS %p unknown record type %d\n", tls, type );
2859  handler = tls_new_unknown;
2860  break;
2861  }
2862 
2863  /* Merge into a single I/O buffer */
2864  if ( *iobuf )
2865  list_add ( &(*iobuf)->list, rx_data );
2866  *iobuf = iob_concatenate ( rx_data );
2867  if ( ! *iobuf ) {
2868  DBGC ( tls, "TLS %p could not concatenate non-data record "
2869  "type %d\n", tls, type );
2870  rc = -ENOMEM_RX_CONCAT;
2871  goto err_concatenate;
2872  }
2873 
2874  /* Handle record */
2875  if ( ( rc = handler ( tls, *iobuf ) ) != 0 )
2876  goto err_handle;
2877 
2878  /* Discard I/O buffer if empty */
2879  if ( ! iob_len ( *iobuf ) ) {
2880  free_iob ( *iobuf );
2881  *iobuf = NULL;
2882  }
2883 
2884  /* Sanity check */
2885  assert ( tmp == NULL );
2886 
2887  return 0;
2888 
2889  err_handle:
2890  free_iob ( *iobuf );
2891  *iobuf = NULL;
2892  err_concatenate:
2893  return rc;
2894 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct io_buffer * handshake
Received handshake fragment.
Definition: tls.h:390
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
#define ENOMEM_RX_CONCAT
Definition: tls.c:142
unsigned long tmp
Definition: linux_pci.h:64
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
Definition: tls.h:53
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static int tls_new_alert(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Alert record.
Definition: tls.c:2043
static int tls_new_data(struct tls_connection *tls, struct list_head *rx_data)
Receive new data record.
Definition: tls.c:2800
static int tls_new_change_cipher(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Change Cipher record.
Definition: tls.c:2008
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
Definition: iobuf.c:249
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
struct tls_rx rx
Receive state.
Definition: tls.h:468
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:62
static int tls_new_handshake(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Handshake record.
Definition: tls.c:2695
A TLS connection.
Definition: tls.h:428
#define TLS_TYPE_DATA
Application data content type.
Definition: tls.h:65
#define TLS_TYPE_ALERT
Alert content type.
Definition: tls.h:59
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static int tls_new_unknown(struct tls_connection *tls __unused, struct io_buffer *iobuf)
Receive new unknown record.
Definition: tls.c:2785
A persistent I/O buffer.
Definition: iobuf.h:37

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()

static 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 2910 of file tls.c.

2911  {
2912  struct tls_cipher_suite *suite = cipherspec->suite;
2913  struct digest_algorithm *digest = suite->digest;
2914 
2915  hmac_init ( digest, ctx, cipherspec->mac_secret, suite->mac_len );
2916  hmac_update ( digest, ctx, authhdr, sizeof ( *authhdr ) );
2917 }
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition: hmac.c:57
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:200
A TLS cipher suite.
Definition: tls.h:192
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
uint8_t mac_len
MAC length.
Definition: tls.h:212
A message digest algorithm.
Definition: crypto.h:18
void * mac_secret
MAC secret.
Definition: tls.h:258

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()

static 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 2927 of file tls.c.

2928  {
2929  struct digest_algorithm *digest = cipherspec->suite->digest;
2930 
2931  hmac_update ( digest, ctx, data, len );
2932 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:200
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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()

static 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 2941 of file tls.c.

2942  {
2943  struct digest_algorithm *digest = cipherspec->suite->digest;
2944 
2945  hmac_final ( digest, ctx, hmac );
2946 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:200
A message digest algorithm.
Definition: crypto.h:18
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition: hmac.c:87

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

Referenced by tls_hmac(), and tls_hmac_list().

◆ tls_hmac()

static 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 2957 of file tls.c.

2959  {
2960  struct digest_algorithm *digest = cipherspec->suite->digest;
2961  uint8_t ctx[ hmac_ctxsize ( digest ) ];
2962 
2963  tls_hmac_init ( cipherspec, ctx, authhdr );
2964  tls_hmac_update ( cipherspec, ctx, data, len );
2965  tls_hmac_final ( cipherspec, ctx, hmac );
2966 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition: tls.c:2941
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2927
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:200
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition: tls.c:2910
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition: hmac.h:28
unsigned char uint8_t
Definition: stdint.h:10
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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()

static 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 2976 of file tls.c.

2978  {
2979  struct digest_algorithm *digest = cipherspec->suite->digest;
2980  uint8_t ctx[ hmac_ctxsize ( digest ) ];
2981  struct io_buffer *iobuf;
2982 
2983  tls_hmac_init ( cipherspec, ctx, authhdr );
2984  list_for_each_entry ( iobuf, list, list ) {
2985  tls_hmac_update ( cipherspec, ctx, iobuf->data,
2986  iob_len ( iobuf ) );
2987  }
2988  tls_hmac_final ( cipherspec, ctx, hmac );
2989 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition: tls.c:2941
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2927
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:200
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition: tls.c:2910
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition: hmac.h:28
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
unsigned char uint8_t
Definition: stdint.h:10
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
void * data
Start of data.
Definition: iobuf.h:52
A message digest algorithm.
Definition: crypto.h:18
A persistent I/O buffer.
Definition: iobuf.h:37

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()

static 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 2998 of file tls.c.

2998  {
2999  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.active;
3000  struct tls_cipher_suite *suite = cipherspec->suite;
3001  struct cipher_algorithm *cipher = suite->cipher;
3002  struct tls_header *tlshdr;
3003  unsigned int count;
3004  size_t each;
3005 
3006  /* Calculate number of records (allowing for zero-length records) */
3007  count = ( len ? ( ( len + TLS_TX_BUFSIZE - 1 ) / TLS_TX_BUFSIZE ) : 1 );
3008 
3009  /* Calculate maximum additional length per record */
3010  each = ( sizeof ( *tlshdr ) + suite->record_iv_len + suite->mac_len +
3011  ( is_block_cipher ( cipher ) ? cipher->blocksize : 0 ) +
3012  cipher->authsize );
3013 
3014  /* Calculate maximum total additional length */
3015  return ( count * each );
3016 }
size_t blocksize
Block size.
Definition: crypto.h:60
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:210
A TLS cipher specification.
Definition: tls.h:250
size_t authsize
Authentication tag size.
Definition: crypto.h:74
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
ring len
Length.
Definition: dwmac.h:231
static unsigned int count
Number of entries.
Definition: dwmac.h:225
A TLS cipher suite.
Definition: tls.h:192
#define TLS_TX_BUFSIZE
TX maximum fragment length.
Definition: tls.h:484
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
uint8_t mac_len
MAC length.
Definition: tls.h:212
A TLS header.
Definition: tls.h:28
struct tls_tx tx
Transmit state.
Definition: tls.h:466
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:266
A cipher algorithm.
Definition: crypto.h:50
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:198
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:254

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()

static 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 3221 of file tls.c.

3222  {
3223  uint8_t *padding;
3224  unsigned int pad;
3225  unsigned int i;
3226  size_t len;
3227 
3228  /* Extract and verify padding */
3229  padding = ( iobuf->tail - 1 );
3230  pad = *padding;
3231  len = ( pad + 1 );
3232  if ( len > iob_len ( iobuf ) ) {
3233  DBGC ( tls, "TLS %p received underlength padding\n", tls );
3234  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3235  return -EINVAL_PADDING;
3236  }
3237  for ( i = 0 ; i < pad ; i++ ) {
3238  if ( *(--padding) != pad ) {
3239  DBGC ( tls, "TLS %p received bad padding\n", tls );
3240  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3241  return -EINVAL_PADDING;
3242  }
3243  }
3244 
3245  return len;
3246 }
#define EINVAL_PADDING
Definition: tls.c:94
#define DBGC(...)
Definition: compiler.h:505
u32 pad[9]
Padding.
Definition: ar9003_mac.h:90
void * tail
End of data.
Definition: iobuf.h:54
ring len
Length.
Definition: dwmac.h:231
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
void * data
Start of data.
Definition: iobuf.h:52

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()

static 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 3256 of file tls.c.

3258  {
3259  struct tls_cipherspec *cipherspec = &tls->rx.cipherspec.active;
3260  struct tls_cipher_suite *suite = cipherspec->suite;
3261  struct cipher_algorithm *cipher = suite->cipher;
3262  struct digest_algorithm *digest = suite->digest;
3263  size_t len = ntohs ( tlshdr->length );
3264  struct {
3265  uint8_t fixed[suite->fixed_iv_len];
3266  uint8_t record[suite->record_iv_len];
3267  } __attribute__ (( packed )) iv;
3268  struct tls_auth_header authhdr;
3269  uint8_t verify_mac[digest->digestsize];
3270  uint8_t verify_auth[cipher->authsize];
3271  struct io_buffer *first;
3272  struct io_buffer *last;
3273  struct io_buffer *iobuf;
3274  void *mac;
3275  void *auth;
3276  size_t check_len;
3277  int pad_len;
3278  int rc;
3279 
3280  /* Locate first and last data buffers */
3281  assert ( ! list_empty ( rx_data ) );
3282  first = list_first_entry ( rx_data, struct io_buffer, list );
3283  last = list_last_entry ( rx_data, struct io_buffer, list );
3284 
3285  /* Extract initialisation vector */
3286  if ( iob_len ( first ) < sizeof ( iv.record ) ) {
3287  DBGC ( tls, "TLS %p received underlength IV\n", tls );
3288  DBGC_HD ( tls, first->data, iob_len ( first ) );
3289  return -EINVAL_IV;
3290  }
3291  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
3292  memcpy ( iv.record, first->data, sizeof ( iv.record ) );
3293  iob_pull ( first, sizeof ( iv.record ) );
3294  len -= sizeof ( iv.record );
3295 
3296  /* Extract unencrypted authentication tag */
3297  if ( iob_len ( last ) < cipher->authsize ) {
3298  DBGC ( tls, "TLS %p received underlength authentication tag\n",
3299  tls );
3300  DBGC_HD ( tls, last->data, iob_len ( last ) );
3301  return -EINVAL_MAC;
3302  }
3303  iob_unput ( last, cipher->authsize );
3304  len -= cipher->authsize;
3305  auth = last->tail;
3306 
3307  /* Construct authentication data */
3308  authhdr.seq = cpu_to_be64 ( tls->rx.seq );
3309  authhdr.header.type = tlshdr->type;
3310  authhdr.header.version = tlshdr->version;
3311  authhdr.header.length = htons ( len );
3312 
3313  /* Set initialisation vector */
3314  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv, sizeof ( iv ) );
3315 
3316  /* Process authentication data, if applicable */
3317  if ( is_auth_cipher ( cipher ) ) {
3318  cipher_decrypt ( cipher, cipherspec->cipher_ctx, &authhdr,
3319  NULL, sizeof ( authhdr ) );
3320  }
3321 
3322  /* Decrypt the received data */
3323  check_len = 0;
3324  list_for_each_entry ( iobuf, &tls->rx.data, list ) {
3325  cipher_decrypt ( cipher, cipherspec->cipher_ctx,
3326  iobuf->data, iobuf->data, iob_len ( iobuf ) );
3327  check_len += iob_len ( iobuf );
3328  }
3329  assert ( check_len == len );
3330 
3331  /* Strip block padding, if applicable */
3332  if ( is_block_cipher ( cipher ) ) {
3333  pad_len = tls_verify_padding ( tls, last );
3334  if ( pad_len < 0 ) {
3335  /* Assume zero padding length to avoid timing attacks */
3336  pad_len = 0;
3337  }
3338  iob_unput ( last, pad_len );
3339  len -= pad_len;
3340  }
3341 
3342  /* Extract decrypted MAC */
3343  if ( iob_len ( last ) < suite->mac_len ) {
3344  DBGC ( tls, "TLS %p received underlength MAC\n", tls );
3345  DBGC_HD ( tls, last->data, iob_len ( last ) );
3346  return -EINVAL_MAC;
3347  }
3348  iob_unput ( last, suite->mac_len );
3349  len -= suite->mac_len;
3350  mac = last->tail;
3351 
3352  /* Dump received data */
3353  DBGC2 ( tls, "Received plaintext data:\n" );
3354  check_len = 0;
3355  list_for_each_entry ( iobuf, rx_data, list ) {
3356  DBGC2_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3357  check_len += iob_len ( iobuf );
3358  }
3359  assert ( check_len == len );
3360 
3361  /* Generate MAC */
3362  authhdr.header.length = htons ( len );
3363  if ( suite->mac_len )
3364  tls_hmac_list ( cipherspec, &authhdr, rx_data, verify_mac );
3365 
3366  /* Generate authentication tag */
3367  cipher_auth ( cipher, cipherspec->cipher_ctx, verify_auth );
3368 
3369  /* Verify MAC */
3370  if ( memcmp ( mac, verify_mac, suite->mac_len ) != 0 ) {
3371  DBGC ( tls, "TLS %p failed MAC verification\n", tls );
3372  return -EINVAL_MAC;
3373  }
3374 
3375  /* Verify authentication tag */
3376  if ( memcmp ( auth, verify_auth, cipher->authsize ) != 0 ) {
3377  DBGC ( tls, "TLS %p failed authentication tag verification\n",
3378  tls );
3379  return -EINVAL_MAC;
3380  }
3381 
3382  /* Process plaintext record */
3383  if ( ( rc = tls_new_record ( tls, tlshdr->type, rx_data ) ) != 0 )
3384  return rc;
3385 
3386  return 0;
3387 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
#define __attribute__(x)
Definition: compiler.h:10
static int is_auth_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:259
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head data
List of received data buffers.
Definition: tls.h:388
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:210
uint32_t first
First block in range.
Definition: pccrr.h:14
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:378
uint8_t type
Content type.
Definition: tls.h:33
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:40
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition: eltorito.h:13
#define ntohs(value)
Definition: byteswap.h:136
TLS authentication header.
Definition: tls.h:147
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:250
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:346
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
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:2976
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
size_t authsize
Authentication tag size.
Definition: crypto.h:74
#define EINVAL_MAC
Definition: tls.c:102
void * tail
End of data.
Definition: iobuf.h:54
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:256
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:200
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:208
A TLS cipher suite.
Definition: tls.h:192
#define iob_unput(iobuf, len)
Definition: iobuf.h:139
#define DBGC2_HD(...)
Definition: compiler.h:524
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
#define DBGC_HD(...)
Definition: compiler.h:507
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition: crypto.h:218
uint8_t mac_len
MAC length.
Definition: tls.h:212
unsigned char uint8_t
Definition: stdint.h:10
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:238
struct tls_rx rx
Receive state.
Definition: tls.h:468
long pad_len
Definition: bigint.h:30
uint64_t seq
Sequence number.
Definition: tls.h:380
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
#define EINVAL_IV
Definition: tls.c:90
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:26
void * data
Start of data.
Definition: iobuf.h:52
uint16_t version
Protocol version.
Definition: tls.h:38
A message digest algorithm.
Definition: crypto.h:18
#define cpu_to_be64(value)
Definition: byteswap.h:111
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:266
A cipher algorithm.
Definition: crypto.h:50
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition: crypto.h:244
static int tls_new_record(struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
Receive new record.
Definition: tls.c:2832
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:198
static int tls_verify_padding(struct tls_connection *tls, struct io_buffer *iobuf)
Verify block padding.
Definition: tls.c:3221
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:260
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:254
A persistent I/O buffer.
Definition: iobuf.h:37

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, pad_len, rc, tls_cipher_suite::record_iv_len, tls_connection::rx, tls_auth_header::seq, tls_rx::seq, 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()

static 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 3402 of file tls.c.

3402  {
3403 
3404  /* Block window unless we are ready to accept data */
3405  if ( ! tls_ready ( tls ) )
3406  return 0;
3407 
3408  return xfer_window ( &tls->cipherstream );
3409 }
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:448
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:259

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

◆ tls_plainstream_deliver()

static 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 3419 of file tls.c.

3421  {
3422  int rc;
3423 
3424  /* Refuse unless we are ready to accept data */
3425  if ( ! tls_ready ( tls ) ) {
3426  rc = -ENOTCONN;
3427  goto done;
3428  }
3429 
3430  /* Send data record */
3431  if ( ( rc = tls_send_record ( tls, TLS_TYPE_DATA,
3432  iob_disown ( iobuf ) ) ) != 0 )
3433  goto done;
3434 
3435  done:
3436  free_iob ( iobuf );
3437  return rc;
3438 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int tls_send_record(struct tls_connection *tls, unsigned int type, struct io_buffer *iobuf)
Send plaintext record(s)
Definition: tls.c:3052
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:216
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:259
#define TLS_TYPE_DATA
Application data content type.
Definition: tls.h:65
struct bofm_section_header done
Definition: bofm_test.c:46

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

◆ tls_progress()

static 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 3447 of file tls.c.

3448  {
3449 
3450  /* Return cipherstream or validator progress as applicable */
3451  if ( is_pending ( &tls->server.validation ) ) {
3452  return job_progress ( &tls->server.validator, progress );
3453  } else {
3454  return job_progress ( &tls->cipherstream, progress );
3455  }
3456 }
struct tls_server server
Server state.
Definition: tls.h:472
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:448
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:422
struct interface validator
Certificate validator.
Definition: tls.h:420
int job_progress(struct interface *intf, struct job_progress *progress)
Get job progress.
Definition: job.c:43

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

◆ tls_newdata_process_header()

static 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 3487 of file tls.c.

3487  {
3488  struct tls_cipherspec *cipherspec = &tls->rx.cipherspec.active;
3489  struct cipher_algorithm *cipher = cipherspec->suite->cipher;
3490  size_t iv_len = cipherspec->suite->record_iv_len;
3491  size_t data_len = ntohs ( tls->rx.header.length );
3492  size_t remaining = data_len;
3493  size_t frag_len;
3494  size_t reserve;
3495  struct io_buffer *iobuf;
3496  struct io_buffer *tmp;
3497  int rc;
3498 
3499  /* Sanity check */
3500  assert ( ( TLS_RX_BUFSIZE % cipher->alignsize ) == 0 );
3501 
3502  /* Calculate alignment reservation at start of first data buffer */
3503  reserve = ( ( -iv_len ) & ( cipher->alignsize - 1 ) );
3504  remaining += reserve;
3505 
3506  /* Allocate data buffers now that we know the length */
3507  assert ( list_empty ( &tls->rx.data ) );
3508  while ( remaining ) {
3509 
3510  /* Calculate fragment length. Ensure that no block is
3511  * smaller than TLS_RX_MIN_BUFSIZE (by increasing the
3512  * allocation length if necessary).
3513  */
3514  frag_len = remaining;
3515  if ( frag_len > TLS_RX_BUFSIZE )
3516  frag_len = TLS_RX_BUFSIZE;
3517  remaining -= frag_len;
3518  if ( remaining < TLS_RX_MIN_BUFSIZE ) {
3519  frag_len += remaining;
3520  remaining = 0;
3521  }
3522 
3523  /* Allocate buffer */
3524  iobuf = alloc_iob_raw ( frag_len, TLS_RX_ALIGN, 0 );
3525  if ( ! iobuf ) {
3526  DBGC ( tls, "TLS %p could not allocate %zd of %zd "
3527  "bytes for receive buffer\n", tls,
3528  remaining, data_len );
3529  rc = -ENOMEM_RX_DATA;
3530  goto err;
3531  }
3532 
3533  /* Ensure tailroom is exactly what we asked for. This
3534  * will result in unaligned I/O buffers when the
3535  * fragment length is unaligned, which can happen only
3536  * before we switch to using a block cipher.
3537  */
3538  iob_reserve ( iobuf, ( iob_tailroom ( iobuf ) - frag_len ) );
3539 
3540  /* Ensure first buffer length will be aligned to a
3541  * multiple of the cipher alignment size after
3542  * stripping the record IV.
3543  */
3544  iob_reserve ( iobuf, reserve );
3545  reserve = 0;
3546 
3547  /* Add I/O buffer to list */
3548  list_add_tail ( &iobuf->list, &tls->rx.data );
3549  }
3550 
3551  /* Move to data state */
3552  tls->rx.state = TLS_RX_DATA;
3553 
3554  return 0;
3555 
3556  err:
3557  list_for_each_entry_safe ( iobuf, tmp, &tls->rx.data, list ) {
3558  list_del ( &iobuf->list );
3559  free_iob ( iobuf );
3560  }
3561  return rc;
3562 }
struct tls_header header
Current received record header.
Definition: tls.h:384
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head data
List of received data buffers.
Definition: tls.h:388
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:210
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:378
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
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:48
size_t alignsize
Alignment size.
Definition: crypto.h:72
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:40
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
#define ntohs(value)
Definition: byteswap.h:136
A TLS cipher specification.
Definition: tls.h:250
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:64
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define ENOMEM_RX_DATA
Definition: tls.c:138
#define TLS_RX_ALIGN
RX I/O buffer alignment.
Definition: tls.h:505
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:252
#define TLS_RX_BUFSIZE
RX I/O buffer size.
Definition: tls.h:494
#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:458
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:179
#define TLS_RX_MIN_BUFSIZE
Minimum RX I/O buffer size.
Definition: tls.h:502
struct tls_rx rx
Receive state.
Definition: tls.h:468
enum tls_rx_state state
State machine current state.
Definition: tls.h:382
#define iob_reserve(iobuf, len)
Definition: iobuf.h:71
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:266
A cipher algorithm.
Definition: crypto.h:50
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:198
A persistent I/O buffer.
Definition: iobuf.h:37

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()

static 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 3570 of file tls.c.

3570  {
3571  struct io_buffer *iobuf;
3572  int rc;
3573 
3574  /* Move current buffer to end of list */
3575  iobuf = list_first_entry ( &tls->rx.data, struct io_buffer, list );
3576  list_del ( &iobuf->list );
3577  list_add_tail ( &iobuf->list, &tls->rx.data );
3578 
3579  /* Continue receiving data if any space remains */
3580  iobuf = list_first_entry ( &tls->rx.data, struct io_buffer, list );
3581  if ( iob_tailroom ( iobuf ) )
3582  return 0;
3583 
3584  /* Process record */
3585  if ( ( rc = tls_new_ciphertext ( tls, &tls->rx.header,
3586  &tls->rx.data ) ) != 0 )
3587  return rc;
3588 
3589  /* Increment RX sequence number */
3590  tls->rx.seq += 1;
3591 
3592  /* Return to header state */
3593  assert ( list_empty ( &tls->rx.data ) );
3594  tls->rx.state = TLS_RX_HEADER;
3595  iob_unput ( &tls->rx.iobuf, sizeof ( tls->rx.header ) );
3596 
3597  return 0;
3598 }
struct tls_header header
Current received record header.
Definition: tls.h:384
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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:3256
struct list_head data
List of received data buffers.
Definition: tls.h:388
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define iob_unput(iobuf, len)
Definition: iobuf.h:139
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:179
struct tls_rx rx
Receive state.
Definition: tls.h:468
enum tls_rx_state state
State machine current state.
Definition: tls.h:382
uint64_t seq
Sequence number.
Definition: tls.h:380
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:386
A persistent I/O buffer.
Definition: iobuf.h:37

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()

static 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 3606 of file tls.c.

3606  {
3607 
3608  /* Open window until we are ready to accept data */
3609  if ( ! tls_ready ( tls ) )
3610  return -1UL;
3611 
3612  return xfer_window ( &tls->plainstream );
3613 }
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:259
struct interface plainstream
Plaintext stream.
Definition: tls.h:446

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

◆ tls_cipherstream_deliver()

static 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 3623 of file tls.c.

3625  {
3626  size_t frag_len;
3627  int ( * process ) ( struct tls_connection *tls );
3628  struct io_buffer *dest;
3629  int rc;
3630 
3631  while ( iob_len ( iobuf ) ) {
3632 
3633  /* Select buffer according to current state */
3634  switch ( tls->rx.state ) {
3635  case TLS_RX_HEADER:
3636  dest = &tls->rx.iobuf;
3638  break;
3639  case TLS_RX_DATA:
3640  dest = list_first_entry ( &tls->rx.data,
3641  struct io_buffer, list );
3642  assert ( dest != NULL );
3644  break;
3645  default:
3646  assert ( 0 );
3647  rc = -EINVAL_RX_STATE;
3648  goto done;
3649  }
3650 
3651  /* Copy data portion to buffer */
3652  frag_len = iob_len ( iobuf );
3653  if ( frag_len > iob_tailroom ( dest ) )
3654  frag_len = iob_tailroom ( dest );
3655  memcpy ( iob_put ( dest, frag_len ), iobuf->data, frag_len );
3656  iob_pull ( iobuf, frag_len );
3657 
3658  /* Process data if buffer is now full */
3659  if ( iob_tailroom ( dest ) == 0 ) {
3660  if ( ( rc = process ( tls ) ) != 0 ) {
3661  tls_close ( tls, rc );
3662  goto done;
3663  }
3664  }
3665  }
3666  rc = 0;
3667 
3668  done:
3669  free_iob ( iobuf );
3670  return rc;
3671 }
A process.
Definition: process.h:17
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:124
static int tls_newdata_process_header(struct tls_connection *tls)
Handle received TLS header.
Definition: tls.c:3487
struct list_head data
List of received data buffers.
Definition: tls.h:388
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:421
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int tls_newdata_process_data(struct tls_connection *tls)
Handle received TLS data payload.
Definition: tls.c:3570
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define EINVAL_RX_STATE
Definition: tls.c:98
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:179
struct tls_rx rx
Receive state.
Definition: tls.h:468
enum tls_rx_state state
State machine current state.
Definition: tls.h:382
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:386
void * data
Start of data.
Definition: iobuf.h:52
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" return dest
Definition: string.h:150
A TLS connection.
Definition: tls.h:428
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct bofm_section_header done
Definition: bofm_test.c:46
A persistent I/O buffer.
Definition: iobuf.h:37

References 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(), tls_newdata_process_data(), tls_newdata_process_header(), TLS_RX_DATA, and TLS_RX_HEADER.

◆ tls_validator_done()

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

Handle certificate validation completion.

Parameters
tlsTLS connection
rcReason for completion

Definition at line 3702 of file tls.c.

3702  {
3703  struct tls_session *session = tls->session;
3704  struct x509_certificate *cert;
3705 
3706  /* Mark validation as complete */
3707  pending_put ( &tls->server.validation );
3708 
3709  /* Close validator interface */
3710  intf_restart ( &tls->server.validator, rc );
3711 
3712  /* Check for validation failure */
3713  if ( rc != 0 ) {
3714  DBGC ( tls, "TLS %p certificate validation failed: %s\n",
3715  tls, strerror ( rc ) );
3716  goto err;
3717  }
3718  DBGC ( tls, "TLS %p certificate validation succeeded\n", tls );
3719 
3720  /* Extract first certificate */
3721  cert = x509_first ( tls->server.chain );
3722  assert ( cert != NULL );
3723 
3724  /* Verify server name */
3725  if ( ( rc = x509_check_name ( cert, session->name ) ) != 0 ) {
3726  DBGC ( tls, "TLS %p server certificate does not match %s: %s\n",
3727  tls, session->name, strerror ( rc ) );
3728  goto err;
3729  }
3730 
3731  /* Extract the now trusted server public key */
3732  memcpy ( &tls->server.key, &cert->subject.public_key.raw,
3733  sizeof ( tls->server.key ) );
3734 
3735  /* Schedule transmission of applicable handshake messages */
3738  TLS_TX_FINISHED );
3739  if ( tls->client.chain ) {
3740  tls->tx.pending |= TLS_TX_CERTIFICATE;
3741  if ( ! list_empty ( &tls->client.chain->links ) )
3743  }
3744  tls_tx_resume ( tls );
3745 
3746  return;
3747 
3748  err:
3749  tls_close ( tls, rc );
3750  return;
3751 }
struct asn1_cursor raw
Raw public key information.
Definition: x509.h:51
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:418
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1109
struct tls_session * session
Session.
Definition: tls.h:433
struct list_head links
List of links.
Definition: x509.h:204
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition: x509.c:1563
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
#define DBGC(...)
Definition: compiler.h:505
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:421
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
struct tls_server server
Server state.
Definition: tls.h:472
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:470
struct x509_public_key public_key
Public key information.
Definition: x509.h:65
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:215
struct x509_subject subject
Subject.
Definition: x509.h:244
struct x509_chain * chain
Certificate chain.
Definition: tls.h:416
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:422
unsigned int pending
Pending transmissions.
Definition: tls.h:370
struct tls_tx tx
Transmit state.
Definition: tls.h:466
A TLS session.
Definition: tls.h:333
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:310
struct interface validator
Certificate validator.
Definition: tls.h:420
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:400
const char * name
Server name.
Definition: tls.h:340
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References assert(), tls_client::chain, tls_server::chain, tls_connection::client, DBGC, intf_restart(), tls_server::key, x509_chain::links, list_empty, memcpy(), tls_session::name, NULL, tls_tx::pending, pending_put(), x509_subject::public_key, x509_public_key::raw, rc, tls_connection::server, tls_connection::session, strerror(), x509_certificate::subject, tls_close(), 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, tls_server::validator, x509_check_name(), and x509_first().

◆ tls_tx_step()

static void tls_tx_step ( struct tls_connection tls)
static

TLS TX state machine.

Parameters
tlsTLS connection

Definition at line 3775 of file tls.c.

3775  {
3776  struct tls_session *session = tls->session;
3777  struct tls_connection *conn;
3778  int rc;
3779 
3780  /* Wait for cipherstream to become ready */
3781  if ( ! xfer_window ( &tls->cipherstream ) )
3782  return;
3783 
3784  /* Send first pending transmission */
3785  if ( tls->tx.pending & TLS_TX_CLIENT_HELLO ) {
3786  /* Serialise server negotiations within a session, to
3787  * provide a consistent view of session IDs and
3788  * session tickets.
3789  */
3790  list_for_each_entry ( conn, &session->conn, list ) {
3791  if ( conn == tls )
3792  break;
3793  if ( is_pending ( &conn->server.negotiation ) )
3794  return;
3795  }
3796  /* Record or generate session ID and associated master secret */
3797  if ( session->id_len ) {
3798  /* Attempt to resume an existing session */
3799  memcpy ( tls->session_id, session->id,
3800  sizeof ( tls->session_id ) );
3801  tls->session_id_len = session->id_len;
3803  sizeof ( tls->master_secret ) );
3804  } else {
3805  /* No existing session: use a random session ID */
3806  assert ( sizeof ( tls->session_id ) ==
3807  sizeof ( tls->client.random ) );
3808  memcpy ( tls->session_id, &tls->client.random,
3809  sizeof ( tls->session_id ) );
3810  tls->session_id_len = sizeof ( tls->session_id );
3811  }
3812  /* Send Client Hello */
3813  if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
3814  DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
3815  tls, strerror ( rc ) );
3816  goto err;
3817  }
3818  tls->tx.pending &= ~TLS_TX_CLIENT_HELLO;
3819  } else if ( tls->tx.pending & TLS_TX_CERTIFICATE ) {
3820  /* Send Certificate */
3821  if ( ( rc = tls_send_certificate ( tls ) ) != 0 ) {
3822  DBGC ( tls, "TLS %p cold not send Certificate: %s\n",
3823  tls, strerror ( rc ) );
3824  goto err;
3825  }
3826  tls->tx.pending &= ~TLS_TX_CERTIFICATE;
3827  } else if ( tls->tx.pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
3828  /* Send Client Key Exchange */
3829  if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
3830  DBGC ( tls, "TLS %p could not send Client Key "
3831  "Exchange: %s\n", tls, strerror ( rc ) );
3832  goto err;
3833  }
3835  } else if ( tls->tx.pending & TLS_TX_CERTIFICATE_VERIFY ) {
3836  /* Send Certificate Verify */
3837  if ( ( rc = tls_send_certificate_verify ( tls ) ) != 0 ) {
3838  DBGC ( tls, "TLS %p could not send Certificate "
3839  "Verify: %s\n", tls, strerror ( rc ) );
3840  goto err;
3841  }
3843  } else if ( tls->tx.pending & TLS_TX_CHANGE_CIPHER ) {
3844  /* Send Change Cipher, and then change the cipher in use */
3845  if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
3846  DBGC ( tls, "TLS %p could not send Change Cipher: "
3847  "%s\n", tls, strerror ( rc ) );
3848  goto err;
3849  }
3850  if ( ( rc = tls_change_cipher ( tls,
3851  &tls->tx.cipherspec ) ) != 0 ){
3852  DBGC ( tls, "TLS %p could not activate TX cipher: "
3853  "%s\n", tls, strerror ( rc ) );
3854  goto err;
3855  }
3856  tls->tx.seq = 0;
3857  tls->tx.pending &= ~TLS_TX_CHANGE_CIPHER;
3858  } else if ( tls->tx.pending & TLS_TX_FINISHED ) {
3859  /* Send Finished */
3860  if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
3861  DBGC ( tls, "TLS %p could not send Finished: %s\n",
3862  tls, strerror ( rc ) );
3863  goto err;
3864  }
3865  tls->tx.pending &= ~TLS_TX_FINISHED;
3866  }
3867 
3868  /* Reschedule process if pending transmissions remain,
3869  * otherwise send notification of a window change.
3870  */
3871  if ( tls->tx.pending ) {
3872  tls_tx_resume ( tls );
3873  } else {
3874  xfer_window_changed ( &tls->plainstream );
3875  }
3876 
3877  return;
3878 
3879  err:
3880  tls_close ( tls, rc );
3881 }
static int tls_send_certificate(struct tls_connection *tls)
Transmit Certificate record.
Definition: tls.c:1359
uint8_t id[32]
Session ID.
Definition: tls.h:347
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec_pair *pair)
Activate next cipher suite.
Definition: tls.c:982
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1109
struct tls_session * session
Session.
Definition: tls.h:433
uint8_t master_secret[48]
Master secret.
Definition: tls.h:355
#define DBGC(...)
Definition: compiler.h:505
uint8_t session_id[32]
Session ID.
Definition: tls.h:437
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:421
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
struct tls_server server
Server state.
Definition: tls.h:472
void * memcpy(void *dest, const void *src, size_t len) __nonnull
size_t id_len
Length of session ID.
Definition: tls.h:349
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:470
static int tls_send_change_cipher(struct tls_connection *tls)
Transmit Change Cipher record.
Definition: tls.c:1950
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct list_head list
List of connections within the same session.
Definition: tls.h:435
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
uint8_t master_secret[48]
Master secret.
Definition: tls.h:453
static int tls_send_client_key_exchange(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition: tls.c:1841
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint64_t seq
Sequence number.
Definition: tls.h:368
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:448
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:424
unsigned int pending
Pending transmissions.
Definition: tls.h:370
struct tls_tx tx
Transmit state.
Definition: tls.h:466
static int tls_send_certificate_verify(struct tls_connection *tls)
Transmit Certificate Verify record.
Definition: tls.c:1869
A TLS session.
Definition: tls.h:333
A TLS connection.
Definition: tls.h:428
struct tls_client_random random
Random bytes.
Definition: tls.h:396
struct list_head conn
List of connections.
Definition: tls.h:360
static int tls_send_finished(struct tls_connection *tls)
Transmit Finished record.
Definition: tls.c:1967
static int tls_send_client_hello(struct tls_connection *tls)
Transmit Client Hello record.
Definition: tls.c:1348
size_t session_id_len
Length of session ID.
Definition: tls.h:439
struct interface plainstream
Plaintext stream.
Definition: tls.h:446

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, tls_session::master_secret, tls_connection::master_secret, 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(), 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()

static 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 3901 of file tls.c.

3901  {
3902  struct tls_session *session;
3903  char *name_copy;
3904  int rc;
3905 
3906  /* Find existing matching session, if any */
3907  list_for_each_entry ( session, &tls_sessions, list ) {
3908  if ( ( strcmp ( name, session->name ) == 0 ) &&
3909  ( tls->server.root == session->root ) &&
3910  ( tls->client.key == session->key ) ) {
3911  ref_get ( &session->refcnt );
3912  tls->session = session;
3913  DBGC ( tls, "TLS %p joining session %s\n", tls, name );
3914  return 0;
3915  }
3916  }
3917 
3918  /* Create new session */
3919  session = zalloc ( sizeof ( *session ) + strlen ( name )
3920  + 1 /* NUL */ );
3921  if ( ! session ) {
3922  rc = -ENOMEM;
3923  goto err_alloc;
3924  }
3925  ref_init ( &session->refcnt, free_tls_session );
3926  name_copy = ( ( ( void * ) session ) + sizeof ( *session ) );
3927  strcpy ( name_copy, name );
3928  session->name = name_copy;
3929  session->root = x509_root_get ( tls->server.root );
3930  session->key = privkey_get ( tls->client.key );
3931  INIT_LIST_HEAD ( &session->conn );
3932  list_add ( &session->list, &tls_sessions );
3933 
3934  /* Record session */
3935  tls->session = session;
3936 
3937  DBGC ( tls, "TLS %p created session %s\n", tls, name );
3938  return 0;
3939 
3940  ref_put ( &session->refcnt );
3941  err_alloc:
3942  return rc;
3943 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
struct tls_session * session
Session.
Definition: tls.h:433
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
#define DBGC(...)
Definition: compiler.h:505
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
Definition: privkey.h:30
static void free_tls_session(struct refcnt *refcnt)
Free TLS session.
Definition: tls.c:358
struct private_key * key
Private key (if used)
Definition: tls.h:398
struct tls_server server
Server state.
Definition: tls.h:472
struct refcnt refcnt
Reference counter.
Definition: tls.h:335
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct tls_client client
Client state.
Definition: tls.h:470
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:346
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:392
struct list_head list
List of sessions.
Definition: tls.h:337
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
A TLS session.
Definition: tls.h:333
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
struct x509_root * root
Root of trust.
Definition: tls.h:342
struct private_key * key
Private key.
Definition: tls.h:344
struct list_head conn
List of connections.
Definition: tls.h:360
const char * name
Server name.
Definition: tls.h:340
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
struct x509_root * root
Root of trust.
Definition: tls.h:414

References tls_connection::client, tls_session::conn, DBGC, ENOMEM, free_tls_session(), INIT_LIST_HEAD, tls_session::key, tls_client::key, tls_session::list, list_add, list_for_each_entry, tls_session::name, name, privkey_get(), rc, ref_get, ref_init, ref_put, tls_session::refcnt, tls_session::root, tls_server::root, tls_connection::server, tls_connection::session, strcmp(), strcpy(), strlen(), 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 3961 of file tls.c.

3962  {
3963  struct tls_connection *tls;
3964  int rc;
3965 
3966  /* Allocate and initialise TLS structure */
3967  tls = malloc ( sizeof ( *tls ) );
3968  if ( ! tls ) {
3969  rc = -ENOMEM;
3970  goto err_alloc;
3971  }
3972  memset ( tls, 0, sizeof ( *tls ) );
3973  ref_init ( &tls->refcnt, free_tls );
3974  INIT_LIST_HEAD ( &tls->list );
3975  intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt );
3977  intf_init ( &tls->server.validator, &tls_validator_desc, &tls->refcnt );
3979  &tls->refcnt );
3980  tls->client.key = privkey_get ( key ? key : &private_key );
3982  tls->version = TLS_VERSION_MAX;
3983  tls_clear_cipher ( tls, &tls->tx.cipherspec.active );
3984  tls_clear_cipher ( tls, &tls->tx.cipherspec.pending );
3985  tls_clear_cipher ( tls, &tls->rx.cipherspec.active );
3986  tls_clear_cipher ( tls, &tls->rx.cipherspec.pending );
3987  tls_clear_handshake ( tls );
3988  tls->client.random.gmt_unix_time = time ( NULL );
3989  iob_populate ( &tls->rx.iobuf, &tls->rx.header, 0,
3990  sizeof ( tls->rx.header ) );
3991  INIT_LIST_HEAD ( &tls->rx.data );
3992  if ( ( rc = tls_generate_random ( tls, &tls->client.random.random,
3993  ( sizeof ( tls->client.random.random ) ) ) ) != 0 ) {
3994  goto err_random;
3995  }
3996  if ( ( rc = tls_session ( tls, name ) ) != 0 )
3997  goto err_session;
3998  list_add_tail ( &tls->list, &tls->session->conn );
3999 
4000  /* Start negotiation */
4001  tls_restart ( tls );
4002 
4003  /* Attach to parent interface, mortalise self, and return */
4004  intf_insert ( xfer, &tls->plainstream, &tls->cipherstream );
4005  ref_put ( &tls->refcnt );
4006  return 0;
4007 
4008  err_session:
4009  err_random:
4010  ref_put ( &tls->refcnt );
4011  err_alloc:
4012  return rc;
4013 }
static void free_tls(struct refcnt *refcnt)
Free TLS connection.
Definition: tls.c:382
struct tls_header header
Current received record header.
Definition: tls.h:384
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
struct process process
Transmit process.
Definition: tls.h:372
struct tls_session * session
Session.
Definition: tls.h:433
struct list_head data
List of received data buffers.
Definition: tls.h:388
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition: tls.c:1130
struct stp_switch root
Root switch.
Definition: stp.h:26
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
struct refcnt refcnt
Reference counter.
Definition: tls.h:430
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:378
struct x509_root root_certificates
Root certificates.
Definition: rootcert.c:78
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
Definition: privkey.h:30
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:194
static struct interface_descriptor tls_cipherstream_desc
TLS ciphertext stream interface descriptor.
Definition: tls.c:3685
static struct interface_descriptor tls_validator_desc
TLS certificate validator interface descriptor.
Definition: tls.c:3759
struct private_key * key
Private key (if used)
Definition: tls.h:398
struct tls_server server
Server state.
Definition: tls.h:472
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct tls_client client
Client state.
Definition: tls.h:470
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct list_head list
List of connections within the same session.
Definition: tls.h:435
uint32_t gmt_unix_time
GMT Unix time.
Definition: tls.h:305
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:392
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:366
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:448
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:145
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:268
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
struct tls_rx rx
Receive state.
Definition: tls.h:468
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
struct tls_tx tx
Transmit state.
Definition: tls.h:466
static struct interface_descriptor tls_plainstream_desc
TLS plaintext stream interface descriptor.
Definition: tls.c:3470
void intf_insert(struct interface *intf, struct interface *upper, struct interface *lower)
Insert a filter interface.
Definition: interface.c:401
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
uint8_t random[28]
Random data.
Definition: tls.h:307
A TLS session.
Definition: tls.h:333
static struct process_descriptor tls_process_desc
TLS TX process descriptor.
Definition: tls.c:3884
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:386
struct interface validator
Certificate validator.
Definition: tls.h:420
uint16_t version
Protocol version.
Definition: tls.h:451
static void tls_clear_handshake(struct tls_connection *tls)
Clear handshake digest algorithm.
Definition: tls.c:777
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:266
A private key.
Definition: privkey.h:16
A TLS connection.
Definition: tls.h:428
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct tls_client_random random
Random bytes.
Definition: tls.h:396
struct list_head conn
List of connections.
Definition: tls.h:360
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:459
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
struct interface plainstream
Plaintext stream.
Definition: tls.h:446
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @391 key
Sense key.
Definition: scsi.h:17
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
void * memset(void *dest, int character, size_t len) __nonnull
struct x509_root * root
Root of trust.
Definition: tls.h:414

References tls_cipherspec_pair::active, tls_tx::cipherspec, tls_rx::cipherspec, tls_connection::cipherstream, tls_connection::client, tls_session::conn, tls_rx::data, ENOMEM, free_tls(), tls_client_random::gmt_unix_time, 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, NULL, tls_cipherspec_pair::pending, tls_connection::plainstream, privkey_get(), tls_tx::process, process_init_stopped(), tls_client_random::random, tls_client::random, 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_handshake(), tls_generate_random(), 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(), and ipair_rx_session().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( add_tls  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_crypto  )

Variable Documentation

◆ md5_sha1_algorithm

struct digest_algorithm md5_sha1_algorithm
static
Initial value:
= {
.name = "md5+sha1",
.ctxsize = sizeof ( struct md5_sha1_context ),
.blocksize = 0,
.digestsize = sizeof ( struct md5_sha1_digest ),
.init = md5_sha1_init,
.update = md5_sha1_update,
.final = md5_sha1_final,
}
An MD5+SHA1 context.
Definition: tls.h:311
static void md5_sha1_final(void *ctx, void *out)
Generate MD5+SHA1 digest.
Definition: tls.c:320
static void md5_sha1_init(void *ctx)
Initialise MD5+SHA1 algorithm.
Definition: tls.c:293
An MD5+SHA1 digest.
Definition: tls.h:322
static void md5_sha1_update(void *ctx, const void *data, size_t len)
Accumulate data with MD5+SHA1 algorithm.
Definition: tls.c:307

Hybrid MD5+SHA1 digest algorithm.

Definition at line 329 of file tls.c.

Referenced by tls_select_cipher(), and tls_verify_dh_params().

◆ __rsa_digestinfo_prefix

struct rsa_digestinfo_prefix rsa_md5_sha1_prefix __rsa_digestinfo_prefix
Initial value:
= {
.digest = &md5_sha1_algorithm,
.data = NULL,
.len = 0,
}
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:329
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

RSA digestInfo prefix for MD5+SHA1 algorithm.

Definition at line 340 of file tls.c.

◆ tls_cipher_suite_null

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

Null cipher suite.

Definition at line 850 of file tls.c.

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_send_client_key_exchange_pubkey(struct tls_connection *tls)
Transmit Client Key Exchange record using public key exchange.
Definition: tls.c:1416

Public key exchange algorithm.

Definition at line 1485 of file tls.c.

◆ 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:1586

Ephemeral Diffie-Hellman key exchange algorithm.

Definition at line 1700 of file tls.c.

◆ tls_ecdhe_exchange_algorithm

struct tls_key_exchange_algorithm tls_ecdhe_exchange_algorithm
Initial value:
= {
.name = "ecdhe",
}
static int tls_send_client_key_exchange_ecdhe(struct tls_connection *tls)
Transmit Client Key Exchange record using ECDHE key exchange.
Definition: tls.c:1711

Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm.

Definition at line 1830 of file tls.c.

◆ 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:249
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:421
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
static int tls_progress(struct tls_connection *tls, struct job_progress *progress)
Report job progress.
Definition: tls.c:3447
Job progress.
Definition: job.h:15
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
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:3419
A TLS connection.
Definition: tls.h:428
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:3025
static size_t tls_plainstream_window(struct tls_connection *tls)
Check flow control window.
Definition: tls.c:3402

TLS plaintext stream interface operations.

Definition at line 3459 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 )
static struct interface_operation tls_plainstream_ops[]
TLS plaintext stream interface operations.
Definition: tls.c:3459
A TLS connection.
Definition: tls.h:428
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:97

TLS plaintext stream interface descriptor.

Definition at line 3470 of file tls.c.

Referenced by add_tls().

◆ tls_cipherstream_ops

struct interface_operation tls_cipherstream_ops[]
static
Initial value:
= {
}
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1109
static int tls_cipherstream_deliver(struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *xfer __unused)
Receive new ciphertext.
Definition: tls.c:3623
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:421
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
A TLS connection.
Definition: tls.h:428
static size_t tls_cipherstream_window(struct tls_connection *tls)
Check flow control window.
Definition: tls.c:3606

TLS ciphertext stream interface operations.

Definition at line 3674 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:3674
A TLS connection.
Definition: tls.h:428
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:97

TLS ciphertext stream interface descriptor.

Definition at line 3685 of file tls.c.

Referenced by add_tls().

◆ tls_validator_ops

struct interface_operation tls_validator_ops[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
static void tls_validator_done(struct tls_connection *tls, int rc)
Handle certificate validation completion.
Definition: tls.c:3702
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
A TLS connection.
Definition: tls.h:428

TLS certificate validator interface operations.

Definition at line 3754 of file tls.c.

◆ tls_validator_desc

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

TLS certificate validator interface descriptor.

Definition at line 3759 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:97
static void tls_tx_step(struct tls_connection *tls)
TLS TX state machine.
Definition: tls.c:3775
A TLS connection.
Definition: tls.h:428
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition: wpa.h:237

TLS TX process descriptor.

Definition at line 3884 of file tls.c.

Referenced by add_tls().