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)
 
 FILE_SECBOOT (PERMITTED)
 
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 59 of file tls.c.

◆ EINFO_EINVAL_CHANGE_CIPHER

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

Definition at line 60 of file tls.c.

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

Definition at line 63 of file tls.c.

◆ EINFO_EINVAL_ALERT

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

Definition at line 64 of file tls.c.

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

Definition at line 67 of file tls.c.

◆ EINFO_EINVAL_HELLO

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

Definition at line 68 of file tls.c.

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

Definition at line 71 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATE

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

Definition at line 72 of file tls.c.

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

Definition at line 75 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATES

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

Definition at line 76 of file tls.c.

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

Definition at line 79 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:430
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 80 of file tls.c.

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

Definition at line 83 of file tls.c.

◆ EINFO_EINVAL_FINISHED

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

Definition at line 84 of file tls.c.

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

Definition at line 87 of file tls.c.

◆ EINFO_EINVAL_HANDSHAKE

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

Definition at line 88 of file tls.c.

◆ EINVAL_IV

#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )

Definition at line 91 of file tls.c.

◆ EINFO_EINVAL_IV

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

Definition at line 92 of file tls.c.

◆ EINVAL_PADDING

#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )

Definition at line 95 of file tls.c.

◆ EINFO_EINVAL_PADDING

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

Definition at line 96 of file tls.c.

◆ EINVAL_RX_STATE

#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )

Definition at line 99 of file tls.c.

◆ EINFO_EINVAL_RX_STATE

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

Definition at line 100 of file tls.c.

◆ EINVAL_MAC

#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )

Definition at line 103 of file tls.c.

◆ EINFO_EINVAL_MAC

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

Definition at line 104 of file tls.c.

◆ EINVAL_TICKET

#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )

Definition at line 107 of file tls.c.

◆ EINFO_EINVAL_TICKET

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

Definition at line 108 of file tls.c.

◆ EINVAL_KEY_EXCHANGE

#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )

Definition at line 111 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:430
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 112 of file tls.c.

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

Definition at line 115 of file tls.c.

◆ EINFO_EIO_ALERT

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

Definition at line 116 of file tls.c.

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

Definition at line 119 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:181
#define EINFO_ENOMEM
Definition: errno.h:536

Definition at line 120 of file tls.c.

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

Definition at line 123 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:181
#define EINFO_ENOMEM
Definition: errno.h:536

Definition at line 124 of file tls.c.

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

Definition at line 127 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:181
#define EINFO_ENOMEM
Definition: errno.h:536

Definition at line 128 of file tls.c.

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

Definition at line 131 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:181
#define EINFO_ENOMEM
Definition: errno.h:536

Definition at line 132 of file tls.c.

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

Definition at line 135 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:181
#define EINFO_ENOMEM
Definition: errno.h:536

Definition at line 136 of file tls.c.

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

Definition at line 139 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:181
#define EINFO_ENOMEM
Definition: errno.h:536

Definition at line 140 of file tls.c.

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

Definition at line 143 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:181
#define EINFO_ENOMEM
Definition: errno.h:536

Definition at line 144 of file tls.c.

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

Definition at line 147 of file tls.c.

◆ EINFO_ENOTSUP_CIPHER

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

Definition at line 148 of file tls.c.

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

Definition at line 151 of file tls.c.

◆ EINFO_ENOTSUP_NULL

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

Definition at line 152 of file tls.c.

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

Definition at line 155 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:591
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 156 of file tls.c.

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

Definition at line 159 of file tls.c.

◆ EINFO_ENOTSUP_VERSION

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

Definition at line 160 of file tls.c.

◆ ENOTSUP_CURVE

#define ENOTSUP_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )

Definition at line 163 of file tls.c.

◆ EINFO_ENOTSUP_CURVE

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

Definition at line 164 of file tls.c.

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

Definition at line 167 of file tls.c.

◆ EINFO_EPERM_ALERT

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

Definition at line 168 of file tls.c.

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

Definition at line 171 of file tls.c.

◆ EINFO_EPERM_VERIFY

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

Definition at line 172 of file tls.c.

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

Definition at line 175 of file tls.c.

◆ EINFO_EPERM_RENEG_INSECURE

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

Definition at line 176 of file tls.c.

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

Definition at line 179 of file tls.c.

◆ EINFO_EPERM_RENEG_VERIFY

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

Definition at line 180 of file tls.c.

◆ EPERM_KEY_EXCHANGE

#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )

Definition at line 183 of file tls.c.

◆ EINFO_EPERM_KEY_EXCHANGE

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

Definition at line 184 of file tls.c.

◆ EPERM_EMS

#define EPERM_EMS   __einfo_error ( EINFO_EPERM_EMS )

Definition at line 187 of file tls.c.

◆ EINFO_EPERM_EMS

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

Definition at line 188 of file tls.c.

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

Definition at line 191 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:181
#define EINFO_EPROTO
Definition: errno.h:626

Definition at line 192 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:567
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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 623 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 859 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 1005 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 1077 of file tls.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

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

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

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

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

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

3054  {
3055  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.active;
3056  struct tls_cipher_suite *suite = cipherspec->suite;
3057  struct cipher_algorithm *cipher = suite->cipher;
3058  struct digest_algorithm *digest = suite->digest;
3059  struct {
3060  uint8_t fixed[suite->fixed_iv_len];
3061  uint8_t rec[suite->record_iv_len];
3062  } __attribute__ (( packed )) iv;
3063  struct tls_auth_header authhdr;
3064  struct tls_header *tlshdr;
3065  uint8_t mac[digest->digestsize];
3066  const void *plaintext;
3067  const void *encrypt;
3068  void *ciphertext;
3069  size_t record_len;
3070  size_t encrypt_len;
3071  size_t pad_len;
3072  size_t len;
3073  int rc;
3074 
3075  /* Record plaintext pointer and length */
3076  plaintext = iobuf->data;
3077  len = iob_len ( iobuf );
3078 
3079  /* Add to handshake digest if applicable */
3080  if ( type == TLS_TYPE_HANDSHAKE )
3081  tls_add_handshake ( tls, plaintext, len );
3082 
3083  /* Start constructing ciphertext at start of reserved space */
3084  iob_push ( iobuf, tls_iob_reserved ( tls, len ) );
3085  iob_unput ( iobuf, iob_len ( iobuf ) );
3086 
3087  /* Construct records */
3088  do {
3089  /* Limit length of this record (may be zero) */
3090  record_len = len;
3091  if ( record_len > TLS_TX_BUFSIZE )
3092  record_len = TLS_TX_BUFSIZE;
3093 
3094  /* Construct and set initialisation vector */
3095  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
3096  if ( ( rc = tls_generate_random ( tls, iv.rec,
3097  sizeof ( iv.rec ) ) ) != 0 ) {
3098  goto err_random;
3099  }
3100  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv,
3101  sizeof ( iv ) );
3102 
3103  /* Construct and process authentication data */
3104  authhdr.seq = cpu_to_be64 ( tls->tx.seq );
3105  authhdr.header.type = type;
3106  authhdr.header.version = htons ( tls->version );
3107  authhdr.header.length = htons ( record_len );
3108  if ( suite->mac_len ) {
3109  tls_hmac ( cipherspec, &authhdr, plaintext, record_len,
3110  mac );
3111  }
3112  if ( is_auth_cipher ( cipher ) ) {
3113  cipher_encrypt ( cipher, cipherspec->cipher_ctx,
3114  &authhdr, NULL, sizeof ( authhdr ) );
3115  }
3116 
3117  /* Calculate encryption length */
3118  encrypt_len = ( record_len + suite->mac_len );
3119  if ( is_block_cipher ( cipher ) ) {
3120  pad_len = ( ( ( cipher->blocksize - 1 ) &
3121  -( encrypt_len + 1 ) ) + 1 );
3122  } else {
3123  pad_len = 0;
3124  }
3125  encrypt_len += pad_len;
3126 
3127  /* Add record header */
3128  tlshdr = iob_put ( iobuf, sizeof ( *tlshdr ) );
3129  tlshdr->type = type;
3130  tlshdr->version = htons ( tls->version );
3131  tlshdr->length = htons ( sizeof ( iv.rec ) + encrypt_len +
3132  cipher->authsize );
3133 
3134  /* Add record initialisation vector, if applicable */
3135  memcpy ( iob_put ( iobuf, sizeof ( iv.rec ) ), iv.rec,
3136  sizeof ( iv.rec ) );
3137 
3138  /* Copy plaintext data if necessary */
3139  ciphertext = iob_put ( iobuf, record_len );
3140  assert ( ciphertext <= plaintext );
3141  if ( encrypt_len > record_len ) {
3142  memmove ( ciphertext, plaintext, record_len );
3143  encrypt = ciphertext;
3144  } else {
3145  encrypt = plaintext;
3146  }
3147 
3148  /* Add MAC, if applicable */
3149  memcpy ( iob_put ( iobuf, suite->mac_len ), mac,
3150  suite->mac_len );
3151 
3152  /* Add padding, if applicable */
3153  memset ( iob_put ( iobuf, pad_len ), ( pad_len - 1 ), pad_len );
3154 
3155  /* Encrypt data and append authentication tag */
3156  DBGC2 ( tls, "Sending plaintext data:\n" );
3157  DBGC2_HDA ( tls, 0, encrypt, encrypt_len );
3158  cipher_encrypt ( cipher, cipherspec->cipher_ctx, encrypt,
3159  ciphertext, encrypt_len );
3160  cipher_auth ( cipher, cipherspec->cipher_ctx,
3161  iob_put ( iobuf, cipher->authsize ) );
3162 
3163  /* Move to next record */
3164  tls->tx.seq += 1;
3165  plaintext += record_len;
3166  len -= record_len;
3167 
3168  } while ( len );
3169 
3170  /* Send ciphertext */
3171  if ( ( rc = xfer_deliver_iob ( &tls->cipherstream,
3172  iob_disown ( iobuf ) ) ) != 0 ) {
3173  DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
3174  tls, strerror ( rc ) );
3175  goto err_deliver;
3176  }
3177 
3178  assert ( iobuf == NULL );
3179  return 0;
3180 
3181  err_deliver:
3182  err_random:
3183  free_iob ( iobuf );
3184  return rc;
3185 }
#define __attribute__(x)
Definition: compiler.h:10
size_t blocksize
Block size.
Definition: crypto.h:61
static int is_auth_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:282
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:125
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:256
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:218
#define iob_push(iobuf, len)
Definition: iobuf.h:89
uint8_t type
Content type.
Definition: tls.h:34
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:819
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:41
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition: eltorito.h:13
TLS authentication header.
Definition: tls.h:155
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:258
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:251
size_t authsize
Authentication tag size.
Definition: crypto.h:75
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
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:264
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:2999
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:208
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:216
A TLS cipher suite.
Definition: tls.h:200
#define TLS_TX_BUFSIZE
TX maximum fragment length.
Definition: tls.h:492
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:374
#define DBGC2_HDA(...)
Definition: compiler.h:523
#define iob_unput(iobuf, len)
Definition: iobuf.h:140
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
uint64_t seq
Sequence number.
Definition: tls.h:376
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:456
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition: crypto.h:241
uint8_t mac_len
MAC length.
Definition: tls.h:220
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:29
struct tls_tx tx
Transmit state.
Definition: tls.h:474
long pad_len
Definition: bigint.h:31
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:63
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:2958
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:27
void * data
Start of data.
Definition: iobuf.h:53
uint16_t version
Protocol version.
Definition: tls.h:39
A message digest algorithm.
Definition: crypto.h:19
uint16_t version
Protocol version.
Definition: tls.h:459
#define cpu_to_be64(value)
Definition: byteswap.h:112
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:274
A cipher algorithm.
Definition: crypto.h:51
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition: crypto.h:267
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:206
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:460
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define htons(value)
Definition: byteswap.h:136
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:268
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:277
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 3196 of file tls.c.

3197  {
3198  struct io_buffer *iobuf;
3199  int rc;
3200 
3201  /* Allocate I/O buffer */
3202  iobuf = tls_alloc_iob ( tls, len );
3203  if ( ! iobuf )
3204  return -ENOMEM_TX_PLAINTEXT;
3205  memcpy ( iob_put ( iobuf, len ), data, len );
3206 
3207  /* Transmit I/O buffer */
3208  if ( ( rc = tls_send_record ( tls, type, iob_disown ( iobuf ) ) ) != 0 )
3209  return rc;
3210 
3211  return 0;
3212 }
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:3053
#define iob_put(iobuf, len)
Definition: iobuf.h:125
uint32_t type
Operating system type.
Definition: ena.h:12
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
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:131
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:3026
A persistent I/O buffer.
Definition: iobuf.h:38

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

835  {
836  struct digest_algorithm *digest = tls->handshake_digest;
837  uint8_t ctx[ digest->ctxsize ];
838 
839  memcpy ( ctx, tls->handshake_ctx, sizeof ( ctx ) );
840  digest_final ( digest, ctx, out );
841 }
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:230
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:465
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:463
size_t ctxsize
Context size.
Definition: crypto.h:23
A message digest algorithm.
Definition: crypto.h:19

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

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

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

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

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

260  {
261  return ( ( ! is_pending ( &tls->client.negotiation ) ) &&
262  ( ! is_pending ( &tls->server.negotiation ) ) );
263 }
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:410
struct tls_server server
Server state.
Definition: tls.h:480
struct tls_client client
Client state.
Definition: tls.h:478
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:25
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:432

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

277  {
278  return ( ( TLS_VERSION_MIN >= version ) ||
279  ( tls->version >= version ) );
280 }
u32 version
Driver version.
Definition: ath9k_hw.c:1985
uint16_t version
Protocol version.
Definition: tls.h:459
#define TLS_VERSION_MIN
Minimum TLS version.
Definition: crypto.h:14

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

294  {
295  struct md5_sha1_context *context = ctx;
296 
297  digest_init ( &md5_algorithm, context->md5 );
298  digest_init ( &sha1_algorithm, context->sha1 );
299 }
An MD5+SHA1 context.
Definition: tls.h:319
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:219
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:323
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:321
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:287
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258

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

308  {
309  struct md5_sha1_context *context = ctx;
310 
311  digest_update ( &md5_algorithm, context->md5, data, len );
312  digest_update ( &sha1_algorithm, context->sha1, data, len );
313 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:224
An MD5+SHA1 context.
Definition: tls.h:319
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:323
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:321
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:287
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258

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

321  {
322  struct md5_sha1_context *context = ctx;
323  struct md5_sha1_digest *digest = out;
324 
325  digest_final ( &md5_algorithm, context->md5, digest->md5 );
326  digest_final ( &sha1_algorithm, context->sha1, digest->sha1 );
327 }
An MD5+SHA1 context.
Definition: tls.h:319
uint8_t sha1[SHA1_DIGEST_SIZE]
SHA-1 digest.
Definition: tls.h:334
uint8_t md5[MD5_DIGEST_SIZE]
MD5 digest.
Definition: tls.h:332
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:230
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:330
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:323
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:321
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:287
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258

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

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

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

383  {
384  struct tls_connection *tls =
386  struct tls_session *session = tls->session;
387  struct io_buffer *iobuf;
388  struct io_buffer *tmp;
389 
390  /* Free dynamically-allocated resources */
391  free ( tls->new_session_ticket );
392  tls_clear_cipher ( tls, &tls->tx.cipherspec.active );
393  tls_clear_cipher ( tls, &tls->tx.cipherspec.pending );
394  tls_clear_cipher ( tls, &tls->rx.cipherspec.active );
395  tls_clear_cipher ( tls, &tls->rx.cipherspec.pending );
396  free ( tls->server.exchange );
397  free ( tls->handshake_ctx );
398  list_for_each_entry_safe ( iobuf, tmp, &tls->rx.data, list ) {
399  list_del ( &iobuf->list );
400  free_iob ( iobuf );
401  }
402  free_iob ( tls->rx.handshake );
403  privkey_put ( tls->client.key );
404  x509_chain_put ( tls->client.chain );
405  x509_chain_put ( tls->server.chain );
406  x509_root_put ( tls->server.root );
407 
408  /* Drop reference to session */
409  assert ( list_empty ( &tls->list ) );
410  ref_put ( &session->refcnt );
411 
412  /* Free TLS structure itself */
413  free ( tls );
414 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:300
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition: privkey.h:42
struct tls_session * session
Session.
Definition: tls.h:441
struct list_head data
List of received data buffers.
Definition: tls.h:396
struct io_buffer * handshake
Received handshake fragment.
Definition: tls.h:398
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:386
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:418
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition: x509.h:404
A reference counter.
Definition: refcnt.h:27
struct private_key * key
Private key (if used)
Definition: tls.h:406
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
unsigned long tmp
Definition: linux_pci.h:65
struct tls_server server
Server state.
Definition: tls.h:480
struct refcnt refcnt
Reference counter.
Definition: tls.h:343
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:465
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
void * new_session_ticket
New session ticket.
Definition: tls.h:449
struct tls_client client
Client state.
Definition: tls.h:478
struct list_head list
List of connections within the same session.
Definition: tls.h:443
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:374
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:459
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
struct x509_chain * chain
Certificate chain.
Definition: tls.h:424
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:276
struct tls_rx rx
Receive state.
Definition: tls.h:476
struct tls_tx tx
Transmit state.
Definition: tls.h:474
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
A TLS session.
Definition: tls.h:341
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:408
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:274
A TLS connection.
Definition: tls.h:436
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
A persistent I/O buffer.
Definition: iobuf.h:38
struct x509_root * root
Root of trust.
Definition: tls.h:422

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

422  {
423 
424  /* Remove pending operations, if applicable */
425  pending_put ( &tls->client.negotiation );
426  pending_put ( &tls->server.negotiation );
427  pending_put ( &tls->server.validation );
428 
429  /* Remove process */
430  process_del ( &tls->tx.process );
431 
432  /* Close all interfaces */
433  intf_shutdown ( &tls->cipherstream, rc );
434  intf_shutdown ( &tls->plainstream, rc );
435  intf_shutdown ( &tls->server.validator, rc );
436 
437  /* Remove from session */
438  list_del ( &tls->list );
439  INIT_LIST_HEAD ( &tls->list );
440 
441  /* Resume all other connections, in case we were the lead connection */
442  tls_tx_resume_all ( tls->session );
443 }
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:1119
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
struct process process
Transmit process.
Definition: tls.h:380
struct tls_session * session
Session.
Definition: tls.h:441
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:410
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:59
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:80
struct tls_server server
Server state.
Definition: tls.h:480
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
struct tls_client client
Client state.
Definition: tls.h:478
struct list_head list
List of connections within the same session.
Definition: tls.h:443
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:456
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:432
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:430
struct tls_tx tx
Transmit state.
Definition: tls.h:474
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
struct interface validator
Certificate validator.
Definition: tls.h:428
struct interface plainstream
Plaintext stream.
Definition: tls.h:454

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

461  {
462  int rc;
463 
464  /* Generate random bits with no additional input and without
465  * prediction resistance
466  */
467  if ( ( rc = rbg_generate ( NULL, 0, 0, data, len ) ) != 0 ) {
468  DBGC ( tls, "TLS %p could not generate random data: %s\n",
469  tls, strerror ( rc ) );
470  return rc;
471  }
472 
473  return 0;
474 }
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:117
#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:79
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

484  {
485  void *data;
486  size_t len;
487 
488  while ( ( data = va_arg ( args, void * ) ) ) {
489  len = va_arg ( args, size_t );
490  hmac_update ( digest, ctx, data, len );
491  }
492 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define va_arg(ap, type)
Definition: stdarg.h:9
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:43
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 505 of file tls.c.

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

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

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

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

645  {
646  struct digest_algorithm *digest = tls->handshake_digest;
647  uint8_t digest_out[ digest->digestsize ];
648 
649  /* Generate handshake digest */
650  tls_verify_handshake ( tls, digest_out );
651 
652  /* Show inputs */
653  DBGC ( tls, "TLS %p pre-master secret:\n", tls );
654  DBGC_HD ( tls, pre_master_secret, pre_master_secret_len );
655  DBGC ( tls, "TLS %p client random bytes:\n", tls );
656  DBGC_HD ( tls, &tls->client.random, sizeof ( tls->client.random ) );
657  DBGC ( tls, "TLS %p server random bytes:\n", tls );
658  DBGC_HD ( tls, &tls->server.random, sizeof ( tls->server.random ) );
659  DBGC ( tls, "TLS %p session hash:\n", tls );
660  DBGC_HD ( tls, digest_out, sizeof ( digest_out ) );
661 
662  /* Generate master secret */
663  if ( tls->extended_master_secret ) {
664  tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
665  &tls->master_secret,
666  sizeof ( tls->master_secret ),
667  "extended master secret",
668  digest_out, sizeof ( digest_out ) );
669  } else {
670  tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
671  &tls->master_secret,
672  sizeof ( tls->master_secret ),
673  "master secret",
674  &tls->client.random,
675  sizeof ( tls->client.random ),
676  &tls->server.random,
677  sizeof ( tls->server.random ) );
678  }
679 
680  /* Show output */
681  DBGC ( tls, "TLS %p generated %smaster secret:\n", tls,
682  ( tls->extended_master_secret ? "extended ": "" ) );
683  DBGC_HD ( tls, &tls->master_secret, sizeof ( tls->master_secret ) );
684 }
uint8_t random[32]
Random bytes.
Definition: tls.h:416
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:835
#define DBGC(...)
Definition: compiler.h:505
struct tls_server server
Server state.
Definition: tls.h:480
struct tls_client client
Client state.
Definition: tls.h:478
int extended_master_secret
Extended master secret flag.
Definition: tls.h:469
uint8_t master_secret[48]
Master secret.
Definition: tls.h:461
#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:463
size_t digestsize
Digest size.
Definition: crypto.h:27
A message digest algorithm.
Definition: crypto.h:19
struct tls_client_random random
Random bytes.
Definition: tls.h:404
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:623

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

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

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

778  {
779 
780  /* Select null digest algorithm */
782 
783  /* Free any existing context */
784  free ( tls->handshake_ctx );
785  tls->handshake_ctx = NULL;
786 }
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:465
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
struct digest_algorithm digest_null
Definition: crypto_null.c:49
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:463
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

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

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

820  {
821  struct digest_algorithm *digest = tls->handshake_digest;
822 
823  digest_update ( digest, tls->handshake_ctx, data, len );
824  return 0;
825 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:224
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:465
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:463
A message digest algorithm.
Definition: crypto.h:19
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 868 of file tls.c.

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

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

886  {
887 
888  free ( cipherspec->dynamic );
889  memset ( cipherspec, 0, sizeof ( *cipherspec ) );
890  cipherspec->suite = &tls_cipher_suite_null;
891 }
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:851
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:262
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 901 of file tls.c.

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

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

941  {
942  struct tls_cipher_suite *suite;
943  struct digest_algorithm *digest;
944  int rc;
945 
946  /* Identify cipher suite */
947  suite = tls_find_cipher_suite ( cipher_suite );
948  if ( ! suite ) {
949  DBGC ( tls, "TLS %p does not support cipher %04x\n",
950  tls, ntohs ( cipher_suite ) );
951  return -ENOTSUP_CIPHER;
952  }
953 
954  /* Set handshake digest algorithm */
955  digest = ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ?
956  suite->handshake : &md5_sha1_algorithm );
957  if ( ( rc = tls_select_handshake ( tls, digest ) ) != 0 )
958  return rc;
959 
960  /* Set ciphers */
961  if ( ( rc = tls_set_cipher ( tls, &tls->tx.cipherspec.pending,
962  suite ) ) != 0 )
963  return rc;
964  if ( ( rc = tls_set_cipher ( tls, &tls->rx.cipherspec.pending,
965  suite ) ) != 0 )
966  return rc;
967 
968  DBGC ( tls, "TLS %p selected %s-%s-%s-%d-%s\n", tls,
969  suite->exchange->name, suite->pubkey->name,
970  suite->cipher->name, ( suite->key_len * 8 ),
971  suite->digest->name );
972 
973  return 0;
974 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:202
static struct tls_cipher_suite * tls_find_cipher_suite(unsigned int cipher_suite)
Identify cipher suite.
Definition: tls.c:868
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:386
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:48
#define ntohs(value)
Definition: byteswap.h:137
const char * name
Algorithm name.
Definition: tls.h:189
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:204
#define ENOTSUP_CIPHER
Definition: tls.c:147
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:208
A TLS cipher suite.
Definition: tls.h:200
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:374
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:330
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:276
struct tls_rx rx
Receive state.
Definition: tls.h:476
struct tls_tx tx
Transmit state.
Definition: tls.h:474
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:277
const char * name
Algorithm name.
Definition: crypto.h:21
struct digest_algorithm * handshake
Handshake digest algorithm (for TLSv1.2 and above)
Definition: tls.h:210
A message digest algorithm.
Definition: crypto.h:19
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:206
const char * name
Algorithm name.
Definition: crypto.h:53
static int tls_set_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
Set cipher suite.
Definition: tls.c:901
static int tls_select_handshake(struct tls_connection *tls, struct digest_algorithm *digest)
Select handshake digest algorithm.
Definition: tls.c:795
const char * name
Algorithm name.
Definition: crypto.h:124
uint8_t key_len
Key length.
Definition: tls.h:214

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

984  {
985 
986  /* Sanity check */
987  if ( pair->pending.suite == &tls_cipher_suite_null ) {
988  DBGC ( tls, "TLS %p refusing to use null cipher\n", tls );
989  return -ENOTSUP_NULL;
990  }
991 
992  tls_clear_cipher ( tls, &pair->active );
993  memswap ( &pair->active, &pair->pending, sizeof ( pair->active ) );
994  return 0;
995 }
void * memswap(void *first, void *second, size_t len)
Swap memory regions.
Definition: string.c:154
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:851
#define DBGC(...)
Definition: compiler.h:505
#define ENOTSUP_NULL
Definition: tls.c:151
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:276
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:274
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 1016 of file tls.c.

1017  {
1018  struct tls_signature_hash_algorithm *sig_hash;
1019 
1020  /* Identify signature and hash algorithm */
1022  if ( ( sig_hash->pubkey == pubkey ) &&
1023  ( sig_hash->digest == digest ) ) {
1024  return sig_hash;
1025  }
1026  }
1027 
1028  return NULL;
1029 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:290
A TLS signature algorithm.
Definition: tls.h:288
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:386
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:302
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:292
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

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

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

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

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

1086  {
1087  struct tls_named_curve *curve;
1088 
1089  /* Identify named curve */
1091  if ( curve->code == named_curve )
1092  return curve;
1093  }
1094 
1095  return NULL;
1096 }
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:250
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:240
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:386
A TLS named curve.
Definition: tls.h:238
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

1110  {
1111  process_add ( &tls->tx.process );
1112 }
struct process process
Transmit process.
Definition: tls.h:380
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
struct tls_tx tx
Transmit state.
Definition: tls.h:474

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

1131  {
1132 
1133  /* Sanity check */
1134  assert ( ! tls->tx.pending );
1135  assert ( ! is_pending ( &tls->client.negotiation ) );
1136  assert ( ! is_pending ( &tls->server.negotiation ) );
1137  assert ( ! is_pending ( &tls->server.validation ) );
1138 
1139  /* (Re)start negotiation */
1141  tls_tx_resume ( tls );
1142  pending_get ( &tls->client.negotiation );
1143  pending_get ( &tls->server.negotiation );
1144 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1110
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:410
struct tls_server server
Server state.
Definition: tls.h:480
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:478
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:25
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:432
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:430
unsigned int pending
Pending transmissions.
Definition: tls.h:378
struct tls_tx tx
Transmit state.
Definition: tls.h:474
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:46

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

1155  {
1156 
1157  /* Send record */
1158  return tls_send_plaintext ( tls, TLS_TYPE_HANDSHAKE, data, len );
1159 }
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:3196
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:63
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 1168 of file tls.c.

1171  {
1172  struct tls_session *session = tls->session;
1173  size_t name_len = strlen ( session->name );
1174  struct {
1175  uint16_t type;
1176  uint16_t len;
1177  struct {
1178  uint16_t len;
1179  struct {
1180  uint8_t type;
1181  uint16_t len;
1182  uint8_t name[name_len];
1183  } __attribute__ (( packed )) list[1];
1184  } __attribute__ (( packed )) data;
1185  } __attribute__ (( packed )) *server_name_ext;
1186  struct {
1187  uint16_t type;
1188  uint16_t len;
1189  struct {
1190  uint8_t max;
1191  } __attribute__ (( packed )) data;
1192  } __attribute__ (( packed )) *max_fragment_length_ext;
1193  struct {
1194  uint16_t type;
1195  uint16_t len;
1196  struct {
1197  uint16_t len;
1198  struct tls_signature_hash_id
1200  } __attribute__ (( packed )) data;
1201  } __attribute__ (( packed )) *signature_algorithms_ext;
1202  struct {
1203  uint16_t type;
1204  uint16_t len;
1205  struct {
1206  uint8_t len;
1208  sizeof ( tls->verify.client ) :0 ];
1209  } __attribute__ (( packed )) data;
1210  } __attribute__ (( packed )) *renegotiation_info_ext;
1211  struct {
1212  uint16_t type;
1213  uint16_t len;
1214  struct {
1215  uint8_t data[session->ticket_len];
1216  } __attribute__ (( packed )) data;
1217  } __attribute__ (( packed )) *session_ticket_ext;
1218  struct {
1219  uint16_t type;
1220  uint16_t len;
1221  struct {
1222  uint16_t len;
1224  } __attribute__ (( packed )) data;
1225  } __attribute__ (( packed )) *named_curve_ext;
1226  struct {
1227  uint16_t type;
1228  uint16_t len;
1229  } __attribute__ (( packed )) *extended_master_secret_ext;
1230  struct {
1231  typeof ( *server_name_ext ) server_name;
1232  typeof ( *max_fragment_length_ext ) max_fragment_length;
1233  typeof ( *signature_algorithms_ext ) signature_algorithms;
1234  typeof ( *renegotiation_info_ext ) renegotiation_info;
1235  typeof ( *session_ticket_ext ) session_ticket;
1236  typeof ( *extended_master_secret_ext ) extended_master_secret;
1237  typeof ( *named_curve_ext )
1238  named_curve[TLS_NUM_NAMED_CURVES ? 1 : 0];
1239  } __attribute__ (( packed )) *extensions;
1240  struct {
1241  uint32_t type_length;
1242  uint16_t version;
1243  uint8_t random[32];
1244  uint8_t session_id_len;
1245  uint8_t session_id[tls->session_id_len];
1246  uint16_t cipher_suite_len;
1247  uint16_t cipher_suites[TLS_NUM_CIPHER_SUITES];
1248  uint8_t compression_methods_len;
1249  uint8_t compression_methods[1];
1250  uint16_t extensions_len;
1251  typeof ( *extensions ) extensions;
1252  } __attribute__ (( packed )) hello;
1253  struct tls_cipher_suite *suite;
1254  struct tls_signature_hash_algorithm *sighash;
1255  struct tls_named_curve *curve;
1256  unsigned int i;
1257 
1258  /* Construct record */
1259  memset ( &hello, 0, sizeof ( hello ) );
1260  hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) |
1261  htonl ( sizeof ( hello ) -
1262  sizeof ( hello.type_length ) ) );
1263  hello.version = htons ( TLS_VERSION_MAX );
1264  memcpy ( &hello.random, &tls->client.random, sizeof ( hello.random ) );
1265  hello.session_id_len = tls->session_id_len;
1266  memcpy ( hello.session_id, tls->session_id,
1267  sizeof ( hello.session_id ) );
1268  hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) );
1269  i = 0 ; for_each_table_entry ( suite, TLS_CIPHER_SUITES )
1270  hello.cipher_suites[i++] = suite->code;
1271  hello.compression_methods_len = sizeof ( hello.compression_methods );
1272  hello.extensions_len = htons ( sizeof ( hello.extensions ) );
1273  extensions = &hello.extensions;
1274 
1275  /* Construct server name extension */
1276  server_name_ext = &extensions->server_name;
1277  server_name_ext->type = htons ( TLS_SERVER_NAME );
1278  server_name_ext->len = htons ( sizeof ( server_name_ext->data ) );
1279  server_name_ext->data.len
1280  = htons ( sizeof ( server_name_ext->data.list ) );
1281  server_name_ext->data.list[0].type = TLS_SERVER_NAME_HOST_NAME;
1282  server_name_ext->data.list[0].len
1283  = htons ( sizeof ( server_name_ext->data.list[0].name ) );
1284  memcpy ( server_name_ext->data.list[0].name, session->name,
1285  sizeof ( server_name_ext->data.list[0].name ) );
1286 
1287  /* Construct maximum fragment length extension */
1288  max_fragment_length_ext = &extensions->max_fragment_length;
1289  max_fragment_length_ext->type = htons ( TLS_MAX_FRAGMENT_LENGTH );
1290  max_fragment_length_ext->len
1291  = htons ( sizeof ( max_fragment_length_ext->data ) );
1292  max_fragment_length_ext->data.max = TLS_MAX_FRAGMENT_LENGTH_VALUE;
1293 
1294  /* Construct supported signature algorithms extension */
1295  signature_algorithms_ext = &extensions->signature_algorithms;
1296  signature_algorithms_ext->type = htons ( TLS_SIGNATURE_ALGORITHMS );
1297  signature_algorithms_ext->len
1298  = htons ( sizeof ( signature_algorithms_ext->data ) );
1299  signature_algorithms_ext->data.len
1300  = htons ( sizeof ( signature_algorithms_ext->data.code ) );
1301  i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
1302  signature_algorithms_ext->data.code[i++] = sighash->code;
1303 
1304  /* Construct renegotiation information extension */
1305  renegotiation_info_ext = &extensions->renegotiation_info;
1306  renegotiation_info_ext->type = htons ( TLS_RENEGOTIATION_INFO );
1307  renegotiation_info_ext->len
1308  = htons ( sizeof ( renegotiation_info_ext->data ) );
1309  renegotiation_info_ext->data.len
1310  = sizeof ( renegotiation_info_ext->data.data );
1311  memcpy ( renegotiation_info_ext->data.data, tls->verify.client,
1312  sizeof ( renegotiation_info_ext->data.data ) );
1313 
1314  /* Construct session ticket extension */
1315  session_ticket_ext = &extensions->session_ticket;
1316  session_ticket_ext->type = htons ( TLS_SESSION_TICKET );
1317  session_ticket_ext->len
1318  = htons ( sizeof ( session_ticket_ext->data ) );
1319  memcpy ( session_ticket_ext->data.data, session->ticket,
1320  sizeof ( session_ticket_ext->data.data ) );
1321 
1322  /* Construct extended master secret extension */
1323  extended_master_secret_ext = &extensions->extended_master_secret;
1324  extended_master_secret_ext->type
1326  extended_master_secret_ext->len = 0;
1327 
1328  /* Construct named curves extension, if applicable */
1329  if ( sizeof ( extensions->named_curve ) ) {
1330  named_curve_ext = &extensions->named_curve[0];
1331  named_curve_ext->type = htons ( TLS_NAMED_CURVE );
1332  named_curve_ext->len
1333  = htons ( sizeof ( named_curve_ext->data ) );
1334  named_curve_ext->data.len
1335  = htons ( sizeof ( named_curve_ext->data.code ) );
1337  named_curve_ext->data.code[i++] = curve->code;
1338  }
1339 
1340  return action ( tls, &hello, sizeof ( hello ) );
1341 }
#define TLS_MAX_FRAGMENT_LENGTH_VALUE
Advertised maximum fragment length.
Definition: tls.h:484
struct tls_verify_data verify
Verification data.
Definition: tls.h:471
#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:859
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:152
#define max(x, y)
Definition: ath.h:41
struct tls_session * session
Session.
Definition: tls.h:441
#define TLS_NUM_NAMED_CURVES
Number of supported named curves.
Definition: tls.c:1077
uint32_t type
Operating system type.
Definition: ena.h:12
#define TLS_CLIENT_HELLO
Definition: tls.h:70
uint8_t session_id[32]
Session ID.
Definition: tls.h:445
static unsigned int code
Response code.
Definition: hyperv.h:26
#define htonl(value)
Definition: byteswap.h:134
#define TLS_MAX_FRAGMENT_LENGTH
Definition: tls.h:130
#define TLS_NAMED_CURVE
Definition: tls.h:137
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Driver version.
Definition: ath9k_hw.c:1985
struct tls_client client
Client state.
Definition: tls.h:478
#define TLS_SESSION_TICKET
Definition: tls.h:149
ring len
Length.
Definition: dwmac.h:231
A TLS cipher suite.
Definition: tls.h:200
#define TLS_SERVER_NAME
Definition: tls.h:126
A TLS signature algorithm.
Definition: tls.h:288
size_t ticket_len
Length of session ticket.
Definition: tls.h:361
struct list_head list
List of sessions.
Definition: tls.h:345
#define cpu_to_le32(value)
Definition: byteswap.h:108
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:250
#define TLS_NUM_SIG_HASH_ALGORITHMS
Number of supported signature and hash algorithms.
Definition: tls.c:1005
void * ticket
Session ticket.
Definition: tls.h:359
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:240
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:386
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:32
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:302
uint16_t hello
Hello time.
Definition: stp.h:39
unsigned int uint32_t
Definition: stdint.h:12
#define TLS_EXTENDED_MASTER_SECRET
Definition: tls.h:146
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:294
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:51
#define TLS_SERVER_NAME_HOST_NAME
Definition: tls.h:127
uint8_t client[12]
Client verification data.
Definition: tls.h:165
A TLS session.
Definition: tls.h:341
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct tls_client_random random
Random bytes.
Definition: tls.h:404
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:467
A TLS named curve.
Definition: tls.h:238
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
const char * name
Server name.
Definition: tls.h:348
A TLS signature and hash algorithm identifier.
Definition: tls.h:280
size_t session_id_len
Length of session ID.
Definition: tls.h:447
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:224
#define htons(value)
Definition: byteswap.h:136
#define TLS_SIGNATURE_ALGORITHMS
Definition: tls.h:143
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:212
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 1349 of file tls.c.

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

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

1360  {
1361  struct {
1362  tls24_t length;
1363  uint8_t data[0];
1364  } __attribute__ (( packed )) *certificate;
1365  struct {
1366  uint32_t type_length;
1367  tls24_t length;
1368  typeof ( *certificate ) certificates[0];
1369  } __attribute__ (( packed )) *certificates;
1370  struct x509_link *link;
1371  struct x509_certificate *cert;
1372  struct io_buffer *iobuf;
1373  size_t len;
1374 
1375  /* Calculate length of client certificates */
1376  len = 0;
1378  cert = link->cert;
1379  len += ( sizeof ( *certificate ) + cert->raw.len );
1380  DBGC ( tls, "TLS %p sending client certificate %s\n",
1381  tls, x509_name ( cert ) );
1382  }
1383 
1384  /* Allocate storage for Certificate record (which may be too
1385  * large for the stack).
1386  */
1387  iobuf = tls_alloc_iob ( tls, ( sizeof ( *certificates ) + len ) );
1388  if ( ! iobuf )
1389  return -ENOMEM_CERTIFICATE;
1390 
1391  /* Populate record */
1392  certificates = iob_put ( iobuf, sizeof ( *certificates ) );
1393  certificates->type_length =
1395  htonl ( sizeof ( *certificates ) + len -
1396  sizeof ( certificates->type_length ) ) );
1397  tls_set_uint24 ( &certificates->length, len );
1399  cert = link->cert;
1400  certificate = iob_put ( iobuf, sizeof ( *certificate ) );
1401  tls_set_uint24 ( &certificate->length, cert->raw.len );
1402  memcpy ( iob_put ( iobuf, cert->raw.len ), cert->raw.data,
1403  cert->raw.len );
1404  }
1405 
1406  /* Transmit record */
1407  return tls_send_record ( tls, TLS_TYPE_HANDSHAKE,
1408  iob_disown ( iobuf ) );
1409 }
#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:3053
#define iob_put(iobuf, len)
Definition: iobuf.h:125
struct list_head links
List of links.
Definition: x509.h:205
const void * data
Start of data.
Definition: asn1.h:23
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:73
#define htonl(value)
Definition: byteswap.h:134
size_t len
Length of data.
Definition: asn1.h:25
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct tls_client client
Client state.
Definition: tls.h:478
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
ring len
Length.
Definition: dwmac.h:231
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:25
#define cpu_to_le32(value)
Definition: byteswap.h:108
An X.509 certificate.
Definition: x509.h:216
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:63
A TLS 24-bit integer.
Definition: tls.c:222
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:147
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
#define ENOMEM_CERTIFICATE
Definition: tls.c:123
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:408
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:248
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
struct asn1_cursor raw
Raw certificate.
Definition: x509.h:231
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:3026
A persistent I/O buffer.
Definition: iobuf.h:38

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

1417  {
1418  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1419  struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1420  struct {
1421  uint16_t version;
1422  uint8_t random[46];
1423  } __attribute__ (( packed )) pre_master_secret;
1424  struct asn1_cursor cursor = {
1425  .data = &pre_master_secret,
1426  .len = sizeof ( pre_master_secret ),
1427  };
1428  struct asn1_builder builder = { NULL, 0 };
1429  int rc;
1430 
1431  /* Generate pre-master secret */
1432  pre_master_secret.version = htons ( TLS_VERSION_MAX );
1433  if ( ( rc = tls_generate_random ( tls, &pre_master_secret.random,
1434  ( sizeof ( pre_master_secret.random ) ) ) ) != 0 ) {
1435  goto err_random;
1436  }
1437 
1438  /* Encrypt pre-master secret using server's public key */
1439  if ( ( rc = pubkey_encrypt ( pubkey, &tls->server.key, &cursor,
1440  &builder ) ) != 0 ) {
1441  DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
1442  tls, strerror ( rc ) );
1443  goto err_encrypt;
1444  }
1445 
1446  /* Construct Client Key Exchange record */
1447  {
1448  struct {
1449  uint32_t type_length;
1450  uint16_t encrypted_pre_master_secret_len;
1451  } __attribute__ (( packed )) header;
1452 
1453  header.type_length =
1455  htonl ( builder.len + sizeof ( header ) -
1456  sizeof ( header.type_length ) ) );
1457  header.encrypted_pre_master_secret_len = htons ( builder.len );
1458 
1459  if ( ( rc = asn1_prepend_raw ( &builder, &header,
1460  sizeof ( header ) ) ) != 0 ) {
1461  DBGC ( tls, "TLS %p could not construct Client Key "
1462  "Exchange: %s\n", tls, strerror ( rc ) );
1463  goto err_prepend;
1464  }
1465  }
1466 
1467  /* Transmit Client Key Exchange record */
1468  if ( ( rc = tls_send_handshake ( tls, builder.data,
1469  builder.len ) ) != 0 ) {
1470  goto err_send;
1471  }
1472 
1473  /* Generate master secret */
1474  tls_generate_master_secret ( tls, &pre_master_secret,
1475  sizeof ( pre_master_secret ) );
1476 
1477  err_random:
1478  err_encrypt:
1479  err_prepend:
1480  err_send:
1481  free ( builder.data );
1482  return rc;
1483 }
#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:426
void * data
Data.
Definition: asn1.h:36
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:643
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition: asn1.c:949
const void * data
Start of data.
Definition: asn1.h:23
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:258
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:204
#define htonl(value)
Definition: byteswap.h:134
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1154
struct tls_server server
Server state.
Definition: tls.h:480
u32 version
Driver version.
Definition: ath9k_hw.c:1985
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:374
#define cpu_to_le32(value)
Definition: byteswap.h:108
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
An ASN.1 object builder.
Definition: asn1.h:29
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:32
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:276
unsigned int uint32_t
Definition: stdint.h:12
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:51
struct tls_tx tx
Transmit state.
Definition: tls.h:474
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:287
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:460
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
size_t len
Length of data.
Definition: asn1.h:38
An ASN.1 object cursor.
Definition: asn1.h:21
A public key algorithm.
Definition: crypto.h:122
#define htons(value)
Definition: byteswap.h:136
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:78

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

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

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

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

References __attribute__, tls_connection::client, cpu_to_le32, data, asn1_cursor::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 1712 of file tls.c.

1712  {
1713  struct tls_named_curve *curve;
1714  const struct {
1715  uint8_t curve_type;
1716  uint16_t named_curve;
1717  uint8_t public_len;
1718  uint8_t public[0];
1719  } __attribute__ (( packed )) *ecdh;
1720  size_t param_len;
1721  size_t pointsize;
1722  size_t keysize;
1723  size_t offset;
1724  int rc;
1725 
1726  /* Parse ServerKeyExchange record */
1727  ecdh = tls->server.exchange;
1728  if ( ( sizeof ( *ecdh ) > tls->server.exchange_len ) ||
1729  ( ecdh->public_len > ( tls->server.exchange_len -
1730  sizeof ( *ecdh ) ) ) ) {
1731  DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1732  tls );
1733  DBGC_HDA ( tls, 0, tls->server.exchange,
1734  tls->server.exchange_len );
1735  return -EINVAL_KEY_EXCHANGE;
1736  }
1737  param_len = ( sizeof ( *ecdh ) + ecdh->public_len );
1738 
1739  /* Verify parameter signature */
1740  if ( ( rc = tls_verify_dh_params ( tls, param_len ) ) != 0 )
1741  return rc;
1742 
1743  /* Identify named curve */
1744  if ( ecdh->curve_type != TLS_NAMED_CURVE_TYPE ) {
1745  DBGC ( tls, "TLS %p unsupported curve type %d\n",
1746  tls, ecdh->curve_type );
1747  DBGC_HDA ( tls, 0, tls->server.exchange,
1748  tls->server.exchange_len );
1749  return -ENOTSUP_CURVE;
1750  }
1751  curve = tls_find_named_curve ( ecdh->named_curve );
1752  if ( ! curve ) {
1753  DBGC ( tls, "TLS %p unsupported named curve %d\n",
1754  tls, ntohs ( ecdh->named_curve ) );
1755  DBGC_HDA ( tls, 0, tls->server.exchange,
1756  tls->server.exchange_len );
1757  return -ENOTSUP_CURVE;
1758  }
1759  DBGC ( tls, "TLS %p using named curve %s\n", tls, curve->curve->name );
1760  pointsize = curve->curve->pointsize;
1761  keysize = curve->curve->keysize;
1762  offset = ( curve->format ? 1 : 0 );
1763 
1764  /* Check key length */
1765  if ( ecdh->public_len != ( offset + pointsize ) ) {
1766  DBGC ( tls, "TLS %p invalid %s key\n",
1767  tls, curve->curve->name );
1768  DBGC_HDA ( tls, 0, tls->server.exchange,
1769  tls->server.exchange_len );
1770  return -EINVAL_KEY_EXCHANGE;
1771  }
1772 
1773  /* Check curve point format byte (if present) */
1774  if ( curve->format && ( ecdh->public[0] != curve->format ) ) {
1775  DBGC ( tls, "TLS %p invalid %s curve point format\n",
1776  tls, curve->curve->name );
1777  DBGC_HDA ( tls, 0, tls->server.exchange,
1778  tls->server.exchange_len );
1779  return -EINVAL_KEY_EXCHANGE;
1780  }
1781 
1782  /* Construct pre-master secret and ClientKeyExchange record */
1783  {
1784  uint8_t private[keysize];
1785  uint8_t pre_master_secret[pointsize];
1786  struct {
1787  uint32_t type_length;
1788  uint8_t public_len;
1789  uint8_t public[ecdh->public_len];
1790  } __attribute__ (( packed )) key_xchg;
1791 
1792  /* Generate ephemeral private key */
1793  if ( ( rc = tls_generate_random ( tls, private,
1794  sizeof ( private ) ) ) != 0){
1795  return rc;
1796  }
1797 
1798  /* Exchange keys */
1799  if ( ( rc = ecdhe_key ( curve->curve, ( ecdh->public + offset ),
1800  private, ( key_xchg.public + offset ),
1801  pre_master_secret ) ) != 0 ) {
1802  DBGC ( tls, "TLS %p could not exchange ECDHE key: %s\n",
1803  tls, strerror ( rc ) );
1804  return rc;
1805  }
1806 
1807  /* Generate Client Key Exchange record */
1808  key_xchg.type_length =
1810  htonl ( sizeof ( key_xchg ) -
1811  sizeof ( key_xchg.type_length ) ) );
1812  key_xchg.public_len = sizeof ( key_xchg.public );
1813  if ( curve->format )
1814  key_xchg.public[0] = curve->format;
1815 
1816  /* Transmit Client Key Exchange record */
1817  if ( ( rc = tls_send_handshake ( tls, &key_xchg,
1818  sizeof ( key_xchg ) ) ) !=0){
1819  return rc;
1820  }
1821 
1822  /* Generate master secret */
1823  tls_generate_master_secret ( tls, pre_master_secret,
1824  curve->pre_master_secret_len );
1825  }
1826 
1827  return 0;
1828 }
#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:1086
#define ENOTSUP_CURVE
Definition: tls.c:163
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:643
#define DBGC(...)
Definition: compiler.h:505
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:418
#define ntohs(value)
Definition: byteswap.h:137
#define htonl(value)
Definition: byteswap.h:134
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1154
struct tls_server server
Server state.
Definition: tls.h:480
#define TLS_NAMED_CURVE_TYPE
TLS named curved type.
Definition: tls.h:232
#define DBGC_HDA(...)
Definition: compiler.h:506
const char * name
Curve name.
Definition: crypto.h:180
#define cpu_to_le32(value)
Definition: byteswap.h:108
int ecdhe_key(struct elliptic_curve *curve, const void *partner, const void *private, void *public, void *shared)
Calculate ECDHE key.
Definition: ecdhe.c:47
uint8_t pre_master_secret_len
Pre-master secret length.
Definition: tls.h:246
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:184
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:240
static int tls_verify_dh_params(struct tls_connection *tls, size_t param_len)
Verify Diffie-Hellman parameter signature.
Definition: tls.c:1498
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:238
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:111
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:460
size_t pointsize
Point (and public key) size.
Definition: crypto.h:182
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:420
uint8_t format
Curve point format byte (if any)
Definition: tls.h:244
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:78

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

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

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

1870  {
1871  struct digest_algorithm *digest = tls->handshake_digest;
1872  struct x509_certificate *cert = x509_first ( tls->client.chain );
1873  struct pubkey_algorithm *pubkey = cert->signature_algorithm->pubkey;
1874  struct asn1_cursor *key = privkey_cursor ( tls->client.key );
1875  uint8_t digest_out[ digest->digestsize ];
1876  struct tls_signature_hash_algorithm *sig_hash = NULL;
1877  struct asn1_builder builder = { NULL, 0 };
1878  int rc;
1879 
1880  /* Generate digest to be signed */
1881  tls_verify_handshake ( tls, digest_out );
1882 
1883  /* TLSv1.2 and later use explicit algorithm identifiers */
1884  if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
1885  sig_hash = tls_signature_hash_algorithm ( pubkey, digest );
1886  if ( ! sig_hash ) {
1887  DBGC ( tls, "TLS %p could not identify (%s,%s) "
1888  "signature and hash algorithm\n", tls,
1889  pubkey->name, digest->name );
1890  rc = -ENOTSUP_SIG_HASH;
1891  goto err_sig_hash;
1892  }
1893  }
1894 
1895  /* Sign digest */
1896  if ( ( rc = pubkey_sign ( pubkey, key, digest, digest_out,
1897  &builder ) ) != 0 ) {
1898  DBGC ( tls, "TLS %p could not sign %s digest using %s client "
1899  "private key: %s\n", tls, digest->name, pubkey->name,
1900  strerror ( rc ) );
1901  goto err_pubkey_sign;
1902  }
1903 
1904  /* Construct Certificate Verify record */
1905  {
1906  int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
1907  struct {
1908  uint32_t type_length;
1909  struct tls_signature_hash_id sig_hash[use_sig_hash];
1910  uint16_t signature_len;
1911  } __attribute__ (( packed )) header;
1912 
1913  header.type_length = ( cpu_to_le32 ( TLS_CERTIFICATE_VERIFY ) |
1914  htonl ( builder.len +
1915  sizeof ( header ) -
1916  sizeof ( header.type_length )));
1917  if ( use_sig_hash ) {
1918  memcpy ( &header.sig_hash[0], &sig_hash->code,
1919  sizeof ( header.sig_hash[0] ) );
1920  }
1921  header.signature_len = htons ( builder.len );
1922 
1923  if ( ( rc = asn1_prepend_raw ( &builder, &header,
1924  sizeof ( header ) ) ) != 0 ) {
1925  DBGC ( tls, "TLS %p could not construct Certificate "
1926  "Verify: %s\n", tls, strerror ( rc ) );
1927  goto err_prepend;
1928  }
1929  }
1930 
1931  /* Transmit record */
1932  if ( ( rc = tls_send_handshake ( tls, builder.data,
1933  builder.len ) ) != 0 ) {
1934  goto err_send;
1935  }
1936 
1937  err_send:
1938  err_prepend:
1939  err_pubkey_sign:
1940  err_sig_hash:
1941  free ( builder.data );
1942  return rc;
1943 }
#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:36
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:835
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition: asn1.c:949
struct asn1_algorithm * signature_algorithm
Signature algorithm.
Definition: x509.h:239
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:48
#define htonl(value)
Definition: byteswap.h:134
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1154
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition: privkey.h:53
struct private_key * key
Private key (if used)
Definition: tls.h:406
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:414
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:301
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:1016
struct tls_client client
Client state.
Definition: tls.h:478
A TLS signature algorithm.
Definition: tls.h:288
#define cpu_to_le32(value)
Definition: byteswap.h:108
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
An X.509 certificate.
Definition: x509.h:216
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
An ASN.1 object builder.
Definition: asn1.h:29
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:294
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:277
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:463
size_t digestsize
Digest size.
Definition: crypto.h:27
const char * name
Algorithm name.
Definition: crypto.h:21
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:311
struct ena_llq_option header
Header locations.
Definition: ena.h:16
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:408
A message digest algorithm.
Definition: crypto.h:19
A TLS signature and hash algorithm identifier.
Definition: tls.h:280
#define TLS_CERTIFICATE_VERIFY
Definition: tls.h:77
#define ENOTSUP_SIG_HASH
Definition: tls.c:155
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
size_t len
Length of data.
Definition: asn1.h:38
An ASN.1 object cursor.
Definition: asn1.h:21
A public key algorithm.
Definition: crypto.h:122
#define htons(value)
Definition: byteswap.h:136
union @391 key
Sense key.
Definition: scsi.h:18
const char * name
Algorithm name.
Definition: crypto.h:124

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

1951  {
1952  static const struct {
1953  uint8_t spec;
1954  } __attribute__ (( packed )) change_cipher = {
1955  .spec = TLS_CHANGE_CIPHER_SPEC,
1956  };
1957 
1959  &change_cipher, sizeof ( change_cipher ) );
1960 }
#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:54
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:3196
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_CHANGE_CIPHER_SPEC
Change cipher spec magic byte.
Definition: tls.h:57

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

1968  {
1969  struct digest_algorithm *digest = tls->handshake_digest;
1970  struct {
1971  uint32_t type_length;
1972  uint8_t verify_data[ sizeof ( tls->verify.client ) ];
1973  } __attribute__ (( packed )) finished;
1974  uint8_t digest_out[ digest->digestsize ];
1975  int rc;
1976 
1977  /* Construct client verification data */
1978  tls_verify_handshake ( tls, digest_out );
1979  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
1980  tls->verify.client, sizeof ( tls->verify.client ),
1981  "client finished", digest_out, sizeof ( digest_out ) );
1982 
1983  /* Construct record */
1984  memset ( &finished, 0, sizeof ( finished ) );
1985  finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
1986  htonl ( sizeof ( finished ) -
1987  sizeof ( finished.type_length ) ) );
1988  memcpy ( finished.verify_data, tls->verify.client,
1989  sizeof ( finished.verify_data ) );
1990 
1991  /* Transmit record */
1992  if ( ( rc = tls_send_handshake ( tls, &finished,
1993  sizeof ( finished ) ) ) != 0 )
1994  return rc;
1995 
1996  /* Mark client as finished */
1997  pending_put ( &tls->client.negotiation );
1998 
1999  return 0;
2000 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:471
#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:410
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:835
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:59
#define htonl(value)
Definition: byteswap.h:134
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1154
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct tls_client client
Client state.
Definition: tls.h:478
uint8_t master_secret[48]
Master secret.
Definition: tls.h:461
#define cpu_to_le32(value)
Definition: byteswap.h:108
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:165
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:463
size_t digestsize
Digest size.
Definition: crypto.h:27
A message digest algorithm.
Definition: crypto.h:19
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:623
#define TLS_FINISHED
Definition: tls.h:79
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 2009 of file tls.c.

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

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

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

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

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

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

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

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

2320  {
2321  const struct {
2323  uint16_t len;
2324  uint8_t ticket[0];
2325  } __attribute__ (( packed )) *new_session_ticket = data;
2326  size_t ticket_len;
2327 
2328  /* Parse header */
2329  if ( sizeof ( *new_session_ticket ) > len ) {
2330  DBGC ( tls, "TLS %p received underlength New Session Ticket\n",
2331  tls );
2332  DBGC_HD ( tls, data, len );
2333  return -EINVAL_TICKET;
2334  }
2335  ticket_len = ntohs ( new_session_ticket->len );
2336  if ( ticket_len > ( len - sizeof ( *new_session_ticket ) ) ) {
2337  DBGC ( tls, "TLS %p received overlength New Session Ticket\n",
2338  tls );
2339  DBGC_HD ( tls, data, len );
2340  return -EINVAL_TICKET;
2341  }
2342 
2343  /* Free any unapplied new session ticket */
2344  free ( tls->new_session_ticket );
2345  tls->new_session_ticket = NULL;
2346  tls->new_session_ticket_len = 0;
2347 
2348  /* Record ticket */
2349  tls->new_session_ticket = malloc ( ticket_len );
2350  if ( ! tls->new_session_ticket )
2351  return -ENOMEM;
2352  memcpy ( tls->new_session_ticket, new_session_ticket->ticket,
2353  ticket_len );
2354  tls->new_session_ticket_len = ticket_len;
2355  DBGC ( tls, "TLS %p new session ticket:\n", tls );
2356  DBGC_HDA ( tls, 0, tls->new_session_ticket,
2357  tls->new_session_ticket_len );
2358 
2359  return 0;
2360 }
#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:451
#define ntohs(value)
Definition: byteswap.h:137
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * new_session_ticket
New session ticket.
Definition: tls.h:449
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
#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:621
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_TICKET
Definition: tls.c:107
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

2371  {
2372  size_t remaining = len;
2373  int rc;
2374 
2375  /* Free any existing certificate chain */
2376  memset ( &tls->server.key, 0, sizeof ( tls->server.key ) );
2377  x509_chain_put ( tls->server.chain );
2378  tls->server.chain = NULL;
2379 
2380  /* Create certificate chain */
2381  tls->server.chain = x509_alloc_chain();
2382  if ( ! tls->server.chain ) {
2383  rc = -ENOMEM_CHAIN;
2384  goto err_alloc_chain;
2385  }
2386 
2387  /* Add certificates to chain */
2388  while ( remaining ) {
2389  const struct {
2390  tls24_t length;
2391  uint8_t data[0];
2392  } __attribute__ (( packed )) *certificate = data;
2393  size_t certificate_len;
2394  size_t record_len;
2395  struct x509_certificate *cert;
2396 
2397  /* Parse header */
2398  if ( sizeof ( *certificate ) > remaining ) {
2399  DBGC ( tls, "TLS %p underlength certificate:\n", tls );
2400  DBGC_HDA ( tls, 0, data, remaining );
2402  goto err_underlength;
2403  }
2404  certificate_len = tls_uint24 ( &certificate->length );
2405  if ( certificate_len > ( remaining - sizeof ( *certificate ) )){
2406  DBGC ( tls, "TLS %p overlength certificate:\n", tls );
2407  DBGC_HDA ( tls, 0, data, remaining );
2409  goto err_overlength;
2410  }
2411  record_len = ( sizeof ( *certificate ) + certificate_len );
2412 
2413  /* Add certificate to chain */
2414  if ( ( rc = x509_append_raw ( tls->server.chain,
2415  certificate->data,
2416  certificate_len ) ) != 0 ) {
2417  DBGC ( tls, "TLS %p could not append certificate: %s\n",
2418  tls, strerror ( rc ) );
2419  DBGC_HDA ( tls, 0, data, remaining );
2420  goto err_parse;
2421  }
2422  cert = x509_last ( tls->server.chain );
2423  DBGC ( tls, "TLS %p found certificate %s\n",
2424  tls, x509_name ( cert ) );
2425 
2426  /* Move to next certificate in list */
2427  data += record_len;
2428  remaining -= record_len;
2429  }
2430 
2431  return 0;
2432 
2433  err_parse:
2434  err_overlength:
2435  err_underlength:
2436  memset ( &tls->server.key, 0, sizeof ( tls->server.key ) );
2437  x509_chain_put ( tls->server.chain );
2438  tls->server.chain = NULL;
2439  err_alloc_chain:
2440  return rc;
2441 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:300
#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:426
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:237
int x509_append_raw(struct x509_chain *chain, const void *data, size_t len)
Append X.509 certificate to X.509 certificate chain.
Definition: x509.c:1674
#define DBGC(...)
Definition: compiler.h:505
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1615
#define ENOMEM_CHAIN
Definition: tls.c:127
#define EINVAL_CERTIFICATE
Definition: tls.c:71
struct tls_server server
Server state.
Definition: tls.h:480
#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:325
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
An X.509 certificate.
Definition: x509.h:216
struct x509_chain * chain
Certificate chain.
Definition: tls.h:424
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:222
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:147
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
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 2451 of file tls.c.

2452  {
2453  const struct {
2454  tls24_t length;
2455  uint8_t certificates[0];
2456  } __attribute__ (( packed )) *certificate = data;
2457  size_t certificates_len;
2458  int rc;
2459 
2460  /* Parse header */
2461  if ( sizeof ( *certificate ) > len ) {
2462  DBGC ( tls, "TLS %p received underlength Server Certificate\n",
2463  tls );
2464  DBGC_HD ( tls, data, len );
2465  return -EINVAL_CERTIFICATES;
2466  }
2467  certificates_len = tls_uint24 ( &certificate->length );
2468  if ( certificates_len > ( len - sizeof ( *certificate ) ) ) {
2469  DBGC ( tls, "TLS %p received overlength Server Certificate\n",
2470  tls );
2471  DBGC_HD ( tls, data, len );
2472  return -EINVAL_CERTIFICATES;
2473  }
2474 
2475  /* Parse certificate chain */
2476  if ( ( rc = tls_parse_chain ( tls, certificate->certificates,
2477  certificates_len ) ) != 0 )
2478  return rc;
2479 
2480  return 0;
2481 }
#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:237
#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:222
static int tls_parse_chain(struct tls_connection *tls, const void *data, size_t len)
Parse certificate chain.
Definition: tls.c:2370
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_CERTIFICATES
Definition: tls.c:75

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

2492  {
2493 
2494  /* Free any existing server key exchange record */
2495  free ( tls->server.exchange );
2496  tls->server.exchange_len = 0;
2497 
2498  /* Allocate copy of server key exchange record */
2499  tls->server.exchange = malloc ( len );
2500  if ( ! tls->server.exchange )
2501  return -ENOMEM;
2502 
2503  /* Store copy of server key exchange record for later
2504  * processing. We cannot verify the signature at this point
2505  * since the certificate validation will not yet have
2506  * completed.
2507  */
2508  memcpy ( tls->server.exchange, data, len );
2509  tls->server.exchange_len = len;
2510 
2511  return 0;
2512 }
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:418
struct tls_server server
Server state.
Definition: tls.h:480
#define ENOMEM
Not enough space.
Definition: errno.h:535
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:55
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:420

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

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

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

2583  {
2584  const struct {
2585  char next[0];
2586  } __attribute__ (( packed )) *hello_done = data;
2587  int rc;
2588 
2589  /* Sanity check */
2590  if ( sizeof ( *hello_done ) != len ) {
2591  DBGC ( tls, "TLS %p received overlength Server Hello Done\n",
2592  tls );
2593  DBGC_HD ( tls, data, len );
2594  return -EINVAL_HELLO_DONE;
2595  }
2596 
2597  /* Begin certificate validation */
2598  if ( ( rc = create_validator ( &tls->server.validator,
2599  tls->server.chain,
2600  tls->server.root ) ) != 0 ) {
2601  DBGC ( tls, "TLS %p could not start certificate validation: "
2602  "%s\n", tls, strerror ( rc ) );
2603  return rc;
2604  }
2605  pending_get ( &tls->server.validation );
2606 
2607  return 0;
2608 }
#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:79
struct tls_server server
Server state.
Definition: tls.h:480
int create_validator(struct interface *job, struct x509_chain *chain, struct x509_root *root)
Instantiate a certificate validator.
Definition: validator.c:760
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
struct x509_chain * chain
Certificate chain.
Definition: tls.h:424
#define DBGC_HD(...)
Definition: compiler.h:507
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:430
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
struct interface validator
Certificate validator.
Definition: tls.h:428
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:46
struct x509_root * root
Root of trust.
Definition: tls.h:422

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

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

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

2697  {
2698  size_t remaining;
2699  int rc;
2700 
2701  while ( ( remaining = iob_len ( iobuf ) ) ) {
2702  const struct {
2703  uint8_t type;
2704  tls24_t length;
2705  uint8_t payload[0];
2706  } __attribute__ (( packed )) *handshake = iobuf->data;
2707  const void *payload;
2708  size_t payload_len;
2709  size_t record_len;
2710 
2711  /* Parse header */
2712  if ( sizeof ( *handshake ) > remaining ) {
2713  /* Leave remaining fragment unconsumed */
2714  break;
2715  }
2716  payload_len = tls_uint24 ( &handshake->length );
2717  if ( payload_len > ( remaining - sizeof ( *handshake ) ) ) {
2718  /* Leave remaining fragment unconsumed */
2719  break;
2720  }
2721  payload = &handshake->payload;
2722  record_len = ( sizeof ( *handshake ) + payload_len );
2723 
2724  /* Handle payload */
2725  switch ( handshake->type ) {
2726  case TLS_HELLO_REQUEST:
2727  rc = tls_new_hello_request ( tls, payload,
2728  payload_len );
2729  break;
2730  case TLS_SERVER_HELLO:
2731  rc = tls_new_server_hello ( tls, payload, payload_len );
2732  break;
2734  rc = tls_new_session_ticket ( tls, payload,
2735  payload_len );
2736  break;
2737  case TLS_CERTIFICATE:
2738  rc = tls_new_certificate ( tls, payload, payload_len );
2739  break;
2741  rc = tls_new_server_key_exchange ( tls, payload,
2742  payload_len );
2743  break;
2745  rc = tls_new_certificate_request ( tls, payload,
2746  payload_len );
2747  break;
2748  case TLS_SERVER_HELLO_DONE:
2749  rc = tls_new_server_hello_done ( tls, payload,
2750  payload_len );
2751  break;
2752  case TLS_FINISHED:
2753  rc = tls_new_finished ( tls, payload, payload_len );
2754  break;
2755  default:
2756  DBGC ( tls, "TLS %p ignoring handshake type %d\n",
2757  tls, handshake->type );
2758  rc = 0;
2759  break;
2760  }
2761 
2762  /* Add to handshake digest (except for Hello Requests,
2763  * which are explicitly excluded).
2764  */
2765  if ( handshake->type != TLS_HELLO_REQUEST )
2766  tls_add_handshake ( tls, handshake, record_len );
2767 
2768  /* Abort on failure */
2769  if ( rc != 0 )
2770  return rc;
2771 
2772  /* Move to next handshake record */
2773  iob_pull ( iobuf, record_len );
2774  }
2775 
2776  return 0;
2777 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:107
#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:237
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:819
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:73
#define TLS_SERVER_HELLO_DONE
Definition: tls.h:76
#define TLS_CERTIFICATE_REQUEST
Definition: tls.h:75
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:2086
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:2319
#define TLS_HELLO_REQUEST
Definition: tls.h:69
static int tls_new_finished(struct tls_connection *tls, const void *data, size_t len)
Receive new Finished handshake record.
Definition: tls.c:2618
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
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:2117
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:2522
#define TLS_NEW_SESSION_TICKET
Definition: tls.h:72
A TLS 24-bit integer.
Definition: tls.c:222
#define TLS_SERVER_KEY_EXCHANGE
Definition: tls.h:74
void * data
Start of data.
Definition: iobuf.h:53
static int tls_new_certificate(struct tls_connection *tls, const void *data, size_t len)
Receive new Certificate handshake record.
Definition: tls.c:2451
#define TLS_SERVER_HELLO
Definition: tls.h:71
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:2582
#define TLS_FINISHED
Definition: tls.h:79
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:2491

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

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

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

2802  {
2803  struct io_buffer *iobuf;
2804  int rc;
2805 
2806  /* Fail unless we are ready to receive data */
2807  if ( ! tls_ready ( tls ) )
2808  return -ENOTCONN;
2809 
2810  /* Deliver each I/O buffer in turn */
2811  while ( ( iobuf = list_first_entry ( rx_data, struct io_buffer,
2812  list ) ) ) {
2813  list_del ( &iobuf->list );
2814  if ( ( rc = xfer_deliver_iob ( &tls->plainstream,
2815  iobuf ) ) != 0 ) {
2816  DBGC ( tls, "TLS %p could not deliver data: "
2817  "%s\n", tls, strerror ( rc ) );
2818  return rc;
2819  }
2820  }
2821 
2822  return 0;
2823 }
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:256
#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:334
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
#define ENOTCONN
The socket is not connected.
Definition: errno.h:570
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:260
struct interface plainstream
Plaintext stream.
Definition: tls.h:454
A persistent I/O buffer.
Definition: iobuf.h:38

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

2834  {
2835  int ( * handler ) ( struct tls_connection *tls,
2836  struct io_buffer *iobuf );
2837  struct io_buffer *tmp = NULL;
2838  struct io_buffer **iobuf;
2839  int rc;
2840 
2841  /* Deliver data records as-is to the plainstream interface */
2842  if ( type == TLS_TYPE_DATA )
2843  return tls_new_data ( tls, rx_data );
2844 
2845  /* Determine handler and fragment buffer */
2846  iobuf = &tmp;
2847  switch ( type ) {
2849  handler = tls_new_change_cipher;
2850  break;
2851  case TLS_TYPE_ALERT:
2852  handler = tls_new_alert;
2853  break;
2854  case TLS_TYPE_HANDSHAKE:
2855  handler = tls_new_handshake;
2856  iobuf = &tls->rx.handshake;
2857  break;
2858  default:
2859  DBGC ( tls, "TLS %p unknown record type %d\n", tls, type );
2860  handler = tls_new_unknown;
2861  break;
2862  }
2863 
2864  /* Merge into a single I/O buffer */
2865  if ( *iobuf )
2866  list_add ( &(*iobuf)->list, rx_data );
2867  *iobuf = iob_concatenate ( rx_data );
2868  if ( ! *iobuf ) {
2869  DBGC ( tls, "TLS %p could not concatenate non-data record "
2870  "type %d\n", tls, type );
2871  rc = -ENOMEM_RX_CONCAT;
2872  goto err_concatenate;
2873  }
2874 
2875  /* Handle record */
2876  if ( ( rc = handler ( tls, *iobuf ) ) != 0 )
2877  goto err_handle;
2878 
2879  /* Discard I/O buffer if empty */
2880  if ( ! iob_len ( *iobuf ) ) {
2881  free_iob ( *iobuf );
2882  *iobuf = NULL;
2883  }
2884 
2885  /* Sanity check */
2886  assert ( tmp == NULL );
2887 
2888  return 0;
2889 
2890  err_handle:
2891  free_iob ( *iobuf );
2892  *iobuf = NULL;
2893  err_concatenate:
2894  return rc;
2895 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct io_buffer * handshake
Received handshake fragment.
Definition: tls.h:398
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:70
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
#define ENOMEM_RX_CONCAT
Definition: tls.c:143
unsigned long tmp
Definition: linux_pci.h:65
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
Definition: tls.h:54
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:2044
static int tls_new_data(struct tls_connection *tls, struct list_head *rx_data)
Receive new data record.
Definition: tls.c:2801
static int tls_new_change_cipher(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Change Cipher record.
Definition: tls.c:2009
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
Definition: iobuf.c:250
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
struct tls_rx rx
Receive state.
Definition: tls.h:476
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:63
static int tls_new_handshake(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Handshake record.
Definition: tls.c:2696
A TLS connection.
Definition: tls.h:436
#define TLS_TYPE_DATA
Application data content type.
Definition: tls.h:66
#define TLS_TYPE_ALERT
Alert content type.
Definition: tls.h:60
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static int tls_new_unknown(struct tls_connection *tls __unused, struct io_buffer *iobuf)
Receive new unknown record.
Definition: tls.c:2786
A persistent I/O buffer.
Definition: iobuf.h:38

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

2912  {
2913  struct tls_cipher_suite *suite = cipherspec->suite;
2914  struct digest_algorithm *digest = suite->digest;
2915 
2916  hmac_init ( digest, ctx, cipherspec->mac_secret, suite->mac_len );
2917  hmac_update ( digest, ctx, authhdr, sizeof ( *authhdr ) );
2918 }
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition: hmac.c:58
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:208
A TLS cipher suite.
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:43
uint8_t mac_len
MAC length.
Definition: tls.h:220
A message digest algorithm.
Definition: crypto.h:19
void * mac_secret
MAC secret.
Definition: tls.h:266

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

2929  {
2930  struct digest_algorithm *digest = cipherspec->suite->digest;
2931 
2932  hmac_update ( digest, ctx, data, len );
2933 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:208
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:43
A message digest algorithm.
Definition: crypto.h:19
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 2942 of file tls.c.

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

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

2960  {
2961  struct digest_algorithm *digest = cipherspec->suite->digest;
2962  uint8_t ctx[ hmac_ctxsize ( digest ) ];
2963 
2964  tls_hmac_init ( cipherspec, ctx, authhdr );
2965  tls_hmac_update ( cipherspec, ctx, data, len );
2966  tls_hmac_final ( cipherspec, ctx, hmac );
2967 }
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:2942
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2928
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:208
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition: tls.c:2911
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition: hmac.h:29
unsigned char uint8_t
Definition: stdint.h:10
A message digest algorithm.
Definition: crypto.h:19
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 2977 of file tls.c.

2979  {
2980  struct digest_algorithm *digest = cipherspec->suite->digest;
2981  uint8_t ctx[ hmac_ctxsize ( digest ) ];
2982  struct io_buffer *iobuf;
2983 
2984  tls_hmac_init ( cipherspec, ctx, authhdr );
2985  list_for_each_entry ( iobuf, list, list ) {
2986  tls_hmac_update ( cipherspec, ctx, iobuf->data,
2987  iob_len ( iobuf ) );
2988  }
2989  tls_hmac_final ( cipherspec, ctx, hmac );
2990 }
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:2942
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2928
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:208
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition: tls.c:2911
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition: hmac.h:29
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
unsigned char uint8_t
Definition: stdint.h:10
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
void * data
Start of data.
Definition: iobuf.h:53
A message digest algorithm.
Definition: crypto.h:19
A persistent I/O buffer.
Definition: iobuf.h:38

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

2999  {
3000  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.active;
3001  struct tls_cipher_suite *suite = cipherspec->suite;
3002  struct cipher_algorithm *cipher = suite->cipher;
3003  struct tls_header *tlshdr;
3004  unsigned int count;
3005  size_t each;
3006 
3007  /* Calculate number of records (allowing for zero-length records) */
3008  count = ( len ? ( ( len + TLS_TX_BUFSIZE - 1 ) / TLS_TX_BUFSIZE ) : 1 );
3009 
3010  /* Calculate maximum additional length per record */
3011  each = ( sizeof ( *tlshdr ) + suite->record_iv_len + suite->mac_len +
3012  ( is_block_cipher ( cipher ) ? cipher->blocksize : 0 ) +
3013  cipher->authsize );
3014 
3015  /* Calculate maximum total additional length */
3016  return ( count * each );
3017 }
size_t blocksize
Block size.
Definition: crypto.h:61
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:218
A TLS cipher specification.
Definition: tls.h:258
size_t authsize
Authentication tag size.
Definition: crypto.h:75
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
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:200
#define TLS_TX_BUFSIZE
TX maximum fragment length.
Definition: tls.h:492
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:374
uint8_t mac_len
MAC length.
Definition: tls.h:220
A TLS header.
Definition: tls.h:29
struct tls_tx tx
Transmit state.
Definition: tls.h:474
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:274
A cipher algorithm.
Definition: crypto.h:51
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:206
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:277

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

3223  {
3224  uint8_t *padding;
3225  unsigned int pad;
3226  unsigned int i;
3227  size_t len;
3228 
3229  /* Extract and verify padding */
3230  padding = ( iobuf->tail - 1 );
3231  pad = *padding;
3232  len = ( pad + 1 );
3233  if ( len > iob_len ( iobuf ) ) {
3234  DBGC ( tls, "TLS %p received underlength padding\n", tls );
3235  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3236  return -EINVAL_PADDING;
3237  }
3238  for ( i = 0 ; i < pad ; i++ ) {
3239  if ( *(--padding) != pad ) {
3240  DBGC ( tls, "TLS %p received bad padding\n", tls );
3241  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3242  return -EINVAL_PADDING;
3243  }
3244  }
3245 
3246  return len;
3247 }
#define EINVAL_PADDING
Definition: tls.c:95
#define DBGC(...)
Definition: compiler.h:505
u32 pad[9]
Padding.
Definition: ar9003_mac.h:47
void * tail
End of data.
Definition: iobuf.h:55
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:160
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
void * data
Start of data.
Definition: iobuf.h:53

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

3259  {
3260  struct tls_cipherspec *cipherspec = &tls->rx.cipherspec.active;
3261  struct tls_cipher_suite *suite = cipherspec->suite;
3262  struct cipher_algorithm *cipher = suite->cipher;
3263  struct digest_algorithm *digest = suite->digest;
3264  size_t len = ntohs ( tlshdr->length );
3265  struct {
3266  uint8_t fixed[suite->fixed_iv_len];
3267  uint8_t record[suite->record_iv_len];
3268  } __attribute__ (( packed )) iv;
3269  struct tls_auth_header authhdr;
3270  uint8_t verify_mac[digest->digestsize];
3271  uint8_t verify_auth[cipher->authsize];
3272  struct io_buffer *first;
3273  struct io_buffer *last;
3274  struct io_buffer *iobuf;
3275  void *mac;
3276  void *auth;
3277  size_t check_len;
3278  int pad_len;
3279  int rc;
3280 
3281  /* Locate first and last data buffers */
3282  assert ( ! list_empty ( rx_data ) );
3283  first = list_first_entry ( rx_data, struct io_buffer, list );
3284  last = list_last_entry ( rx_data, struct io_buffer, list );
3285 
3286  /* Extract initialisation vector */
3287  if ( iob_len ( first ) < sizeof ( iv.record ) ) {
3288  DBGC ( tls, "TLS %p received underlength IV\n", tls );
3289  DBGC_HD ( tls, first->data, iob_len ( first ) );
3290  return -EINVAL_IV;
3291  }
3292  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
3293  memcpy ( iv.record, first->data, sizeof ( iv.record ) );
3294  iob_pull ( first, sizeof ( iv.record ) );
3295  len -= sizeof ( iv.record );
3296 
3297  /* Extract unencrypted authentication tag */
3298  if ( iob_len ( last ) < cipher->authsize ) {
3299  DBGC ( tls, "TLS %p received underlength authentication tag\n",
3300  tls );
3301  DBGC_HD ( tls, last->data, iob_len ( last ) );
3302  return -EINVAL_MAC;
3303  }
3304  iob_unput ( last, cipher->authsize );
3305  len -= cipher->authsize;
3306  auth = last->tail;
3307 
3308  /* Construct authentication data */
3309  authhdr.seq = cpu_to_be64 ( tls->rx.seq );
3310  authhdr.header.type = tlshdr->type;
3311  authhdr.header.version = tlshdr->version;
3312  authhdr.header.length = htons ( len );
3313 
3314  /* Set initialisation vector */
3315  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv, sizeof ( iv ) );
3316 
3317  /* Process authentication data, if applicable */
3318  if ( is_auth_cipher ( cipher ) ) {
3319  cipher_decrypt ( cipher, cipherspec->cipher_ctx, &authhdr,
3320  NULL, sizeof ( authhdr ) );
3321  }
3322 
3323  /* Decrypt the received data */
3324  check_len = 0;
3325  list_for_each_entry ( iobuf, &tls->rx.data, list ) {
3326  cipher_decrypt ( cipher, cipherspec->cipher_ctx,
3327  iobuf->data, iobuf->data, iob_len ( iobuf ) );
3328  check_len += iob_len ( iobuf );
3329  }
3330  assert ( check_len == len );
3331 
3332  /* Strip block padding, if applicable */
3333  if ( is_block_cipher ( cipher ) ) {
3334  pad_len = tls_verify_padding ( tls, last );
3335  if ( pad_len < 0 ) {
3336  /* Assume zero padding length to avoid timing attacks */
3337  pad_len = 0;
3338  }
3339  iob_unput ( last, pad_len );
3340  len -= pad_len;
3341  }
3342 
3343  /* Extract decrypted MAC */
3344  if ( iob_len ( last ) < suite->mac_len ) {
3345  DBGC ( tls, "TLS %p received underlength MAC\n", tls );
3346  DBGC_HD ( tls, last->data, iob_len ( last ) );
3347  return -EINVAL_MAC;
3348  }
3349  iob_unput ( last, suite->mac_len );
3350  len -= suite->mac_len;
3351  mac = last->tail;
3352 
3353  /* Dump received data */
3354  DBGC2 ( tls, "Received plaintext data:\n" );
3355  check_len = 0;
3356  list_for_each_entry ( iobuf, rx_data, list ) {
3357  DBGC2_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3358  check_len += iob_len ( iobuf );
3359  }
3360  assert ( check_len == len );
3361 
3362  /* Generate MAC */
3363  authhdr.header.length = htons ( len );
3364  if ( suite->mac_len )
3365  tls_hmac_list ( cipherspec, &authhdr, rx_data, verify_mac );
3366 
3367  /* Generate authentication tag */
3368  cipher_auth ( cipher, cipherspec->cipher_ctx, verify_auth );
3369 
3370  /* Verify MAC */
3371  if ( memcmp ( mac, verify_mac, suite->mac_len ) != 0 ) {
3372  DBGC ( tls, "TLS %p failed MAC verification\n", tls );
3373  return -EINVAL_MAC;
3374  }
3375 
3376  /* Verify authentication tag */
3377  if ( memcmp ( auth, verify_auth, cipher->authsize ) != 0 ) {
3378  DBGC ( tls, "TLS %p failed authentication tag verification\n",
3379  tls );
3380  return -EINVAL_MAC;
3381  }
3382 
3383  /* Process plaintext record */
3384  if ( ( rc = tls_new_record ( tls, tlshdr->type, rx_data ) ) != 0 )
3385  return rc;
3386 
3387  return 0;
3388 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:107
#define __attribute__(x)
Definition: compiler.h:10
static int is_auth_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:282
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head data
List of received data buffers.
Definition: tls.h:396
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:218
uint32_t first
First block in range.
Definition: pccrr.h:15
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:386
uint8_t type
Content type.
Definition: tls.h:34
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:41
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition: eltorito.h:13
#define ntohs(value)
Definition: byteswap.h:137
TLS authentication header.
Definition: tls.h:155
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:258
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:347
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
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:2977
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:334
size_t authsize
Authentication tag size.
Definition: crypto.h:75
#define EINVAL_MAC
Definition: tls.c:103
void * tail
End of data.
Definition: iobuf.h:55
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:264
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:260
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:208
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:216
A TLS cipher suite.
Definition: tls.h:200
#define iob_unput(iobuf, len)
Definition: iobuf.h:140
#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:160
#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:241
uint8_t mac_len
MAC length.
Definition: tls.h:220
unsigned char uint8_t
Definition: stdint.h:10
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:261
struct tls_rx rx
Receive state.
Definition: tls.h:476
long pad_len
Definition: bigint.h:31
uint64_t seq
Sequence number.
Definition: tls.h:388
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
#define EINVAL_IV
Definition: tls.c:91
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:27
void * data
Start of data.
Definition: iobuf.h:53
uint16_t version
Protocol version.
Definition: tls.h:39
A message digest algorithm.
Definition: crypto.h:19
#define cpu_to_be64(value)
Definition: byteswap.h:112
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:274
A cipher algorithm.
Definition: crypto.h:51
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition: crypto.h:267
static int tls_new_record(struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
Receive new record.
Definition: tls.c:2833
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:206
static int tls_verify_padding(struct tls_connection *tls, struct io_buffer *iobuf)
Verify block padding.
Definition: tls.c:3222
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define htons(value)
Definition: byteswap.h:136
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:268
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:277
A persistent I/O buffer.
Definition: iobuf.h:38

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

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

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

3422  {
3423  int rc;
3424 
3425  /* Refuse unless we are ready to accept data */
3426  if ( ! tls_ready ( tls ) ) {
3427  rc = -ENOTCONN;
3428  goto done;
3429  }
3430 
3431  /* Send data record */
3432  if ( ( rc = tls_send_record ( tls, TLS_TYPE_DATA,
3433  iob_disown ( iobuf ) ) ) != 0 )
3434  goto done;
3435 
3436  done:
3437  free_iob ( iobuf );
3438  return rc;
3439 }
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:3053
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
#define ENOTCONN
The socket is not connected.
Definition: errno.h:570
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:260
#define TLS_TYPE_DATA
Application data content type.
Definition: tls.h:66
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 3448 of file tls.c.

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

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

◆ tls_newdata_process_header()

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

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

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

3571  {
3572  struct io_buffer *iobuf;
3573  int rc;
3574 
3575  /* Move current buffer to end of list */
3576  iobuf = list_first_entry ( &tls->rx.data, struct io_buffer, list );
3577  list_del ( &iobuf->list );
3578  list_add_tail ( &iobuf->list, &tls->rx.data );
3579 
3580  /* Continue receiving data if any space remains */
3581  iobuf = list_first_entry ( &tls->rx.data, struct io_buffer, list );
3582  if ( iob_tailroom ( iobuf ) )
3583  return 0;
3584 
3585  /* Process record */
3586  if ( ( rc = tls_new_ciphertext ( tls, &tls->rx.header,
3587  &tls->rx.data ) ) != 0 )
3588  return rc;
3589 
3590  /* Increment RX sequence number */
3591  tls->rx.seq += 1;
3592 
3593  /* Return to header state */
3594  assert ( list_empty ( &tls->rx.data ) );
3595  tls->rx.state = TLS_RX_HEADER;
3596  iob_unput ( &tls->rx.iobuf, sizeof ( tls->rx.header ) );
3597 
3598  return 0;
3599 }
struct tls_header header
Current received record header.
Definition: tls.h:392
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:3257
struct list_head data
List of received data buffers.
Definition: tls.h:396
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:334
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
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:94
#define iob_unput(iobuf, len)
Definition: iobuf.h:140
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:180
struct tls_rx rx
Receive state.
Definition: tls.h:476
enum tls_rx_state state
State machine current state.
Definition: tls.h:390
uint64_t seq
Sequence number.
Definition: tls.h:388
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:394
A persistent I/O buffer.
Definition: iobuf.h:38

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

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

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

3626  {
3627  size_t frag_len;
3628  int ( * process ) ( struct tls_connection *tls );
3629  struct io_buffer *dest;
3630  int rc;
3631 
3632  while ( iob_len ( iobuf ) ) {
3633 
3634  /* Select buffer according to current state */
3635  switch ( tls->rx.state ) {
3636  case TLS_RX_HEADER:
3637  dest = &tls->rx.iobuf;
3639  break;
3640  case TLS_RX_DATA:
3641  dest = list_first_entry ( &tls->rx.data,
3642  struct io_buffer, list );
3643  assert ( dest != NULL );
3645  break;
3646  default:
3647  assert ( 0 );
3648  rc = -EINVAL_RX_STATE;
3649  goto done;
3650  }
3651 
3652  /* Copy data portion to buffer */
3653  frag_len = iob_len ( iobuf );
3654  if ( frag_len > iob_tailroom ( dest ) )
3655  frag_len = iob_tailroom ( dest );
3656  memcpy ( iob_put ( dest, frag_len ), iobuf->data, frag_len );
3657  iob_pull ( iobuf, frag_len );
3658 
3659  /* Process data if buffer is now full */
3660  if ( iob_tailroom ( dest ) == 0 ) {
3661  if ( ( rc = process ( tls ) ) != 0 ) {
3662  tls_close ( tls, rc );
3663  goto done;
3664  }
3665  }
3666  }
3667  rc = 0;
3668 
3669  done:
3670  free_iob ( iobuf );
3671  return rc;
3672 }
A process.
Definition: process.h:18
#define iob_pull(iobuf, len)
Definition: iobuf.h:107
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:125
static int tls_newdata_process_header(struct tls_connection *tls)
Handle received TLS header.
Definition: tls.c:3488
struct list_head data
List of received data buffers.
Definition: tls.h:396
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:422
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:334
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:3571
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define EINVAL_RX_STATE
Definition: tls.c:99
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:180
struct tls_rx rx
Receive state.
Definition: tls.h:476
enum tls_rx_state state
State machine current state.
Definition: tls.h:390
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:394
void * data
Start of data.
Definition: iobuf.h:53
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:151
A TLS connection.
Definition: tls.h:436
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct bofm_section_header done
Definition: bofm_test.c:46
A persistent I/O buffer.
Definition: iobuf.h:38

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

3703  {
3704  struct tls_session *session = tls->session;
3705  struct x509_certificate *cert;
3706 
3707  /* Mark validation as complete */
3708  pending_put ( &tls->server.validation );
3709 
3710  /* Close validator interface */
3711  intf_restart ( &tls->server.validator, rc );
3712 
3713  /* Check for validation failure */
3714  if ( rc != 0 ) {
3715  DBGC ( tls, "TLS %p certificate validation failed: %s\n",
3716  tls, strerror ( rc ) );
3717  goto err;
3718  }
3719  DBGC ( tls, "TLS %p certificate validation succeeded\n", tls );
3720 
3721  /* Extract first certificate */
3722  cert = x509_first ( tls->server.chain );
3723  assert ( cert != NULL );
3724 
3725  /* Verify server name */
3726  if ( ( rc = x509_check_name ( cert, session->name ) ) != 0 ) {
3727  DBGC ( tls, "TLS %p server certificate does not match %s: %s\n",
3728  tls, session->name, strerror ( rc ) );
3729  goto err;
3730  }
3731 
3732  /* Extract the now trusted server public key */
3733  memcpy ( &tls->server.key, &cert->subject.public_key.raw,
3734  sizeof ( tls->server.key ) );
3735 
3736  /* Schedule transmission of applicable handshake messages */
3739  TLS_TX_FINISHED );
3740  if ( tls->client.chain ) {
3741  tls->tx.pending |= TLS_TX_CERTIFICATE;
3742  if ( ! list_empty ( &tls->client.chain->links ) )
3744  }
3745  tls_tx_resume ( tls );
3746 
3747  return;
3748 
3749  err:
3750  tls_close ( tls, rc );
3751  return;
3752 }
struct asn1_cursor raw
Raw public key information.
Definition: x509.h:52
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:344
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:426
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1110
struct tls_session * session
Session.
Definition: tls.h:441
struct list_head links
List of links.
Definition: x509.h:205
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition: x509.c:1564
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:59
#define DBGC(...)
Definition: compiler.h:505
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:422
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
struct tls_server server
Server state.
Definition: tls.h:480
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:478
struct x509_public_key public_key
Public key information.
Definition: x509.h:66
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
An X.509 certificate.
Definition: x509.h:216
struct x509_subject subject
Subject.
Definition: x509.h:245
struct x509_chain * chain
Certificate chain.
Definition: tls.h:424
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:430
unsigned int pending
Pending transmissions.
Definition: tls.h:378
struct tls_tx tx
Transmit state.
Definition: tls.h:474
A TLS session.
Definition: tls.h:341
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:311
struct interface validator
Certificate validator.
Definition: tls.h:428
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:408
const char * name
Server name.
Definition: tls.h:348
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

3776  {
3777  struct tls_session *session = tls->session;
3778  struct tls_connection *conn;
3779  int rc;
3780 
3781  /* Wait for cipherstream to become ready */
3782  if ( ! xfer_window ( &tls->cipherstream ) )
3783  return;
3784 
3785  /* Send first pending transmission */
3786  if ( tls->tx.pending & TLS_TX_CLIENT_HELLO ) {
3787  /* Serialise server negotiations within a session, to
3788  * provide a consistent view of session IDs and
3789  * session tickets.
3790  */
3791  list_for_each_entry ( conn, &session->conn, list ) {
3792  if ( conn == tls )
3793  break;
3794  if ( is_pending ( &conn->server.negotiation ) )
3795  return;
3796  }
3797  /* Record or generate session ID and associated master secret */
3798  if ( session->id_len ) {
3799  /* Attempt to resume an existing session */
3800  memcpy ( tls->session_id, session->id,
3801  sizeof ( tls->session_id ) );
3802  tls->session_id_len = session->id_len;
3804  sizeof ( tls->master_secret ) );
3805  } else {
3806  /* No existing session: use a random session ID */
3807  assert ( sizeof ( tls->session_id ) ==
3808  sizeof ( tls->client.random ) );
3809  memcpy ( tls->session_id, &tls->client.random,
3810  sizeof ( tls->session_id ) );
3811  tls->session_id_len = sizeof ( tls->session_id );
3812  }
3813  /* Send Client Hello */
3814  if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
3815  DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
3816  tls, strerror ( rc ) );
3817  goto err;
3818  }
3819  tls->tx.pending &= ~TLS_TX_CLIENT_HELLO;
3820  } else if ( tls->tx.pending & TLS_TX_CERTIFICATE ) {
3821  /* Send Certificate */
3822  if ( ( rc = tls_send_certificate ( tls ) ) != 0 ) {
3823  DBGC ( tls, "TLS %p cold not send Certificate: %s\n",
3824  tls, strerror ( rc ) );
3825  goto err;
3826  }
3827  tls->tx.pending &= ~TLS_TX_CERTIFICATE;
3828  } else if ( tls->tx.pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
3829  /* Send Client Key Exchange */
3830  if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
3831  DBGC ( tls, "TLS %p could not send Client Key "
3832  "Exchange: %s\n", tls, strerror ( rc ) );
3833  goto err;
3834  }
3836  } else if ( tls->tx.pending & TLS_TX_CERTIFICATE_VERIFY ) {
3837  /* Send Certificate Verify */
3838  if ( ( rc = tls_send_certificate_verify ( tls ) ) != 0 ) {
3839  DBGC ( tls, "TLS %p could not send Certificate "
3840  "Verify: %s\n", tls, strerror ( rc ) );
3841  goto err;
3842  }
3844  } else if ( tls->tx.pending & TLS_TX_CHANGE_CIPHER ) {
3845  /* Send Change Cipher, and then change the cipher in use */
3846  if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
3847  DBGC ( tls, "TLS %p could not send Change Cipher: "
3848  "%s\n", tls, strerror ( rc ) );
3849  goto err;
3850  }
3851  if ( ( rc = tls_change_cipher ( tls,
3852  &tls->tx.cipherspec ) ) != 0 ){
3853  DBGC ( tls, "TLS %p could not activate TX cipher: "
3854  "%s\n", tls, strerror ( rc ) );
3855  goto err;
3856  }
3857  tls->tx.seq = 0;
3858  tls->tx.pending &= ~TLS_TX_CHANGE_CIPHER;
3859  } else if ( tls->tx.pending & TLS_TX_FINISHED ) {
3860  /* Send Finished */
3861  if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
3862  DBGC ( tls, "TLS %p could not send Finished: %s\n",
3863  tls, strerror ( rc ) );
3864  goto err;
3865  }
3866  tls->tx.pending &= ~TLS_TX_FINISHED;
3867  }
3868 
3869  /* Reschedule process if pending transmissions remain,
3870  * otherwise send notification of a window change.
3871  */
3872  if ( tls->tx.pending ) {
3873  tls_tx_resume ( tls );
3874  } else {
3875  xfer_window_changed ( &tls->plainstream );
3876  }
3877 
3878  return;
3879 
3880  err:
3881  tls_close ( tls, rc );
3882 }
static int tls_send_certificate(struct tls_connection *tls)
Transmit Certificate record.
Definition: tls.c:1360
uint8_t id[32]
Session ID.
Definition: tls.h:355
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:147
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec_pair *pair)
Activate next cipher suite.
Definition: tls.c:983
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1110
struct tls_session * session
Session.
Definition: tls.h:441
uint8_t master_secret[48]
Master secret.
Definition: tls.h:363
#define DBGC(...)
Definition: compiler.h:505
uint8_t session_id[32]
Session ID.
Definition: tls.h:445
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:422
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:117
struct tls_server server
Server state.
Definition: tls.h:480
void * memcpy(void *dest, const void *src, size_t len) __nonnull
size_t id_len
Length of session ID.
Definition: tls.h:357
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:478
static int tls_send_change_cipher(struct tls_connection *tls)
Transmit Change Cipher record.
Definition: tls.c:1951
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
struct list_head list
List of connections within the same session.
Definition: tls.h:443
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:25
uint8_t master_secret[48]
Master secret.
Definition: tls.h:461
static int tls_send_client_key_exchange(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition: tls.c:1842
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:374
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
uint64_t seq
Sequence number.
Definition: tls.h:376
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:456
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:432
unsigned int pending
Pending transmissions.
Definition: tls.h:378
struct tls_tx tx
Transmit state.
Definition: tls.h:474
static int tls_send_certificate_verify(struct tls_connection *tls)
Transmit Certificate Verify record.
Definition: tls.c:1870
A TLS session.
Definition: tls.h:341
A TLS connection.
Definition: tls.h:436
struct tls_client_random random
Random bytes.
Definition: tls.h:404
struct list_head conn
List of connections.
Definition: tls.h:368
static int tls_send_finished(struct tls_connection *tls)
Transmit Finished record.
Definition: tls.c:1968
static int tls_send_client_hello(struct tls_connection *tls)
Transmit Client Hello record.
Definition: tls.c:1349
size_t session_id_len
Length of session ID.
Definition: tls.h:447
struct interface plainstream
Plaintext stream.
Definition: tls.h:454

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

3902  {
3903  struct tls_session *session;
3904  char *name_copy;
3905  int rc;
3906 
3907  /* Find existing matching session, if any */
3908  list_for_each_entry ( session, &tls_sessions, list ) {
3909  if ( ( strcmp ( name, session->name ) == 0 ) &&
3910  ( tls->server.root == session->root ) &&
3911  ( tls->client.key == session->key ) ) {
3912  ref_get ( &session->refcnt );
3913  tls->session = session;
3914  DBGC ( tls, "TLS %p joining session %s\n", tls, name );
3915  return 0;
3916  }
3917  }
3918 
3919  /* Create new session */
3920  session = zalloc ( sizeof ( *session ) + strlen ( name )
3921  + 1 /* NUL */ );
3922  if ( ! session ) {
3923  rc = -ENOMEM;
3924  goto err_alloc;
3925  }
3926  ref_init ( &session->refcnt, free_tls_session );
3927  name_copy = ( ( ( void * ) session ) + sizeof ( *session ) );
3928  strcpy ( name_copy, name );
3929  session->name = name_copy;
3930  session->root = x509_root_get ( tls->server.root );
3931  session->key = privkey_get ( tls->client.key );
3932  INIT_LIST_HEAD ( &session->conn );
3933  list_add ( &session->list, &tls_sessions );
3934 
3935  /* Record session */
3936  tls->session = session;
3937 
3938  DBGC ( tls, "TLS %p created session %s\n", tls, name );
3939  return 0;
3940 
3941  ref_put ( &session->refcnt );
3942  err_alloc:
3943  return rc;
3944 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1986
struct tls_session * session
Session.
Definition: tls.h:441
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:70
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
#define DBGC(...)
Definition: compiler.h:505
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
Definition: privkey.h:31
static void free_tls_session(struct refcnt *refcnt)
Free TLS session.
Definition: tls.c:359
struct private_key * key
Private key (if used)
Definition: tls.h:406
struct tls_server server
Server state.
Definition: tls.h:480
struct refcnt refcnt
Reference counter.
Definition: tls.h:343
#define ENOMEM
Not enough space.
Definition: errno.h:535
struct tls_client client
Client state.
Definition: tls.h:478
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:347
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:393
struct list_head list
List of sessions.
Definition: tls.h:345
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:93
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
A TLS session.
Definition: tls.h:341
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:174
struct x509_root * root
Root of trust.
Definition: tls.h:350
struct private_key * key
Private key.
Definition: tls.h:352
struct list_head conn
List of connections.
Definition: tls.h:368
const char * name
Server name.
Definition: tls.h:348
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
struct x509_root * root
Root of trust.
Definition: tls.h:422

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

3963  {
3964  struct tls_connection *tls;
3965  int rc;
3966 
3967  /* Allocate and initialise TLS structure */
3968  tls = malloc ( sizeof ( *tls ) );
3969  if ( ! tls ) {
3970  rc = -ENOMEM;
3971  goto err_alloc;
3972  }
3973  memset ( tls, 0, sizeof ( *tls ) );
3974  ref_init ( &tls->refcnt, free_tls );
3975  INIT_LIST_HEAD ( &tls->list );
3976  intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt );
3978  intf_init ( &tls->server.validator, &tls_validator_desc, &tls->refcnt );
3980  &tls->refcnt );
3981  tls->client.key = privkey_get ( key ? key : &private_key );
3983  tls->version = TLS_VERSION_MAX;
3984  tls_clear_cipher ( tls, &tls->tx.cipherspec.active );
3985  tls_clear_cipher ( tls, &tls->tx.cipherspec.pending );
3986  tls_clear_cipher ( tls, &tls->rx.cipherspec.active );
3987  tls_clear_cipher ( tls, &tls->rx.cipherspec.pending );
3988  tls_clear_handshake ( tls );
3989  tls->client.random.gmt_unix_time = time ( NULL );
3990  iob_populate ( &tls->rx.iobuf, &tls->rx.header, 0,
3991  sizeof ( tls->rx.header ) );
3992  INIT_LIST_HEAD ( &tls->rx.data );
3993  if ( ( rc = tls_generate_random ( tls, &tls->client.random.random,
3994  ( sizeof ( tls->client.random.random ) ) ) ) != 0 ) {
3995  goto err_random;
3996  }
3997  if ( ( rc = tls_session ( tls, name ) ) != 0 )
3998  goto err_session;
3999  list_add_tail ( &tls->list, &tls->session->conn );
4000 
4001  /* Start negotiation */
4002  tls_restart ( tls );
4003 
4004  /* Attach to parent interface, mortalise self, and return */
4005  intf_insert ( xfer, &tls->plainstream, &tls->cipherstream );
4006  ref_put ( &tls->refcnt );
4007  return 0;
4008 
4009  err_session:
4010  err_random:
4011  ref_put ( &tls->refcnt );
4012  err_alloc:
4013  return rc;
4014 }
static void free_tls(struct refcnt *refcnt)
Free TLS connection.
Definition: tls.c:383
struct tls_header header
Current received record header.
Definition: tls.h:392
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1986
struct process process
Transmit process.
Definition: tls.h:380
struct tls_session * session
Session.
Definition: tls.h:441
struct list_head data
List of received data buffers.
Definition: tls.h:396
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition: tls.c:1131
struct stp_switch root
Root switch.
Definition: stp.h:27
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
struct refcnt refcnt
Reference counter.
Definition: tls.h:438
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:386
struct x509_root root_certificates
Root certificates.
Definition: rootcert.c:79
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
Definition: privkey.h:31
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:195
static struct interface_descriptor tls_cipherstream_desc
TLS ciphertext stream interface descriptor.
Definition: tls.c:3686
static struct interface_descriptor tls_validator_desc
TLS certificate validator interface descriptor.
Definition: tls.c:3760
struct private_key * key
Private key (if used)
Definition: tls.h:406
struct tls_server server
Server state.
Definition: tls.h:480
#define ENOMEM
Not enough space.
Definition: errno.h:535
struct tls_client client
Client state.
Definition: tls.h:478
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
struct list_head list
List of connections within the same session.
Definition: tls.h:443
uint32_t gmt_unix_time
GMT Unix time.
Definition: tls.h:313
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:393
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:374
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:456
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:146
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:276
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
struct tls_rx rx
Receive state.
Definition: tls.h:476
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:51
struct tls_tx tx
Transmit state.
Definition: tls.h:474
static struct interface_descriptor tls_plainstream_desc
TLS plaintext stream interface descriptor.
Definition: tls.c:3471
void intf_insert(struct interface *intf, struct interface *upper, struct interface *lower)
Insert a filter interface.
Definition: interface.c:402
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
uint8_t random[28]
Random data.
Definition: tls.h:315
A TLS session.
Definition: tls.h:341
static struct process_descriptor tls_process_desc
TLS TX process descriptor.
Definition: tls.c:3885
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:394
struct interface validator
Certificate validator.
Definition: tls.h:428
uint16_t version
Protocol version.
Definition: tls.h:459
static void tls_clear_handshake(struct tls_connection *tls)
Clear handshake digest algorithm.
Definition: tls.c:778
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:274
A private key.
Definition: privkey.h:17
A TLS connection.
Definition: tls.h:436
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct tls_client_random random
Random bytes.
Definition: tls.h:404
struct list_head conn
List of connections.
Definition: tls.h:368
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:460
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
struct interface plainstream
Plaintext stream.
Definition: tls.h:454
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
union @391 key
Sense key.
Definition: scsi.h:18
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
void * memset(void *dest, int character, size_t len) __nonnull
struct x509_root * root
Root of trust.
Definition: tls.h:422

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:319
static void md5_sha1_final(void *ctx, void *out)
Generate MD5+SHA1 digest.
Definition: tls.c:321
static void md5_sha1_init(void *ctx)
Initialise MD5+SHA1 algorithm.
Definition: tls.c:294
An MD5+SHA1 digest.
Definition: tls.h:330
static void md5_sha1_update(void *ctx, const void *data, size_t len)
Accumulate data with MD5+SHA1 algorithm.
Definition: tls.c:308

Hybrid MD5+SHA1 digest algorithm.

Definition at line 330 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:330
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

RSA digestInfo prefix for MD5+SHA1 algorithm.

Definition at line 341 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:123
struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm
Public key exchange algorithm.
Definition: tls.c:1486
struct digest_algorithm digest_null
Definition: crypto_null.c:49
struct cipher_algorithm cipher_null
Definition: crypto_null.c:84

Null cipher suite.

Definition at line 851 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:1417

Public key exchange algorithm.

Definition at line 1486 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:1587

Ephemeral Diffie-Hellman key exchange algorithm.

Definition at line 1701 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:1712

Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm.

Definition at line 1831 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:250
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:159
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:422
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:117
static int tls_progress(struct tls_connection *tls, struct job_progress *progress)
Report job progress.
Definition: tls.c:3448
Job progress.
Definition: job.h:16
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
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:3420
A TLS connection.
Definition: tls.h:436
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:3026
static size_t tls_plainstream_window(struct tls_connection *tls)
Check flow control window.
Definition: tls.c:3403

TLS plaintext stream interface operations.

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

TLS plaintext stream interface descriptor.

Definition at line 3471 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:147
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1110
static int tls_cipherstream_deliver(struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *xfer __unused)
Receive new ciphertext.
Definition: tls.c:3624
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:422
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:117
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
A TLS connection.
Definition: tls.h:436
static size_t tls_cipherstream_window(struct tls_connection *tls)
Check flow control window.
Definition: tls.c:3607

TLS ciphertext stream interface operations.

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

TLS ciphertext stream interface descriptor.

Definition at line 3686 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:250
static void tls_validator_done(struct tls_connection *tls, int rc)
Handle certificate validation completion.
Definition: tls.c:3703
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
A TLS connection.
Definition: tls.h:436

TLS certificate validator interface operations.

Definition at line 3755 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:3755
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81
A TLS connection.
Definition: tls.h:436

TLS certificate validator interface descriptor.

Definition at line 3760 of file tls.c.

Referenced by add_tls().

◆ tls_process_desc

struct process_descriptor tls_process_desc
static
Initial value:
=
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition: process.h:98
static void tls_tx_step(struct tls_connection *tls)
TLS TX state machine.
Definition: tls.c:3776
A TLS connection.
Definition: tls.h:436
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 3885 of file tls.c.

Referenced by add_tls().