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/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_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )
 
#define EINFO_EPERM_CLIENT_CERT
 
#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 EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )
 
#define EINFO_EPROTO_VERSION
 
#define tls_prf_label(tls, secret, secret_len, out, out_len, label, ...)
 Generate secure pseudo-random data. More...
 
#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )
 Number of supported cipher suites. More...
 
#define TLS_NUM_SIG_HASH_ALGORITHMS   table_num_entries ( TLS_SIG_HASH_ALGORITHMS )
 Number of supported signature and hash algorithms. More...
 
#define TLS_NUM_NAMED_CURVES   table_num_entries ( TLS_NAMED_CURVES )
 Number of supported named curves. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
static LIST_HEAD (tls_sessions)
 List of TLS session. More...
 
static void tls_tx_resume_all (struct tls_session *session)
 Resume TX state machine for all connections within a session. More...
 
static 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 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 void tls_verify_handshake (struct tls_connection *tls, void *out)
 Calculate handshake 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 *pending, struct tls_cipherspec *active)
 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 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 57 of file tls.c.

◆ EINFO_EINVAL_CHANGE_CIPHER

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

Definition at line 58 of file tls.c.

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

Definition at line 61 of file tls.c.

◆ EINFO_EINVAL_ALERT

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

Definition at line 62 of file tls.c.

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

Definition at line 65 of file tls.c.

◆ EINFO_EINVAL_HELLO

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

Definition at line 66 of file tls.c.

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

Definition at line 69 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATE

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

Definition at line 70 of file tls.c.

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

Definition at line 73 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATES

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

Definition at line 74 of file tls.c.

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

Definition at line 77 of file tls.c.

◆ EINFO_EINVAL_HELLO_DONE

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

Definition at line 78 of file tls.c.

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

Definition at line 81 of file tls.c.

◆ EINFO_EINVAL_FINISHED

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

Definition at line 82 of file tls.c.

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

Definition at line 85 of file tls.c.

◆ EINFO_EINVAL_HANDSHAKE

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

Definition at line 86 of file tls.c.

◆ EINVAL_IV

#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )

Definition at line 89 of file tls.c.

◆ EINFO_EINVAL_IV

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

Definition at line 90 of file tls.c.

◆ EINVAL_PADDING

#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )

Definition at line 93 of file tls.c.

◆ EINFO_EINVAL_PADDING

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

Definition at line 94 of file tls.c.

◆ EINVAL_RX_STATE

#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )

Definition at line 97 of file tls.c.

◆ EINFO_EINVAL_RX_STATE

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

Definition at line 98 of file tls.c.

◆ EINVAL_MAC

#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )

Definition at line 101 of file tls.c.

◆ EINFO_EINVAL_MAC

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

Definition at line 102 of file tls.c.

◆ EINVAL_TICKET

#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )

Definition at line 105 of file tls.c.

◆ EINFO_EINVAL_TICKET

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

Definition at line 106 of file tls.c.

◆ EINVAL_KEY_EXCHANGE

#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )

Definition at line 109 of file tls.c.

◆ EINFO_EINVAL_KEY_EXCHANGE

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

Definition at line 110 of file tls.c.

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

Definition at line 113 of file tls.c.

◆ EINFO_EIO_ALERT

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

Definition at line 114 of file tls.c.

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

Definition at line 117 of file tls.c.

◆ EINFO_ENOMEM_CONTEXT

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

Definition at line 118 of file tls.c.

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

Definition at line 121 of file tls.c.

◆ EINFO_ENOMEM_CERTIFICATE

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

Definition at line 122 of file tls.c.

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

Definition at line 125 of file tls.c.

◆ EINFO_ENOMEM_CHAIN

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

Definition at line 126 of file tls.c.

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

Definition at line 129 of file tls.c.

◆ EINFO_ENOMEM_TX_PLAINTEXT

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

Definition at line 130 of file tls.c.

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

Definition at line 133 of file tls.c.

◆ EINFO_ENOMEM_TX_CIPHERTEXT

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

Definition at line 134 of file tls.c.

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

Definition at line 137 of file tls.c.

◆ EINFO_ENOMEM_RX_DATA

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

Definition at line 138 of file tls.c.

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

Definition at line 141 of file tls.c.

◆ EINFO_ENOMEM_RX_CONCAT

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

Definition at line 142 of file tls.c.

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

Definition at line 145 of file tls.c.

◆ EINFO_ENOTSUP_CIPHER

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

Definition at line 146 of file tls.c.

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

Definition at line 149 of file tls.c.

◆ EINFO_ENOTSUP_NULL

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

Definition at line 150 of file tls.c.

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

Definition at line 153 of file tls.c.

◆ EINFO_ENOTSUP_SIG_HASH

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

Definition at line 154 of file tls.c.

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

Definition at line 157 of file tls.c.

◆ EINFO_ENOTSUP_VERSION

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

Definition at line 158 of file tls.c.

◆ ENOTSUP_CURVE

#define ENOTSUP_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )

Definition at line 161 of file tls.c.

◆ EINFO_ENOTSUP_CURVE

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

Definition at line 162 of file tls.c.

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

Definition at line 165 of file tls.c.

◆ EINFO_EPERM_ALERT

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

Definition at line 166 of file tls.c.

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

Definition at line 169 of file tls.c.

◆ EINFO_EPERM_VERIFY

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

Definition at line 170 of file tls.c.

◆ EPERM_CLIENT_CERT

#define EPERM_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )

Definition at line 173 of file tls.c.

◆ EINFO_EPERM_CLIENT_CERT

#define EINFO_EPERM_CLIENT_CERT
Value:
"No suitable client certificate available" )
#define EINFO_EPERM
Definition: errno.h:615
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 174 of file tls.c.

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

Definition at line 177 of file tls.c.

◆ EINFO_EPERM_RENEG_INSECURE

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

Definition at line 178 of file tls.c.

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

Definition at line 181 of file tls.c.

◆ EINFO_EPERM_RENEG_VERIFY

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

Definition at line 182 of file tls.c.

◆ EPERM_KEY_EXCHANGE

#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )

Definition at line 185 of file tls.c.

◆ EINFO_EPERM_KEY_EXCHANGE

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

Definition at line 186 of file tls.c.

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

Definition at line 189 of file tls.c.

◆ EINFO_EPROTO_VERSION

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

Definition at line 190 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 )
__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:560
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

Generate secure pseudo-random data.

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

Definition at line 616 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 830 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 985 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 1057 of file tls.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ LIST_HEAD()

static LIST_HEAD ( tls_sessions  )
static

List of TLS session.

◆ tls_tx_resume_all()

static void tls_tx_resume_all ( struct tls_session session)
static

Resume TX state machine for all connections within a session.

Parameters
sessionTLS session

Definition at line 1099 of file tls.c.

1099  {
1100  struct tls_connection *tls;
1101 
1102  list_for_each_entry ( tls, &session->conn, list )
1103  tls_tx_resume ( tls );
1104 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1090
struct ntlm_data session
Session key.
Definition: ntlm.h:24
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct list_head list
List of connections within the same session.
Definition: tls.h:351
A TLS connection.
Definition: tls.h:344

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

Referenced by tls_close(), and tls_new_finished().

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

2937  {
2938  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec;
2939  struct tls_cipher_suite *suite = cipherspec->suite;
2940  struct cipher_algorithm *cipher = suite->cipher;
2941  struct digest_algorithm *digest = suite->digest;
2942  struct {
2943  uint8_t fixed[suite->fixed_iv_len];
2944  uint8_t record[suite->record_iv_len];
2945  } __attribute__ (( packed )) iv;
2946  struct tls_auth_header authhdr;
2947  struct tls_header *tlshdr;
2948  void *plaintext;
2949  size_t plaintext_len;
2950  struct io_buffer *ciphertext;
2951  size_t ciphertext_len;
2952  size_t padding_len;
2954  void *tmp;
2955  int rc;
2956 
2957  /* Construct initialisation vector */
2958  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
2959  if ( ( rc = tls_generate_random ( tls, iv.record,
2960  sizeof ( iv.record ) ) ) != 0 ) {
2961  goto err_random;
2962  }
2963 
2964  /* Construct authentication data */
2965  authhdr.seq = cpu_to_be64 ( tls->tx_seq );
2966  authhdr.header.type = type;
2967  authhdr.header.version = htons ( tls->version );
2968  authhdr.header.length = htons ( len );
2969 
2970  /* Calculate padding length */
2971  plaintext_len = ( len + suite->mac_len );
2972  if ( is_block_cipher ( cipher ) ) {
2973  padding_len = ( ( ( cipher->blocksize - 1 ) &
2974  -( plaintext_len + 1 ) ) + 1 );
2975  } else {
2976  padding_len = 0;
2977  }
2978  plaintext_len += padding_len;
2979 
2980  /* Allocate plaintext */
2981  plaintext = malloc ( plaintext_len );
2982  if ( ! plaintext ) {
2983  DBGC ( tls, "TLS %p could not allocate %zd bytes for "
2984  "plaintext\n", tls, plaintext_len );
2986  goto err_plaintext;
2987  }
2988 
2989  /* Assemble plaintext */
2990  tmp = plaintext;
2991  memcpy ( tmp, data, len );
2992  tmp += len;
2993  if ( suite->mac_len )
2994  tls_hmac ( cipherspec, &authhdr, data, len, mac );
2995  memcpy ( tmp, mac, suite->mac_len );
2996  tmp += suite->mac_len;
2997  memset ( tmp, ( padding_len - 1 ), padding_len );
2998  tmp += padding_len;
2999  assert ( tmp == ( plaintext + plaintext_len ) );
3000  DBGC2 ( tls, "Sending plaintext data:\n" );
3001  DBGC2_HD ( tls, plaintext, plaintext_len );
3002 
3003  /* Set initialisation vector */
3004  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv, sizeof ( iv ) );
3005 
3006  /* Process authentication data, if applicable */
3007  if ( is_auth_cipher ( cipher ) ) {
3008  cipher_encrypt ( cipher, cipherspec->cipher_ctx, &authhdr,
3009  NULL, sizeof ( authhdr ) );
3010  }
3011 
3012  /* Allocate ciphertext */
3013  ciphertext_len = ( sizeof ( *tlshdr ) + sizeof ( iv.record ) +
3014  plaintext_len + cipher->authsize );
3015  ciphertext = xfer_alloc_iob ( &tls->cipherstream, ciphertext_len );
3016  if ( ! ciphertext ) {
3017  DBGC ( tls, "TLS %p could not allocate %zd bytes for "
3018  "ciphertext\n", tls, ciphertext_len );
3020  goto err_ciphertext;
3021  }
3022 
3023  /* Assemble ciphertext */
3024  tlshdr = iob_put ( ciphertext, sizeof ( *tlshdr ) );
3025  tlshdr->type = type;
3026  tlshdr->version = htons ( tls->version );
3027  tlshdr->length = htons ( ciphertext_len - sizeof ( *tlshdr ) );
3028  memcpy ( iob_put ( ciphertext, sizeof ( iv.record ) ), iv.record,
3029  sizeof ( iv.record ) );
3030  cipher_encrypt ( cipher, cipherspec->cipher_ctx, plaintext,
3031  iob_put ( ciphertext, plaintext_len ), plaintext_len );
3032  cipher_auth ( cipher, cipherspec->cipher_ctx,
3033  iob_put ( ciphertext, cipher->authsize ) );
3034  assert ( iob_len ( ciphertext ) == ciphertext_len );
3035 
3036  /* Free plaintext as soon as possible to conserve memory */
3037  free ( plaintext );
3038  plaintext = NULL;
3039 
3040  /* Send ciphertext */
3041  if ( ( rc = xfer_deliver_iob ( &tls->cipherstream,
3042  iob_disown ( ciphertext ) ) ) != 0 ) {
3043  DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
3044  tls, strerror ( rc ) );
3045  goto err_deliver;
3046  }
3047 
3048  /* Update TX state machine to next record */
3049  tls->tx_seq += 1;
3050 
3051  assert ( plaintext == NULL );
3052  assert ( ciphertext == NULL );
3053  return 0;
3054 
3055  err_deliver:
3056  free_iob ( ciphertext );
3057  err_ciphertext:
3058  free ( plaintext );
3059  err_plaintext:
3060  err_random:
3061  return rc;
3062 }
#define __attribute__(x)
Definition: compiler.h:10
size_t blocksize
Block size.
Definition: crypto.h:59
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:120
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:255
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:205
uint8_t type
Content type.
Definition: tls.h:33
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:40
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition: eltorito.h:13
TLS authentication header.
Definition: tls.h:142
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:238
unsigned long tmp
Definition: linux_pci.h:53
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:248
size_t authsize
Authentication tag size.
Definition: crypto.h:73
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:369
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:246
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:195
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:203
A TLS cipher suite.
Definition: tls.h:187
#define ENOMEM_TX_CIPHERTEXT
Definition: tls.c:133
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:364
#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:155
uint8_t mac_len
MAC length.
Definition: tls.h:207
unsigned char uint8_t
Definition: stdint.h:10
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
A TLS header.
Definition: tls.h:28
#define ENOMEM_TX_PLAINTEXT
Definition: tls.c:129
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:2893
uint32_t len
Length.
Definition: ena.h:14
uint32_t type
Operating system type.
Definition: ena.h:12
static void const void * iv
Definition: crypto.h:238
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:25
uint16_t version
Protocol version.
Definition: tls.h:38
A message digest algorithm.
Definition: crypto.h:17
uint16_t version
Protocol version.
Definition: tls.h:367
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define cpu_to_be64(value)
Definition: byteswap.h:111
A cipher algorithm.
Definition: crypto.h:49
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:193
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:453
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:250
uint64_t tx_seq
TX sequence number.
Definition: tls.h:414
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33

References __attribute__, assert(), cipher_algorithm::authsize, cipher_algorithm::blocksize, tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_encrypt, tls_connection::cipherstream, cpu_to_be64, data, DBGC, DBGC2, DBGC2_HD, tls_cipher_suite::digest, digest, digest_algorithm::digestsize, ENOMEM_TX_CIPHERTEXT, ENOMEM_TX_PLAINTEXT, fixed, tls_cipherspec::fixed_iv, tls_cipher_suite::fixed_iv_len, free, free_iob(), tls_auth_header::header, htons, iob_disown, iob_len(), iob_put, iv, len, tls_header::length, mac, tls_cipher_suite::mac_len, malloc(), memcpy(), memset(), NULL, rc, tls_cipher_suite::record_iv_len, tls_auth_header::seq, strerror(), tls_cipherspec::suite, tls_generate_random(), tls_hmac(), tmp, tls_connection::tx_cipherspec, tls_connection::tx_seq, type, tls_header::type, tls_header::version, tls_connection::version, xfer_alloc_iob(), and xfer_deliver_iob().

Referenced by tls_plainstream_deliver(), 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_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 230 of file tls.c.

230  {
231 
232  return ( ( field24->high << 16 ) | be16_to_cpu ( field24->low ) );
233 }
#define be16_to_cpu(value)
Definition: byteswap.h:115
uint16_t low
Low word.
Definition: tls.c:219
uint8_t high
High byte.
Definition: tls.c:217

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

241  {
242 
243  field24->high = ( value >> 16 );
244  field24->low = cpu_to_be16 ( value );
245 }
#define cpu_to_be16(value)
Definition: byteswap.h:109
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
uint16_t low
Low word.
Definition: tls.c:219
uint8_t high
High byte.
Definition: tls.c:217

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

253  {
254  return ( ( ! is_pending ( &tls->client_negotiation ) ) &&
255  ( ! is_pending ( &tls->server_negotiation ) ) );
256 }
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:407
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:409

References tls_connection::client_negotiation, is_pending(), and tls_connection::server_negotiation.

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

270  {
271  return ( ( TLS_VERSION_MIN >= version ) ||
272  ( tls->version >= version ) );
273 }
u32 version
Driver version.
Definition: ath9k_hw.c:1983
uint16_t version
Protocol version.
Definition: tls.h:367
#define TLS_VERSION_MIN
Minimum TLS version.
Definition: crypto.h:13

References TLS_VERSION_MIN, tls_connection::version, and version.

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

◆ md5_sha1_init()

static void md5_sha1_init ( void *  ctx)
static

Initialise MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context

Definition at line 287 of file tls.c.

287  {
288  struct md5_sha1_context *context = ctx;
289 
290  digest_init ( &md5_algorithm, context->md5 );
291  digest_init ( &sha1_algorithm, context->sha1 );
292 }
An MD5+SHA1 context.
Definition: tls.h:293
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:297
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:295
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257

References ctx, 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 301 of file tls.c.

301  {
302  struct md5_sha1_context *context = ctx;
303 
304  digest_update ( &md5_algorithm, context->md5, data, len );
305  digest_update ( &sha1_algorithm, context->sha1, data, len );
306 }
An MD5+SHA1 context.
Definition: tls.h:293
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint32_t len
Length.
Definition: ena.h:14
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:297
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:295
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257

References ctx, data, 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 314 of file tls.c.

314  {
315  struct md5_sha1_context *context = ctx;
316  struct md5_sha1_digest *digest = out;
317 
318  digest_final ( &md5_algorithm, context->md5, digest->md5 );
319  digest_final ( &sha1_algorithm, context->sha1, digest->sha1 );
320 }
An MD5+SHA1 context.
Definition: tls.h:293
__be32 out[4]
Definition: CIB_PRM.h:36
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
An MD5+SHA1 digest.
Definition: tls.h:304
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:297
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:295
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257

References ctx, digest, md5_sha1_context::md5, md5_algorithm, out, md5_sha1_context::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 352 of file tls.c.

352  {
353  struct tls_session *session =
354  container_of ( refcnt, struct tls_session, refcnt );
355 
356  /* Sanity check */
357  assert ( list_empty ( &session->conn ) );
358 
359  /* Remove from list of sessions */
360  list_del ( &session->list );
361 
362  /* Free dynamically-allocated resources */
363  x509_root_put ( session->root );
364  privkey_put ( session->key );
365  free ( session->ticket );
366 
367  /* Free session */
368  free ( session );
369 }
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition: privkey.h:41
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition: x509.h:395
A reference counter.
Definition: refcnt.h:26
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct ntlm_data session
Session key.
Definition: ntlm.h:24
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
A TLS session.
Definition: tls.h:315

References assert(), container_of, free, list_del, list_empty, privkey_put(), session, 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 376 of file tls.c.

376  {
377  struct tls_connection *tls =
379  struct tls_session *session = tls->session;
380  struct io_buffer *iobuf;
381  struct io_buffer *tmp;
382 
383  /* Free dynamically-allocated resources */
384  free ( tls->new_session_ticket );
385  tls_clear_cipher ( tls, &tls->tx_cipherspec );
387  tls_clear_cipher ( tls, &tls->rx_cipherspec );
389  free ( tls->server_key );
390  free ( tls->handshake_ctx );
391  list_for_each_entry_safe ( iobuf, tmp, &tls->rx_data, list ) {
392  list_del ( &iobuf->list );
393  free_iob ( iobuf );
394  }
395  free_iob ( tls->rx_handshake );
396  x509_chain_put ( tls->certs );
397  x509_chain_put ( tls->chain );
398  x509_root_put ( tls->root );
399  privkey_put ( tls->key );
400 
401  /* Drop reference to session */
402  assert ( list_empty ( &tls->list ) );
403  ref_put ( &session->refcnt );
404 
405  /* Free TLS structure itself */
406  free ( tls );
407 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:291
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:402
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition: privkey.h:41
struct tls_session * session
Session.
Definition: tls.h:349
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition: x509.h:395
struct x509_root * root
Root of trust.
Definition: tls.h:400
A reference counter.
Definition: refcnt.h:26
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:53
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:389
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:369
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct ntlm_data session
Session key.
Definition: ntlm.h:24
void * new_session_ticket
New session ticket.
Definition: tls.h:357
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:393
struct list_head list
List of connections within the same session.
Definition: tls.h:351
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * server_key
Server Key Exchange record (if any)
Definition: tls.h:383
struct private_key * key
Private key.
Definition: tls.h:391
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:373
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
struct list_head rx_data
List of received data buffers.
Definition: tls.h:429
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
A TLS session.
Definition: tls.h:315
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:375
struct io_buffer * rx_handshake
Received handshake fragment.
Definition: tls.h:431
A TLS connection.
Definition: tls.h:344
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
A persistent I/O buffer.
Definition: iobuf.h:33

References assert(), tls_connection::certs, tls_connection::chain, container_of, free, free_iob(), tls_connection::handshake_ctx, tls_connection::key, io_buffer::list, tls_connection::list, list_del, list_empty, list_for_each_entry_safe, tls_connection::new_session_ticket, privkey_put(), ref_put, tls_connection::root, tls_connection::rx_cipherspec, tls_connection::rx_cipherspec_pending, tls_connection::rx_data, tls_connection::rx_handshake, tls_connection::server_key, session, tls_connection::session, tls_clear_cipher(), tmp, tls_connection::tx_cipherspec, tls_connection::tx_cipherspec_pending, 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 415 of file tls.c.

415  {
416 
417  /* Remove pending operations, if applicable */
420  pending_put ( &tls->validation );
421 
422  /* Remove process */
423  process_del ( &tls->process );
424 
425  /* Close all interfaces */
426  intf_shutdown ( &tls->cipherstream, rc );
427  intf_shutdown ( &tls->plainstream, rc );
428  intf_shutdown ( &tls->validator, rc );
429 
430  /* Remove from session */
431  list_del ( &tls->list );
432  INIT_LIST_HEAD ( &tls->list );
433 
434  /* Resume all other connections, in case we were the lead connection */
435  tls_tx_resume_all ( tls->session );
436 }
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:1099
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:407
struct process process
TX process.
Definition: tls.h:418
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:278
struct tls_session * session
Session.
Definition: tls.h:349
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:411
struct list_head list
List of connections within the same session.
Definition: tls.h:351
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:364
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:409
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
struct interface validator
Certificate validator.
Definition: tls.h:404
struct interface plainstream
Plaintext stream.
Definition: tls.h:362

References tls_connection::cipherstream, tls_connection::client_negotiation, INIT_LIST_HEAD, intf_shutdown(), tls_connection::list, list_del, pending_put(), tls_connection::plainstream, tls_connection::process, process_del(), rc, tls_connection::server_negotiation, tls_connection::session, tls_tx_resume_all(), tls_connection::validation, and tls_connection::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 453 of file tls.c.

454  {
455  int rc;
456 
457  /* Generate random bits with no additional input and without
458  * prediction resistance
459  */
460  if ( ( rc = rbg_generate ( NULL, 0, 0, data, len ) ) != 0 ) {
461  DBGC ( tls, "TLS %p could not generate random data: %s\n",
462  tls, strerror ( rc ) );
463  return rc;
464  }
465 
466  return 0;
467 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
Definition: rbg.h:36
#define DBGC(...)
Definition: compiler.h:505
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

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

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

477  {
478  void *data;
479  size_t len;
480 
481  while ( ( data = va_arg ( args, void * ) ) ) {
482  len = va_arg ( args, size_t );
483  hmac_update ( digest, ctx, data, len );
484  }
485 }
#define va_arg(ap, type)
Definition: stdarg.h:8
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References ctx, data, digest, 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 498 of file tls.c.

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

References a, ctx, DBGC2, DBGC2_HD, digest, digest_algorithm::digestsize, 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 560 of file tls.c.

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

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

◆ tls_generate_master_secret()

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

Generate master secret.

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

The client and server random values must already be known.

Definition at line 636 of file tls.c.

638  {
639 
640  DBGC ( tls, "TLS %p pre-master-secret:\n", tls );
641  DBGC_HD ( tls, pre_master_secret, pre_master_secret_len );
642  DBGC ( tls, "TLS %p client random bytes:\n", tls );
643  DBGC_HD ( tls, &tls->client_random, sizeof ( tls->client_random ) );
644  DBGC ( tls, "TLS %p server random bytes:\n", tls );
645  DBGC_HD ( tls, &tls->server_random, sizeof ( tls->server_random ) );
646 
647  tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
648  &tls->master_secret, sizeof ( tls->master_secret ),
649  "master secret",
650  &tls->client_random, sizeof ( tls->client_random ),
651  &tls->server_random, sizeof ( tls->server_random ) );
652 
653  DBGC ( tls, "TLS %p generated master secret:\n", tls );
654  DBGC_HD ( tls, &tls->master_secret, sizeof ( tls->master_secret ) );
655 }
#define DBGC(...)
Definition: compiler.h:505
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:379
uint8_t master_secret[48]
Master secret.
Definition: tls.h:377
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:381
#define DBGC_HD(...)
Definition: compiler.h:507
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:616

References tls_connection::client_random, DBGC, DBGC_HD, tls_connection::master_secret, tls_connection::server_random, and tls_prf_label.

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

664  {
665  struct tls_cipherspec *tx_cipherspec = &tls->tx_cipherspec_pending;
666  struct tls_cipherspec *rx_cipherspec = &tls->rx_cipherspec_pending;
667  size_t hash_size = tx_cipherspec->suite->mac_len;
668  size_t key_size = tx_cipherspec->suite->key_len;
669  size_t iv_size = tx_cipherspec->suite->fixed_iv_len;
670  size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
671  uint8_t key_block[total];
672  uint8_t *key;
673  int rc;
674 
675  /* Generate key block */
676  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
677  key_block, sizeof ( key_block ), "key expansion",
678  &tls->server_random, sizeof ( tls->server_random ),
679  &tls->client_random, sizeof ( tls->client_random ) );
680 
681  /* Split key block into portions */
682  key = key_block;
683 
684  /* TX MAC secret */
685  memcpy ( tx_cipherspec->mac_secret, key, hash_size );
686  DBGC ( tls, "TLS %p TX MAC secret:\n", tls );
687  DBGC_HD ( tls, key, hash_size );
688  key += hash_size;
689 
690  /* RX MAC secret */
691  memcpy ( rx_cipherspec->mac_secret, key, hash_size );
692  DBGC ( tls, "TLS %p RX MAC secret:\n", tls );
693  DBGC_HD ( tls, key, hash_size );
694  key += hash_size;
695 
696  /* TX key */
697  if ( ( rc = cipher_setkey ( tx_cipherspec->suite->cipher,
698  tx_cipherspec->cipher_ctx,
699  key, key_size ) ) != 0 ) {
700  DBGC ( tls, "TLS %p could not set TX key: %s\n",
701  tls, strerror ( rc ) );
702  return rc;
703  }
704  DBGC ( tls, "TLS %p TX key:\n", tls );
705  DBGC_HD ( tls, key, key_size );
706  key += key_size;
707 
708  /* RX key */
709  if ( ( rc = cipher_setkey ( rx_cipherspec->suite->cipher,
710  rx_cipherspec->cipher_ctx,
711  key, key_size ) ) != 0 ) {
712  DBGC ( tls, "TLS %p could not set TX key: %s\n",
713  tls, strerror ( rc ) );
714  return rc;
715  }
716  DBGC ( tls, "TLS %p RX key:\n", tls );
717  DBGC_HD ( tls, key, key_size );
718  key += key_size;
719 
720  /* TX initialisation vector */
721  memcpy ( tx_cipherspec->fixed_iv, key, iv_size );
722  DBGC ( tls, "TLS %p TX IV:\n", tls );
723  DBGC_HD ( tls, key, iv_size );
724  key += iv_size;
725 
726  /* RX initialisation vector */
727  memcpy ( rx_cipherspec->fixed_iv, key, iv_size );
728  DBGC ( tls, "TLS %p RX IV:\n", tls );
729  DBGC_HD ( tls, key, iv_size );
730  key += iv_size;
731 
732  assert ( ( key_block + total ) == key );
733 
734  return 0;
735 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:379
A TLS cipher specification.
Definition: tls.h:238
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:246
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:203
uint8_t master_secret[48]
Master secret.
Definition: tls.h:377
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:381
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC_HD(...)
Definition: compiler.h:507
uint8_t mac_len
MAC length.
Definition: tls.h:207
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:375
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:193
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:616
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:250
union @382 key
Sense key.
Definition: crypto.h:284
void * mac_secret
MAC secret.
Definition: tls.h:248
uint8_t key_len
Key length.
Definition: tls.h:201

References assert(), tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, tls_connection::client_random, 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(), rc, tls_connection::rx_cipherspec_pending, tls_connection::server_random, strerror(), tls_cipherspec::suite, tls_prf_label, and tls_connection::tx_cipherspec_pending.

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

749  {
750 
751  /* Select null digest algorithm */
753 
754  /* Free any existing context */
755  free ( tls->handshake_ctx );
756  tls->handshake_ctx = NULL;
757 }
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:389
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct digest_algorithm digest_null
Definition: crypto_null.c:48
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:387
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by add_tls(), and tls_select_handshake().

◆ tls_select_handshake()

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

Select handshake digest algorithm.

Parameters
tlsTLS connection
digestHandshake digest algorithm
Return values
rcReturn status code

Definition at line 766 of file tls.c.

767  {
768 
769  /* Clear existing handshake digest */
770  tls_clear_handshake ( tls );
771 
772  /* Allocate and initialise context */
773  tls->handshake_ctx = malloc ( digest->ctxsize );
774  if ( ! tls->handshake_ctx )
775  return -ENOMEM;
776  tls->handshake_digest = digest;
777  digest_init ( digest, tls->handshake_ctx );
778 
779  return 0;
780 }
#define ENOMEM
Not enough space.
Definition: errno.h:534
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:389
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:387
size_t ctxsize
Context size.
Definition: crypto.h:21
static void tls_clear_handshake(struct tls_connection *tls)
Clear handshake digest algorithm.
Definition: tls.c:749

References digest_algorithm::ctxsize, digest, 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 790 of file tls.c.

791  {
793 
794  digest_update ( digest, tls->handshake_ctx, data, len );
795  return 0;
796 }
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:389
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:387
uint32_t len
Length.
Definition: ena.h:14
A message digest algorithm.
Definition: crypto.h:17
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References data, digest, tls_connection::handshake_ctx, tls_connection::handshake_digest, and len.

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

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

806  {
809 
810  memcpy ( ctx, tls->handshake_ctx, sizeof ( ctx ) );
811  digest_final ( digest, ctx, out );
812 }
__be32 out[4]
Definition: CIB_PRM.h:36
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:389
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
unsigned char uint8_t
Definition: stdint.h:10
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:387
size_t ctxsize
Context size.
Definition: crypto.h:21
A message digest algorithm.
Definition: crypto.h:17

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

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

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

839  {
840  struct tls_cipher_suite *suite;
841 
842  /* Identify cipher suite */
844  if ( suite->code == cipher_suite )
845  return suite;
846  }
847 
848  return NULL;
849 }
A TLS cipher suite.
Definition: tls.h:187
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:211
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:199

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

857  {
858 
859  if ( cipherspec->suite ) {
860  pubkey_final ( cipherspec->suite->pubkey,
861  cipherspec->pubkey_ctx );
862  }
863  free ( cipherspec->dynamic );
864  memset ( cipherspec, 0, sizeof ( *cipherspec ) );
865  cipherspec->suite = &tls_cipher_suite_null;
866 }
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:822
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:191
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:244
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:242
void * memset(void *dest, int character, size_t len) __nonnull

References tls_cipherspec::dynamic, free, memset(), tls_cipher_suite::pubkey, tls_cipherspec::pubkey_ctx, 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 876 of file tls.c.

878  {
879  struct pubkey_algorithm *pubkey = suite->pubkey;
880  struct cipher_algorithm *cipher = suite->cipher;
881  size_t total;
882  void *dynamic;
883 
884  /* Clear out old cipher contents, if any */
885  tls_clear_cipher ( tls, cipherspec );
886 
887  /* Allocate dynamic storage */
888  total = ( pubkey->ctxsize + cipher->ctxsize + suite->mac_len +
889  suite->fixed_iv_len );
890  dynamic = zalloc ( total );
891  if ( ! dynamic ) {
892  DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto "
893  "context\n", tls, total );
894  return -ENOMEM_CONTEXT;
895  }
896 
897  /* Assign storage */
898  cipherspec->dynamic = dynamic;
899  cipherspec->pubkey_ctx = dynamic; dynamic += pubkey->ctxsize;
900  cipherspec->cipher_ctx = dynamic; dynamic += cipher->ctxsize;
901  cipherspec->mac_secret = dynamic; dynamic += suite->mac_len;
902  cipherspec->fixed_iv = dynamic; dynamic += suite->fixed_iv_len;
903  assert ( ( cipherspec->dynamic + total ) == dynamic );
904 
905  /* Store parameters */
906  cipherspec->suite = suite;
907 
908  return 0;
909 }
#define DBGC(...)
Definition: compiler.h:505
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:191
size_t ctxsize
Context size.
Definition: crypto.h:124
#define ENOMEM_CONTEXT
Definition: tls.c:117
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:246
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:203
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
uint8_t mac_len
MAC length.
Definition: tls.h:207
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:244
size_t ctxsize
Context size.
Definition: crypto.h:53
A cipher algorithm.
Definition: crypto.h:49
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:193
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:242
A public key algorithm.
Definition: crypto.h:120
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:250
void * mac_secret
MAC secret.
Definition: tls.h:248

References assert(), tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_algorithm::ctxsize, pubkey_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_cipher_suite::pubkey, tls_cipherspec::pubkey_ctx, 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 918 of file tls.c.

919  {
920  struct tls_cipher_suite *suite;
921  struct digest_algorithm *digest;
922  int rc;
923 
924  /* Identify cipher suite */
925  suite = tls_find_cipher_suite ( cipher_suite );
926  if ( ! suite ) {
927  DBGC ( tls, "TLS %p does not support cipher %04x\n",
928  tls, ntohs ( cipher_suite ) );
929  return -ENOTSUP_CIPHER;
930  }
931 
932  /* Set handshake digest algorithm */
933  digest = ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ?
934  suite->handshake : &md5_sha1_algorithm );
935  if ( ( rc = tls_select_handshake ( tls, digest ) ) != 0 )
936  return rc;
937 
938  /* Set ciphers */
939  if ( ( rc = tls_set_cipher ( tls, &tls->tx_cipherspec_pending,
940  suite ) ) != 0 )
941  return rc;
942  if ( ( rc = tls_set_cipher ( tls, &tls->rx_cipherspec_pending,
943  suite ) ) != 0 )
944  return rc;
945 
946  DBGC ( tls, "TLS %p selected %s-%s-%s-%d-%s\n", tls,
947  suite->exchange->name, suite->pubkey->name,
948  suite->cipher->name, ( suite->key_len * 8 ),
949  suite->digest->name );
950 
951  return 0;
952 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:189
static struct tls_cipher_suite * tls_find_cipher_suite(unsigned int cipher_suite)
Identify cipher suite.
Definition: tls.c:839
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
#define ntohs(value)
Definition: byteswap.h:136
const char * name
Algorithm name.
Definition: tls.h:176
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:191
#define ENOTSUP_CIPHER
Definition: tls.c:145
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:195
A TLS cipher suite.
Definition: tls.h:187
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:323
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:270
const char * name
Algorithm name.
Definition: crypto.h:19
struct digest_algorithm * handshake
Handshake digest algorithm (for TLSv1.2 and above)
Definition: tls.h:197
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:375
A message digest algorithm.
Definition: crypto.h:17
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:193
const char * name
Algorithm name.
Definition: crypto.h:51
static int tls_set_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
Set cipher suite.
Definition: tls.c:876
static int tls_select_handshake(struct tls_connection *tls, struct digest_algorithm *digest)
Select handshake digest algorithm.
Definition: tls.c:766
const char * name
Algorithm name.
Definition: crypto.h:122
uint8_t key_len
Key length.
Definition: tls.h:201

References tls_cipher_suite::cipher, DBGC, tls_cipher_suite::digest, 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_cipher_suite::pubkey, rc, tls_connection::rx_cipherspec_pending, tls_find_cipher_suite(), tls_select_handshake(), tls_set_cipher(), tls_version(), TLS_VERSION_TLS_1_2, and tls_connection::tx_cipherspec_pending.

Referenced by tls_new_server_hello().

◆ tls_change_cipher()

static int tls_change_cipher ( struct tls_connection tls,
struct tls_cipherspec pending,
struct tls_cipherspec active 
)
static

Activate next cipher suite.

Parameters
tlsTLS connection
pendingPending cipher specification
activeActive cipher specification to replace
Return values
rcReturn status code

Definition at line 962 of file tls.c.

964  {
965 
966  /* Sanity check */
967  if ( pending->suite == &tls_cipher_suite_null ) {
968  DBGC ( tls, "TLS %p refusing to use null cipher\n", tls );
969  return -ENOTSUP_NULL;
970  }
971 
972  tls_clear_cipher ( tls, active );
973  memswap ( active, pending, sizeof ( *active ) );
974  return 0;
975 }
void * memswap(void *first, void *second, size_t len)
Swap memory regions.
Definition: string.c:153
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:822
#define DBGC(...)
Definition: compiler.h:505
uint32_t pending
Pending events.
Definition: hyperv.h:12
#define ENOTSUP_NULL
Definition: tls.c:149
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)

References DBGC, ENOTSUP_NULL, memswap(), pending, 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 996 of file tls.c.

997  {
998  struct tls_signature_hash_algorithm *sig_hash;
999 
1000  /* Identify signature and hash algorithm */
1002  if ( ( sig_hash->pubkey == pubkey ) &&
1003  ( sig_hash->digest == digest ) ) {
1004  return sig_hash;
1005  }
1006  }
1007 
1008  return NULL;
1009 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:264
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
A TLS signature algorithm.
Definition: tls.h:262
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:276
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:266
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References tls_signature_hash_algorithm::digest, 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 1018 of file tls.c.

1018  {
1019  struct tls_signature_hash_algorithm *sig_hash;
1020 
1021  /* Identify signature and hash algorithm */
1023  if ( sig_hash->code.signature == code.signature )
1024  return sig_hash->pubkey;
1025  }
1026 
1027  return NULL;
1028 }
A TLS signature algorithm.
Definition: tls.h:262
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
uint8_t signature
Signature algorithm.
Definition: tls.h:258
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:276
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:268
uint8_t code
Response code.
Definition: scsi.h:16
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:266
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_verify_dh_params().

◆ tls_signature_hash_digest()

static struct digest_algorithm* tls_signature_hash_digest ( struct tls_signature_hash_id  code)
static

Find TLS hash algorithm.

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

Definition at line 1037 of file tls.c.

1037  {
1038  struct tls_signature_hash_algorithm *sig_hash;
1039 
1040  /* Identify signature and hash algorithm */
1042  if ( sig_hash->code.hash == code.hash )
1043  return sig_hash->digest;
1044  }
1045 
1046  return NULL;
1047 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:264
A TLS signature algorithm.
Definition: tls.h:262
uint8_t hash
Hash algorithm.
Definition: tls.h:256
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:276
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:268
uint8_t code
Response code.
Definition: scsi.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_verify_dh_params().

◆ tls_find_named_curve()

static struct tls_named_curve* tls_find_named_curve ( unsigned int  named_curve)
static

Identify named curve.

Parameters
named_curveNamed curve specification
Return values
curveNamed curve, or NULL

Definition at line 1066 of file tls.c.

1066  {
1067  struct tls_named_curve *curve;
1068 
1069  /* Identify named curve */
1071  if ( curve->code == named_curve )
1072  return curve;
1073  }
1074 
1075  return NULL;
1076 }
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:230
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:224
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
A TLS named curve.
Definition: tls.h:222
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_send_client_key_exchange_ecdhe().

◆ tls_tx_resume()

static void tls_tx_resume ( struct tls_connection tls)
static

Resume TX state machine.

Parameters
tlsTLS connection

Definition at line 1090 of file tls.c.

1090  {
1091  process_add ( &tls->process );
1092 }
struct process process
TX process.
Definition: tls.h:418
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59

References tls_connection::process, and process_add().

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

1111  {
1112 
1113  /* Sanity check */
1114  assert ( ! tls->tx_pending );
1115  assert ( ! is_pending ( &tls->client_negotiation ) );
1116  assert ( ! is_pending ( &tls->server_negotiation ) );
1117  assert ( ! is_pending ( &tls->validation ) );
1118 
1119  /* (Re)start negotiation */
1121  tls_tx_resume ( tls );
1122  pending_get ( &tls->client_negotiation );
1123  pending_get ( &tls->server_negotiation );
1124 }
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:407
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1090
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:411
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:409
unsigned int tx_pending
TX pending transmissions.
Definition: tls.h:416
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45

References assert(), tls_connection::client_negotiation, is_pending(), pending_get(), tls_connection::server_negotiation, TLS_TX_CLIENT_HELLO, tls_tx_resume(), tls_connection::tx_pending, and tls_connection::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 1134 of file tls.c.

1135  {
1136 
1137  /* Add to handshake digest */
1138  tls_add_handshake ( tls, data, len );
1139 
1140  /* Send record */
1141  return tls_send_plaintext ( tls, TLS_TYPE_HANDSHAKE, data, len );
1142 }
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:790
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:2936
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:62
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

Referenced by tls_send_certificate(), 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 1151 of file tls.c.

1154  {
1155  struct tls_session *session = tls->session;
1156  size_t name_len = strlen ( session->name );
1157  struct {
1158  uint16_t type;
1159  uint16_t len;
1160  struct {
1161  uint16_t len;
1162  struct {
1163  uint8_t type;
1164  uint16_t len;
1165  uint8_t name[name_len];
1166  } __attribute__ (( packed )) list[1];
1167  } __attribute__ (( packed )) data;
1168  } __attribute__ (( packed )) *server_name_ext;
1169  struct {
1170  uint16_t type;
1171  uint16_t len;
1172  struct {
1173  uint8_t max;
1174  } __attribute__ (( packed )) data;
1175  } __attribute__ (( packed )) *max_fragment_length_ext;
1176  struct {
1177  uint16_t type;
1178  uint16_t len;
1179  struct {
1180  uint16_t len;
1181  struct tls_signature_hash_id
1183  } __attribute__ (( packed )) data;
1184  } __attribute__ (( packed )) *signature_algorithms_ext;
1185  struct {
1186  uint16_t type;
1187  uint16_t len;
1188  struct {
1189  uint8_t len;
1191  sizeof ( tls->verify.client ) :0 ];
1192  } __attribute__ (( packed )) data;
1193  } __attribute__ (( packed )) *renegotiation_info_ext;
1194  struct {
1195  uint16_t type;
1196  uint16_t len;
1197  struct {
1198  uint8_t data[session->ticket_len];
1199  } __attribute__ (( packed )) data;
1200  } __attribute__ (( packed )) *session_ticket_ext;
1201  struct {
1202  uint16_t type;
1203  uint16_t len;
1204  struct {
1205  uint16_t len;
1207  } __attribute__ (( packed )) data;
1208  } __attribute__ (( packed )) *named_curve_ext;
1209  struct {
1210  typeof ( *server_name_ext ) server_name;
1211  typeof ( *max_fragment_length_ext ) max_fragment_length;
1212  typeof ( *signature_algorithms_ext ) signature_algorithms;
1213  typeof ( *renegotiation_info_ext ) renegotiation_info;
1214  typeof ( *session_ticket_ext ) session_ticket;
1215  typeof ( *named_curve_ext )
1216  named_curve[TLS_NUM_NAMED_CURVES ? 1 : 0];
1217  } __attribute__ (( packed )) *extensions;
1218  struct {
1219  uint32_t type_length;
1220  uint16_t version;
1221  uint8_t random[32];
1222  uint8_t session_id_len;
1223  uint8_t session_id[tls->session_id_len];
1224  uint16_t cipher_suite_len;
1225  uint16_t cipher_suites[TLS_NUM_CIPHER_SUITES];
1226  uint8_t compression_methods_len;
1227  uint8_t compression_methods[1];
1228  uint16_t extensions_len;
1229  typeof ( *extensions ) extensions;
1230  } __attribute__ (( packed )) hello;
1231  struct tls_cipher_suite *suite;
1232  struct tls_signature_hash_algorithm *sighash;
1233  struct tls_named_curve *curve;
1234  unsigned int i;
1235 
1236  /* Construct record */
1237  memset ( &hello, 0, sizeof ( hello ) );
1238  hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) |
1239  htonl ( sizeof ( hello ) -
1240  sizeof ( hello.type_length ) ) );
1241  hello.version = htons ( TLS_VERSION_MAX );
1242  memcpy ( &hello.random, &tls->client_random, sizeof ( hello.random ) );
1243  hello.session_id_len = tls->session_id_len;
1244  memcpy ( hello.session_id, tls->session_id,
1245  sizeof ( hello.session_id ) );
1246  hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) );
1247  i = 0 ; for_each_table_entry ( suite, TLS_CIPHER_SUITES )
1248  hello.cipher_suites[i++] = suite->code;
1249  hello.compression_methods_len = sizeof ( hello.compression_methods );
1250  hello.extensions_len = htons ( sizeof ( hello.extensions ) );
1251  extensions = &hello.extensions;
1252 
1253  /* Construct server name extension */
1254  server_name_ext = &extensions->server_name;
1255  server_name_ext->type = htons ( TLS_SERVER_NAME );
1256  server_name_ext->len = htons ( sizeof ( server_name_ext->data ) );
1257  server_name_ext->data.len
1258  = htons ( sizeof ( server_name_ext->data.list ) );
1259  server_name_ext->data.list[0].type = TLS_SERVER_NAME_HOST_NAME;
1260  server_name_ext->data.list[0].len
1261  = htons ( sizeof ( server_name_ext->data.list[0].name ) );
1262  memcpy ( server_name_ext->data.list[0].name, session->name,
1263  sizeof ( server_name_ext->data.list[0].name ) );
1264 
1265  /* Construct maximum fragment length extension */
1266  max_fragment_length_ext = &extensions->max_fragment_length;
1267  max_fragment_length_ext->type = htons ( TLS_MAX_FRAGMENT_LENGTH );
1268  max_fragment_length_ext->len
1269  = htons ( sizeof ( max_fragment_length_ext->data ) );
1270  max_fragment_length_ext->data.max = TLS_MAX_FRAGMENT_LENGTH_4096;
1271 
1272  /* Construct supported signature algorithms extension */
1273  signature_algorithms_ext = &extensions->signature_algorithms;
1274  signature_algorithms_ext->type = htons ( TLS_SIGNATURE_ALGORITHMS );
1275  signature_algorithms_ext->len
1276  = htons ( sizeof ( signature_algorithms_ext->data ) );
1277  signature_algorithms_ext->data.len
1278  = htons ( sizeof ( signature_algorithms_ext->data.code ) );
1279  i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
1280  signature_algorithms_ext->data.code[i++] = sighash->code;
1281 
1282  /* Construct renegotiation information extension */
1283  renegotiation_info_ext = &extensions->renegotiation_info;
1284  renegotiation_info_ext->type = htons ( TLS_RENEGOTIATION_INFO );
1285  renegotiation_info_ext->len
1286  = htons ( sizeof ( renegotiation_info_ext->data ) );
1287  renegotiation_info_ext->data.len
1288  = sizeof ( renegotiation_info_ext->data.data );
1289  memcpy ( renegotiation_info_ext->data.data, tls->verify.client,
1290  sizeof ( renegotiation_info_ext->data.data ) );
1291 
1292  /* Construct session ticket extension */
1293  session_ticket_ext = &extensions->session_ticket;
1294  session_ticket_ext->type = htons ( TLS_SESSION_TICKET );
1295  session_ticket_ext->len
1296  = htons ( sizeof ( session_ticket_ext->data ) );
1297  memcpy ( session_ticket_ext->data.data, session->ticket,
1298  sizeof ( session_ticket_ext->data.data ) );
1299 
1300  /* Construct named curves extension, if applicable */
1301  if ( sizeof ( extensions->named_curve ) ) {
1302  named_curve_ext = &extensions->named_curve[0];
1303  named_curve_ext->type = htons ( TLS_NAMED_CURVE );
1304  named_curve_ext->len
1305  = htons ( sizeof ( named_curve_ext->data ) );
1306  named_curve_ext->data.len
1307  = htons ( sizeof ( named_curve_ext->data.code ) );
1309  named_curve_ext->data.code[i++] = curve->code;
1310  }
1311 
1312  return action ( tls, &hello, sizeof ( hello ) );
1313 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:397
#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:830
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:139
#define max(x, y)
Definition: ath.h:39
struct tls_session * session
Session.
Definition: tls.h:349
#define TLS_NUM_NAMED_CURVES
Number of supported named curves.
Definition: tls.c:1057
#define TLS_CLIENT_HELLO
Definition: tls.h:69
uint8_t session_id[32]
Session ID.
Definition: tls.h:353
#define htonl(value)
Definition: byteswap.h:133
#define TLS_MAX_FRAGMENT_LENGTH
Definition: tls.h:122
#define TLS_NAMED_CURVE
Definition: tls.h:129
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct ntlm_data session
Session key.
Definition: ntlm.h:24
#define TLS_SESSION_TICKET
Definition: tls.h:136
A TLS cipher suite.
Definition: tls.h:187
#define TLS_SERVER_NAME
Definition: tls.h:118
A TLS signature algorithm.
Definition: tls.h:262
struct list_head list
List of sessions.
Definition: tls.h:319
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:230
#define TLS_NUM_SIG_HASH_ALGORITHMS
Number of supported signature and hash algorithms.
Definition: tls.c:985
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:381
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:224
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:276
uint16_t hello
Hello time.
Definition: stp.h:38
unsigned int uint32_t
Definition: stdint.h:12
u32 version
Driver version.
Definition: ath9k_hw.c:1983
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:268
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
#define TLS_SERVER_NAME_HOST_NAME
Definition: tls.h:119
uint8_t client[12]
Client verification data.
Definition: tls.h:152
uint8_t code
Response code.
Definition: scsi.h:16
uint32_t len
Length.
Definition: ena.h:14
A TLS session.
Definition: tls.h:315
uint32_t type
Operating system type.
Definition: ena.h:12
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:395
A TLS named curve.
Definition: tls.h:222
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
#define TLS_MAX_FRAGMENT_LENGTH_4096
Definition: tls.h:126
const char * name
Server name.
Definition: tls.h:322
A TLS signature and hash algorithm identifier.
Definition: tls.h:254
size_t session_id_len
Length of session ID.
Definition: tls.h:355
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:211
#define htons(value)
Definition: byteswap.h:135
#define TLS_SIGNATURE_ALGORITHMS
Definition: tls.h:133
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:199
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, tls_verify_data::client, tls_connection::client_random, 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_connection::secure_renegotiation, session, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, strlen(), TLS_CIPHER_SUITES, TLS_CLIENT_HELLO, TLS_MAX_FRAGMENT_LENGTH, TLS_MAX_FRAGMENT_LENGTH_4096, 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 1321 of file tls.c.

1321  {
1322 
1323  return tls_client_hello ( tls, tls_send_handshake );
1324 }
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1134
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:1151

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

1332  {
1333  struct {
1334  tls24_t length;
1335  uint8_t data[0];
1336  } __attribute__ (( packed )) *certificate;
1337  struct {
1338  uint32_t type_length;
1339  tls24_t length;
1340  typeof ( *certificate ) certificates[0];
1341  } __attribute__ (( packed )) *certificates;
1342  struct x509_link *link;
1343  struct x509_certificate *cert;
1344  size_t len;
1345  int rc;
1346 
1347  /* Calculate length of client certificates */
1348  len = 0;
1349  list_for_each_entry ( link, &tls->certs->links, list ) {
1350  cert = link->cert;
1351  len += ( sizeof ( *certificate ) + cert->raw.len );
1352  DBGC ( tls, "TLS %p sending client certificate %s\n",
1353  tls, x509_name ( cert ) );
1354  }
1355 
1356  /* Allocate storage for Certificate record (which may be too
1357  * large for the stack).
1358  */
1359  certificates = zalloc ( sizeof ( *certificates ) + len );
1360  if ( ! certificates )
1361  return -ENOMEM_CERTIFICATE;
1362 
1363  /* Populate record */
1364  certificates->type_length =
1366  htonl ( sizeof ( *certificates ) + len -
1367  sizeof ( certificates->type_length ) ) );
1368  tls_set_uint24 ( &certificates->length, len );
1369  certificate = &certificates->certificates[0];
1370  list_for_each_entry ( link, &tls->certs->links, list ) {
1371  cert = link->cert;
1372  tls_set_uint24 ( &certificate->length, cert->raw.len );
1373  memcpy ( certificate->data, cert->raw.data, cert->raw.len );
1374  certificate = ( ( ( void * ) certificate->data ) +
1375  cert->raw.len );
1376  }
1377 
1378  /* Transmit record */
1379  rc = tls_send_handshake ( tls, certificates,
1380  ( sizeof ( *certificates ) + len ) );
1381 
1382  /* Free record */
1383  free ( certificates );
1384 
1385  return rc;
1386 }
#define __attribute__(x)
Definition: compiler.h:10
u16 length
Definition: sky2.h:9
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head links
List of links.
Definition: x509.h:203
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:72
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1134
size_t len
Length of data.
Definition: asn1.h:24
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:393
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
#define cpu_to_le32(value)
Definition: byteswap.h:107
An X.509 certificate.
Definition: x509.h:207
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
A TLS 24-bit integer.
Definition: tls.c:215
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:145
uint32_t len
Length.
Definition: ena.h:14
#define ENOMEM_CERTIFICATE
Definition: tls.c:121
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:241
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
struct asn1_cursor raw
Raw certificate.
Definition: x509.h:222

References __attribute__, tls_connection::certs, cpu_to_le32, asn1_cursor::data, data, DBGC, ENOMEM_CERTIFICATE, free, htonl, len, asn1_cursor::len, length, link, x509_chain::links, list_for_each_entry, memcpy(), x509_certificate::raw, rc, TLS_CERTIFICATE, tls_send_handshake(), tls_set_uint24(), typeof(), x509_name(), and zalloc().

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

1394  {
1395  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
1396  struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1397  size_t max_len = pubkey_max_len ( pubkey, cipherspec->pubkey_ctx );
1398  struct {
1399  uint16_t version;
1400  uint8_t random[46];
1401  } __attribute__ (( packed )) pre_master_secret;
1402  struct {
1403  uint32_t type_length;
1404  uint16_t encrypted_pre_master_secret_len;
1405  uint8_t encrypted_pre_master_secret[max_len];
1406  } __attribute__ (( packed )) key_xchg;
1407  size_t unused;
1408  int len;
1409  int rc;
1410 
1411  /* Generate pre-master secret */
1412  pre_master_secret.version = htons ( TLS_VERSION_MAX );
1413  if ( ( rc = tls_generate_random ( tls, &pre_master_secret.random,
1414  ( sizeof ( pre_master_secret.random ) ) ) ) != 0 ) {
1415  return rc;
1416  }
1417 
1418  /* Generate master secret */
1419  tls_generate_master_secret ( tls, &pre_master_secret,
1420  sizeof ( pre_master_secret ) );
1421 
1422  /* Encrypt pre-master secret using server's public key */
1423  memset ( &key_xchg, 0, sizeof ( key_xchg ) );
1424  len = pubkey_encrypt ( pubkey, cipherspec->pubkey_ctx,
1425  &pre_master_secret, sizeof ( pre_master_secret ),
1426  key_xchg.encrypted_pre_master_secret );
1427  if ( len < 0 ) {
1428  rc = len;
1429  DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
1430  tls, strerror ( rc ) );
1431  return rc;
1432  }
1433  unused = ( max_len - len );
1434  key_xchg.type_length =
1436  htonl ( sizeof ( key_xchg ) -
1437  sizeof ( key_xchg.type_length ) - unused ) );
1438  key_xchg.encrypted_pre_master_secret_len =
1439  htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) -
1440  unused );
1441 
1442  return tls_send_handshake ( tls, &key_xchg,
1443  ( sizeof ( key_xchg ) - unused ) );
1444 }
#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
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
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:636
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:238
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:191
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1134
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:244
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
u32 version
Driver version.
Definition: ath9k_hw.c:1983
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
uint32_t len
Length.
Definition: ena.h:14
uint8_t unused[32]
Unused.
Definition: eltorito.h:15
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:453
A public key algorithm.
Definition: crypto.h:120
#define htons(value)
Definition: byteswap.h:135
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:77
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, cpu_to_le32, DBGC, htonl, htons, len, max_len, memset(), tls_cipher_suite::pubkey, tls_cipherspec::pubkey_ctx, random(), rc, strerror(), tls_cipherspec::suite, TLS_CLIENT_KEY_EXCHANGE, tls_generate_master_secret(), tls_generate_random(), tls_send_handshake(), TLS_VERSION_MAX, tls_connection::tx_cipherspec_pending, unused, 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 1459 of file tls.c.

1460  {
1461  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
1462  struct pubkey_algorithm *pubkey;
1463  struct digest_algorithm *digest;
1464  int use_sig_hash = tls_version ( tls, TLS_VERSION_TLS_1_2 );
1465  const struct {
1466  struct tls_signature_hash_id sig_hash[use_sig_hash];
1468  uint8_t signature[0];
1469  } __attribute__ (( packed )) *sig;
1470  const void *data;
1471  size_t remaining;
1472  int rc;
1473 
1474  /* Signature follows parameters */
1475  assert ( param_len <= tls->server_key_len );
1476  data = ( tls->server_key + param_len );
1477  remaining = ( tls->server_key_len - param_len );
1478 
1479  /* Parse signature from ServerKeyExchange */
1480  sig = data;
1481  if ( ( sizeof ( *sig ) > remaining ) ||
1482  ( ntohs ( sig->signature_len ) > ( remaining -
1483  sizeof ( *sig ) ) ) ) {
1484  DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1485  tls );
1486  DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
1487  return -EINVAL_KEY_EXCHANGE;
1488  }
1489 
1490  /* Identify signature and hash algorithm */
1491  if ( use_sig_hash ) {
1492  pubkey = tls_signature_hash_pubkey ( sig->sig_hash[0] );
1493  digest = tls_signature_hash_digest ( sig->sig_hash[0] );
1494  if ( ( ! pubkey ) || ( ! digest ) ) {
1495  DBGC ( tls, "TLS %p ServerKeyExchange unsupported "
1496  "signature and hash algorithm\n", tls );
1497  return -ENOTSUP_SIG_HASH;
1498  }
1499  if ( pubkey != cipherspec->suite->pubkey ) {
1500  DBGC ( tls, "TLS %p ServerKeyExchange incorrect "
1501  "signature algorithm %s (expected %s)\n", tls,
1502  pubkey->name, cipherspec->suite->pubkey->name );
1503  return -EPERM_KEY_EXCHANGE;
1504  }
1505  } else {
1506  pubkey = cipherspec->suite->pubkey;
1508  }
1509 
1510  /* Verify signature */
1511  {
1512  const void *signature = sig->signature;
1513  size_t signature_len = ntohs ( sig->signature_len );
1516 
1517  /* Calculate digest */
1518  digest_init ( digest, ctx );
1519  digest_update ( digest, ctx, &tls->client_random,
1520  sizeof ( tls->client_random ) );
1521  digest_update ( digest, ctx, tls->server_random,
1522  sizeof ( tls->server_random ) );
1523  digest_update ( digest, ctx, tls->server_key, param_len );
1524  digest_final ( digest, ctx, hash );
1525 
1526  /* Verify signature */
1527  if ( ( rc = pubkey_verify ( pubkey, cipherspec->pubkey_ctx,
1528  digest, hash, signature,
1529  signature_len ) ) != 0 ) {
1530  DBGC ( tls, "TLS %p ServerKeyExchange failed "
1531  "verification\n", tls );
1532  DBGC_HDA ( tls, 0, tls->server_key,
1533  tls->server_key_len );
1534  return -EPERM_KEY_EXCHANGE;
1535  }
1536  }
1537 
1538  return 0;
1539 }
#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 pubkey_algorithm * tls_signature_hash_pubkey(struct tls_signature_hash_id code)
Find TLS signature algorithm.
Definition: tls.c:1018
u8 sig
Definition: CIB_PRM.h:43
#define EPERM_KEY_EXCHANGE
Definition: tls.c:185
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:379
static struct digest_algorithm * tls_signature_hash_digest(struct tls_signature_hash_id code)
Find TLS hash algorithm.
Definition: tls.c:1037
#define ntohs(value)
Definition: byteswap.h:136
A TLS cipher specification.
Definition: tls.h:238
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:191
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
#define DBGC_HDA(...)
Definition: compiler.h:506
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
static void struct digest_algorithm const void const void size_t signature_len
Definition: crypto.h:316
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:323
pseudo_bit_t hash[0x00010]
Hash algorithm.
Definition: arbel.h:13
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:381
void * server_key
Server Key Exchange record (if any)
Definition: tls.h:383
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:244
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:270
size_t ctxsize
Context size.
Definition: crypto.h:21
size_t digestsize
Digest size.
Definition: crypto.h:25
A message digest algorithm.
Definition: crypto.h:17
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:109
A TLS signature and hash algorithm identifier.
Definition: tls.h:254
#define ENOTSUP_SIG_HASH
Definition: tls.c:153
u8 signature
Signature.
Definition: CIB_PRM.h:35
A public key algorithm.
Definition: crypto.h:120
const char * name
Algorithm name.
Definition: crypto.h:122
size_t server_key_len
Server Key Exchange record length.
Definition: tls.h:385

References __attribute__, assert(), tls_connection::client_random, ctx, digest_algorithm::ctxsize, data, DBGC, DBGC_HDA, digest, digest_algorithm::digestsize, EINVAL_KEY_EXCHANGE, ENOTSUP_SIG_HASH, EPERM_KEY_EXCHANGE, hash, md5_sha1_algorithm, pubkey_algorithm::name, ntohs, tls_cipher_suite::pubkey, tls_cipherspec::pubkey_ctx, rc, tls_connection::server_key, tls_connection::server_key_len, tls_connection::server_random, sig, signature, signature_len, tls_cipherspec::suite, tls_signature_hash_digest(), tls_signature_hash_pubkey(), tls_version(), TLS_VERSION_TLS_1_2, and tls_connection::tx_cipherspec_pending.

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

1547  {
1548  uint8_t private[ sizeof ( tls->client_random.random ) ];
1549  const struct {
1550  uint16_t len;
1551  uint8_t data[0];
1552  } __attribute__ (( packed )) *dh_val[3];
1553  const void *data;
1554  size_t remaining;
1555  size_t frag_len;
1556  size_t param_len;
1557  unsigned int i;
1558  int rc;
1559 
1560  /* Parse ServerKeyExchange */
1561  data = tls->server_key;
1562  remaining = tls->server_key_len;
1563  for ( i = 0 ; i < ( sizeof ( dh_val ) / sizeof ( dh_val[0] ) ) ; i++ ){
1564  dh_val[i] = data;
1565  if ( ( sizeof ( *dh_val[i] ) > remaining ) ||
1566  ( ntohs ( dh_val[i]->len ) > ( remaining -
1567  sizeof ( *dh_val[i] ) ) )){
1568  DBGC ( tls, "TLS %p received underlength "
1569  "ServerKeyExchange\n", tls );
1570  DBGC_HDA ( tls, 0, tls->server_key,
1571  tls->server_key_len );
1573  goto err_header;
1574  }
1575  frag_len = ( sizeof ( *dh_val[i] ) + ntohs ( dh_val[i]->len ));
1576  data += frag_len;
1577  remaining -= frag_len;
1578  }
1579  param_len = ( tls->server_key_len - remaining );
1580 
1581  /* Verify parameter signature */
1582  if ( ( rc = tls_verify_dh_params ( tls, param_len ) ) != 0 )
1583  goto err_verify;
1584 
1585  /* Generate Diffie-Hellman private key */
1586  if ( ( rc = tls_generate_random ( tls, private,
1587  sizeof ( private ) ) ) != 0 ) {
1588  goto err_random;
1589  }
1590 
1591  /* Construct pre-master secret and ClientKeyExchange record */
1592  {
1593  typeof ( dh_val[0] ) dh_p = dh_val[0];
1594  typeof ( dh_val[1] ) dh_g = dh_val[1];
1595  typeof ( dh_val[2] ) dh_ys = dh_val[2];
1596  size_t len = ntohs ( dh_p->len );
1597  struct {
1598  uint32_t type_length;
1599  uint16_t dh_xs_len;
1600  uint8_t dh_xs[len];
1601  } __attribute__ (( packed )) *key_xchg;
1602  struct {
1603  uint8_t pre_master_secret[len];
1604  typeof ( *key_xchg ) key_xchg;
1605  } *dynamic;
1606  uint8_t *pre_master_secret;
1607 
1608  /* Allocate space */
1609  dynamic = malloc ( sizeof ( *dynamic ) );
1610  if ( ! dynamic ) {
1611  rc = -ENOMEM;
1612  goto err_alloc;
1613  }
1614  pre_master_secret = dynamic->pre_master_secret;
1615  key_xchg = &dynamic->key_xchg;
1616  key_xchg->type_length =
1618  htonl ( sizeof ( *key_xchg ) -
1619  sizeof ( key_xchg->type_length ) ) );
1620  key_xchg->dh_xs_len = htons ( len );
1621 
1622  /* Calculate pre-master secret and client public value */
1623  if ( ( rc = dhe_key ( dh_p->data, len,
1624  dh_g->data, ntohs ( dh_g->len ),
1625  dh_ys->data, ntohs ( dh_ys->len ),
1626  private, sizeof ( private ),
1627  key_xchg->dh_xs,
1628  pre_master_secret ) ) != 0 ) {
1629  DBGC ( tls, "TLS %p could not calculate DHE key: %s\n",
1630  tls, strerror ( rc ) );
1631  goto err_dhe_key;
1632  }
1633 
1634  /* Strip leading zeroes from pre-master secret */
1635  while ( len && ( ! *pre_master_secret ) ) {
1636  pre_master_secret++;
1637  len--;
1638  }
1639 
1640  /* Generate master secret */
1641  tls_generate_master_secret ( tls, pre_master_secret, len );
1642 
1643  /* Transmit Client Key Exchange record */
1644  if ( ( rc = tls_send_handshake ( tls, key_xchg,
1645  sizeof ( *key_xchg ) ) ) !=0){
1646  goto err_send_handshake;
1647  }
1648 
1649  err_send_handshake:
1650  err_dhe_key:
1651  free ( dynamic );
1652  }
1653  err_alloc:
1654  err_random:
1655  err_verify:
1656  err_header:
1657  return rc;
1658 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
int dhe_key(const void *modulus, size_t len, const void *generator, size_t generator_len, const void *partner, size_t partner_len, const void *private, size_t private_len, void *public, void *shared)
Calculate Diffie-Hellman key.
Definition: dhe.c:53
static void tls_generate_master_secret(struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
Generate master secret.
Definition: tls.c:636
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1134
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define DBGC_HDA(...)
Definition: compiler.h:506
#define cpu_to_le32(value)
Definition: byteswap.h:107
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:381
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * server_key
Server Key Exchange record (if any)
Definition: tls.h:383
static int tls_verify_dh_params(struct tls_connection *tls, size_t param_len)
Verify Diffie-Hellman parameter signature.
Definition: tls.c:1459
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:583
uint8_t random[28]
Random data.
Definition: tls.h:289
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:109
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:453
#define htons(value)
Definition: byteswap.h:135
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:77
size_t server_key_len
Server Key Exchange record length.
Definition: tls.h:385

References __attribute__, tls_connection::client_random, cpu_to_le32, data, DBGC, DBGC_HDA, dhe_key(), EINVAL_KEY_EXCHANGE, ENOMEM, free, htonl, htons, len, malloc(), ntohs, tls_client_random::random, rc, tls_connection::server_key, tls_connection::server_key_len, 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 1672 of file tls.c.

1672  {
1673  struct tls_named_curve *curve;
1674  const struct {
1675  uint8_t curve_type;
1676  uint16_t named_curve;
1677  uint8_t public_len;
1678  uint8_t public[0];
1679  } __attribute__ (( packed )) *ecdh;
1680  size_t param_len;
1681  int rc;
1682 
1683  /* Parse ServerKeyExchange record */
1684  ecdh = tls->server_key;
1685  if ( ( sizeof ( *ecdh ) > tls->server_key_len ) ||
1686  ( ecdh->public_len > ( tls->server_key_len - sizeof ( *ecdh ) ))){
1687  DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1688  tls );
1689  DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
1690  return -EINVAL_KEY_EXCHANGE;
1691  }
1692  param_len = ( sizeof ( *ecdh ) + ecdh->public_len );
1693 
1694  /* Verify parameter signature */
1695  if ( ( rc = tls_verify_dh_params ( tls, param_len ) ) != 0 )
1696  return rc;
1697 
1698  /* Identify named curve */
1699  if ( ecdh->curve_type != TLS_NAMED_CURVE_TYPE ) {
1700  DBGC ( tls, "TLS %p unsupported curve type %d\n",
1701  tls, ecdh->curve_type );
1702  DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
1703  return -ENOTSUP_CURVE;
1704  }
1705  curve = tls_find_named_curve ( ecdh->named_curve );
1706  if ( ! curve ) {
1707  DBGC ( tls, "TLS %p unsupported named curve %d\n",
1708  tls, ntohs ( ecdh->named_curve ) );
1709  DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
1710  return -ENOTSUP_CURVE;
1711  }
1712 
1713  /* Check key length */
1714  if ( ecdh->public_len != curve->curve->keysize ) {
1715  DBGC ( tls, "TLS %p invalid %s key\n",
1716  tls, curve->curve->name );
1717  DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
1718  return -EINVAL_KEY_EXCHANGE;
1719  }
1720 
1721  /* Construct pre-master secret and ClientKeyExchange record */
1722  {
1723  size_t len = curve->curve->keysize;
1724  uint8_t private[len];
1725  uint8_t pre_master_secret[len];
1726  struct {
1727  uint32_t type_length;
1728  uint8_t public_len;
1729  uint8_t public[len];
1730  } __attribute__ (( packed )) key_xchg;
1731 
1732  /* Generate ephemeral private key */
1733  if ( ( rc = tls_generate_random ( tls, private,
1734  sizeof ( private ) ) ) != 0){
1735  return rc;
1736  }
1737 
1738  /* Calculate pre-master secret */
1739  if ( ( rc = elliptic_multiply ( curve->curve,
1740  ecdh->public, private,
1741  pre_master_secret ) ) != 0 ) {
1742  DBGC ( tls, "TLS %p could not exchange ECDHE key: %s\n",
1743  tls, strerror ( rc ) );
1744  return rc;
1745  }
1746 
1747  /* Generate master secret */
1748  tls_generate_master_secret ( tls, pre_master_secret, len );
1749 
1750  /* Generate Client Key Exchange record */
1751  key_xchg.type_length =
1753  htonl ( sizeof ( key_xchg ) -
1754  sizeof ( key_xchg.type_length ) ) );
1755  key_xchg.public_len = len;
1756  if ( ( rc = elliptic_multiply ( curve->curve, NULL, private,
1757  key_xchg.public ) ) != 0 ) {
1758  DBGC ( tls, "TLS %p could not generate ECDHE key: %s\n",
1759  tls, strerror ( rc ) );
1760  return rc;
1761  }
1762 
1763  /* Transmit Client Key Exchange record */
1764  if ( ( rc = tls_send_handshake ( tls, &key_xchg,
1765  sizeof ( key_xchg ) ) ) !=0){
1766  return rc;
1767  }
1768  }
1769 
1770  return 0;
1771 }
#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:1066
#define ENOTSUP_CURVE
Definition: tls.c:161
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:636
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1134
#define TLS_NAMED_CURVE_TYPE
TLS named curved type.
Definition: tls.h:219
#define DBGC_HDA(...)
Definition: compiler.h:506
const char * name
Curve name.
Definition: crypto.h:201
#define cpu_to_le32(value)
Definition: byteswap.h:107
size_t keysize
Key size.
Definition: crypto.h:203
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * server_key
Server Key Exchange record (if any)
Definition: tls.h:383
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:224
static int tls_verify_dh_params(struct tls_connection *tls, size_t param_len)
Verify Diffie-Hellman parameter signature.
Definition: tls.c:1459
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
uint32_t len
Length.
Definition: ena.h:14
A TLS named curve.
Definition: tls.h:222
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:109
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:453
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:77
size_t server_key_len
Server Key Exchange record length.
Definition: tls.h:385

References __attribute__, cpu_to_le32, tls_named_curve::curve, DBGC, DBGC_HDA, EINVAL_KEY_EXCHANGE, ENOTSUP_CURVE, htonl, elliptic_curve::keysize, len, elliptic_curve::name, ntohs, NULL, rc, tls_connection::server_key, tls_connection::server_key_len, 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 1785 of file tls.c.

1785  {
1786  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
1787  struct tls_cipher_suite *suite = cipherspec->suite;
1788  int rc;
1789 
1790  /* Transmit Client Key Exchange record via key exchange algorithm */
1791  if ( ( rc = suite->exchange->exchange ( tls ) ) != 0 ) {
1792  DBGC ( tls, "TLS %p could not exchange keys: %s\n",
1793  tls, strerror ( rc ) );
1794  return rc;
1795  }
1796 
1797  /* Generate keys from master secret */
1798  if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
1799  DBGC ( tls, "TLS %p could not generate keys: %s\n",
1800  tls, strerror ( rc ) );
1801  return rc;
1802  }
1803 
1804  return 0;
1805 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:189
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:238
int(* exchange)(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition: tls.h:183
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
A TLS cipher suite.
Definition: tls.h:187
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:664

References DBGC, tls_key_exchange_algorithm::exchange, tls_cipher_suite::exchange, rc, strerror(), tls_cipherspec::suite, tls_generate_keys(), and tls_connection::tx_cipherspec_pending.

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

1813  {
1814  struct digest_algorithm *digest = tls->handshake_digest;
1815  struct x509_certificate *cert = x509_first ( tls->certs );
1816  struct pubkey_algorithm *pubkey = cert->signature_algorithm->pubkey;
1817  struct asn1_cursor *key = privkey_cursor ( tls->key );
1818  uint8_t digest_out[ digest->digestsize ];
1819  uint8_t ctx[ pubkey->ctxsize ];
1820  struct tls_signature_hash_algorithm *sig_hash = NULL;
1821  int rc;
1822 
1823  /* Generate digest to be signed */
1824  tls_verify_handshake ( tls, digest_out );
1825 
1826  /* Initialise public-key algorithm */
1827  if ( ( rc = pubkey_init ( pubkey, ctx, key->data, key->len ) ) != 0 ) {
1828  DBGC ( tls, "TLS %p could not initialise %s client private "
1829  "key: %s\n", tls, pubkey->name, strerror ( rc ) );
1830  goto err_pubkey_init;
1831  }
1832 
1833  /* TLSv1.2 and later use explicit algorithm identifiers */
1834  if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
1835  sig_hash = tls_signature_hash_algorithm ( pubkey, digest );
1836  if ( ! sig_hash ) {
1837  DBGC ( tls, "TLS %p could not identify (%s,%s) "
1838  "signature and hash algorithm\n", tls,
1839  pubkey->name, digest->name );
1840  rc = -ENOTSUP_SIG_HASH;
1841  goto err_sig_hash;
1842  }
1843  }
1844 
1845  /* Generate and transmit record */
1846  {
1847  size_t max_len = pubkey_max_len ( pubkey, ctx );
1848  int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
1849  struct {
1850  uint32_t type_length;
1851  struct tls_signature_hash_id sig_hash[use_sig_hash];
1854  } __attribute__ (( packed )) certificate_verify;
1855  size_t unused;
1856  int len;
1857 
1858  /* Sign digest */
1859  len = pubkey_sign ( pubkey, ctx, digest, digest_out,
1860  certificate_verify.signature );
1861  if ( len < 0 ) {
1862  rc = len;
1863  DBGC ( tls, "TLS %p could not sign %s digest using %s "
1864  "client private key: %s\n", tls, digest->name,
1865  pubkey->name, strerror ( rc ) );
1866  goto err_pubkey_sign;
1867  }
1868  unused = ( max_len - len );
1869 
1870  /* Construct Certificate Verify record */
1871  certificate_verify.type_length =
1873  htonl ( sizeof ( certificate_verify ) -
1874  sizeof ( certificate_verify.type_length ) -
1875  unused ) );
1876  if ( use_sig_hash ) {
1877  memcpy ( &certificate_verify.sig_hash[0],
1878  &sig_hash->code,
1879  sizeof ( certificate_verify.sig_hash[0] ) );
1880  }
1881  certificate_verify.signature_len =
1882  htons ( sizeof ( certificate_verify.signature ) -
1883  unused );
1884 
1885  /* Transmit record */
1886  rc = tls_send_handshake ( tls, &certificate_verify,
1887  ( sizeof ( certificate_verify ) - unused ) );
1888  }
1889 
1890  err_pubkey_sign:
1891  err_sig_hash:
1892  pubkey_final ( pubkey, ctx );
1893  err_pubkey_init:
1894  return rc;
1895 }
#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 void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:806
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
struct asn1_algorithm * signature_algorithm
Signature algorithm.
Definition: x509.h:230
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
#define htonl(value)
Definition: byteswap.h:133
size_t ctxsize
Context size.
Definition: crypto.h:124
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1134
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition: privkey.h:52
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:317
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:996
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:393
A TLS signature algorithm.
Definition: tls.h:262
static void struct digest_algorithm const void const void size_t signature_len
Definition: crypto.h:316
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:207
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
unsigned char uint8_t
Definition: stdint.h:10
struct private_key * key
Private key.
Definition: tls.h:391
unsigned int uint32_t
Definition: stdint.h:12
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:268
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:270
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:387
uint32_t len
Length.
Definition: ena.h:14
uint8_t unused[32]
Unused.
Definition: eltorito.h:15
size_t digestsize
Digest size.
Definition: crypto.h:25
const char * name
Algorithm name.
Definition: crypto.h:19
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:302
A message digest algorithm.
Definition: crypto.h:17
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:266
A TLS signature and hash algorithm identifier.
Definition: tls.h:254
#define TLS_CERTIFICATE_VERIFY
Definition: tls.h:76
#define ENOTSUP_SIG_HASH
Definition: tls.c:153
u8 signature
Signature.
Definition: CIB_PRM.h:35
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
An ASN.1 object cursor.
Definition: asn1.h:20
A public key algorithm.
Definition: crypto.h:120
#define htons(value)
Definition: byteswap.h:135
union @382 key
Sense key.
Definition: crypto.h:284
const char * name
Algorithm name.
Definition: crypto.h:122

References __attribute__, tls_connection::certs, tls_signature_hash_algorithm::code, cpu_to_le32, ctx, pubkey_algorithm::ctxsize, DBGC, digest, digest_algorithm::digestsize, ENOTSUP_SIG_HASH, tls_connection::handshake_digest, htonl, htons, key, tls_connection::key, len, max_len, memcpy(), digest_algorithm::name, pubkey_algorithm::name, NULL, privkey_cursor(), tls_signature_hash_algorithm::pubkey, asn1_algorithm::pubkey, rc, signature, x509_certificate::signature_algorithm, signature_len, strerror(), TLS_CERTIFICATE_VERIFY, tls_send_handshake(), tls_signature_hash_algorithm(), tls_verify_handshake(), tls_version(), TLS_VERSION_TLS_1_2, unused, 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 1903 of file tls.c.

1903  {
1904  static const struct {
1905  uint8_t spec;
1906  } __attribute__ (( packed )) change_cipher = {
1907  .spec = TLS_CHANGE_CIPHER_SPEC,
1908  };
1909 
1911  &change_cipher, sizeof ( change_cipher ) );
1912 }
#define __attribute__(x)
Definition: compiler.h:10
uint16_t spec
ENA specification version.
Definition: ena.h:26
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
Definition: tls.h:53
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:2936
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_CHANGE_CIPHER_SPEC
Change cipher spec magic byte.
Definition: tls.h:56

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

Referenced by tls_tx_step().

◆ tls_send_finished()

static int tls_send_finished ( struct tls_connection tls)
static

Transmit Finished record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1920 of file tls.c.

1920  {
1921  struct digest_algorithm *digest = tls->handshake_digest;
1922  struct {
1923  uint32_t type_length;
1924  uint8_t verify_data[ sizeof ( tls->verify.client ) ];
1925  } __attribute__ (( packed )) finished;
1926  uint8_t digest_out[ digest->digestsize ];
1927  int rc;
1928 
1929  /* Construct client verification data */
1930  tls_verify_handshake ( tls, digest_out );
1931  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
1932  tls->verify.client, sizeof ( tls->verify.client ),
1933  "client finished", digest_out, sizeof ( digest_out ) );
1934 
1935  /* Construct record */
1936  memset ( &finished, 0, sizeof ( finished ) );
1937  finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
1938  htonl ( sizeof ( finished ) -
1939  sizeof ( finished.type_length ) ) );
1940  memcpy ( finished.verify_data, tls->verify.client,
1941  sizeof ( finished.verify_data ) );
1942 
1943  /* Transmit record */
1944  if ( ( rc = tls_send_handshake ( tls, &finished,
1945  sizeof ( finished ) ) ) != 0 )
1946  return rc;
1947 
1948  /* Mark client as finished */
1949  pending_put ( &tls->client_negotiation );
1950 
1951  return 0;
1952 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:397
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:407
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:806
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1134
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
uint8_t master_secret[48]
Master secret.
Definition: tls.h:377
#define cpu_to_le32(value)
Definition: byteswap.h:107
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
uint8_t client[12]
Client verification data.
Definition: tls.h:152
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:387
size_t digestsize
Digest size.
Definition: crypto.h:25
A message digest algorithm.
Definition: crypto.h:17
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:616
#define TLS_FINISHED
Definition: tls.h:78
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, tls_verify_data::client, tls_connection::client_negotiation, cpu_to_le32, digest, digest_algorithm::digestsize, tls_connection::handshake_digest, htonl, tls_connection::master_secret, memcpy(), memset(), 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 1961 of file tls.c.

1962  {
1963  const struct {
1964  uint8_t spec;
1965  } __attribute__ (( packed )) *change_cipher = iobuf->data;
1966  size_t len = iob_len ( iobuf );
1967  int rc;
1968 
1969  /* Sanity check */
1970  if ( ( sizeof ( *change_cipher ) != len ) ||
1971  ( change_cipher->spec != TLS_CHANGE_CIPHER_SPEC ) ) {
1972  DBGC ( tls, "TLS %p received invalid Change Cipher\n", tls );
1973  DBGC_HD ( tls, change_cipher, len );
1974  return -EINVAL_CHANGE_CIPHER;
1975  }
1976  iob_pull ( iobuf, sizeof ( *change_cipher ) );
1977 
1978  /* Change receive cipher spec */
1979  if ( ( rc = tls_change_cipher ( tls, &tls->rx_cipherspec_pending,
1980  &tls->rx_cipherspec ) ) != 0 ) {
1981  DBGC ( tls, "TLS %p could not activate RX cipher: %s\n",
1982  tls, strerror ( rc ) );
1983  return rc;
1984  }
1985  tls->rx_seq = ~( ( uint64_t ) 0 );
1986 
1987  return 0;
1988 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t spec
ENA specification version.
Definition: ena.h:26
uint64_t rx_seq
RX sequence number.
Definition: tls.h:421
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
#define EINVAL_CHANGE_CIPHER
Definition: tls.c:57
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec *pending, struct tls_cipherspec *active)
Activate next cipher suite.
Definition: tls.c:962
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:373
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:48
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:375
#define TLS_CHANGE_CIPHER_SPEC
Change cipher spec magic byte.
Definition: tls.h:56

References __attribute__, io_buffer::data, DBGC, DBGC_HD, EINVAL_CHANGE_CIPHER, iob_len(), iob_pull, len, rc, tls_connection::rx_cipherspec, tls_connection::rx_cipherspec_pending, tls_connection::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 1997 of file tls.c.

1998  {
1999  const struct {
2000  uint8_t level;
2001  uint8_t description;
2002  char next[0];
2003  } __attribute__ (( packed )) *alert = iobuf->data;
2004  size_t len = iob_len ( iobuf );
2005 
2006  /* Sanity check */
2007  if ( sizeof ( *alert ) != len ) {
2008  DBGC ( tls, "TLS %p received overlength Alert\n", tls );
2009  DBGC_HD ( tls, alert, len );
2010  return -EINVAL_ALERT;
2011  }
2012  iob_pull ( iobuf, sizeof ( *alert ) );
2013 
2014  /* Handle alert */
2015  switch ( alert->level ) {
2016  case TLS_ALERT_WARNING:
2017  DBGC ( tls, "TLS %p received warning alert %d\n",
2018  tls, alert->description );
2019  return 0;
2020  case TLS_ALERT_FATAL:
2021  DBGC ( tls, "TLS %p received fatal alert %d\n",
2022  tls, alert->description );
2023  return -EPERM_ALERT;
2024  default:
2025  DBGC ( tls, "TLS %p received unknown alert level %d"
2026  "(alert %d)\n", tls, alert->level, alert->description );
2027  return -EIO_ALERT;
2028  }
2029 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#define __attribute__(x)
Definition: compiler.h:10
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
#define EIO_ALERT
Definition: tls.c:113
#define TLS_ALERT_WARNING
Definition: tls.h:81
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define EINVAL_ALERT
Definition: tls.c:61
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_ALERT_FATAL
Definition: tls.h:82
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:48
static void alert(const char *fmt,...)
Print alert message.
Definition: settings_ui.c:327
#define EPERM_ALERT
Definition: tls.c:165

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

2041  {
2042 
2043  /* Ignore if a handshake is in progress */
2044  if ( ! tls_ready ( tls ) ) {
2045  DBGC ( tls, "TLS %p ignoring Hello Request\n", tls );
2046  return 0;
2047  }
2048 
2049  /* Fail unless server supports secure renegotiation */
2050  if ( ! tls->secure_renegotiation ) {
2051  DBGC ( tls, "TLS %p refusing to renegotiate insecurely\n",
2052  tls );
2053  return -EPERM_RENEG_INSECURE;
2054  }
2055 
2056  /* Restart negotiation */
2057  tls_restart ( tls );
2058 
2059  return 0;
2060 }
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition: tls.c:1111
#define DBGC(...)
Definition: compiler.h:505
#define EPERM_RENEG_INSECURE
Definition: tls.c:177
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:395
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:253

References DBGC, EPERM_RENEG_INSECURE, 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 2070 of file tls.c.

2071  {
2072  const struct {
2073  uint16_t version;
2074  uint8_t random[32];
2075  uint8_t session_id_len;
2076  uint8_t session_id[0];
2077  } __attribute__ (( packed )) *hello_a = data;
2078  const uint8_t *session_id;
2079  const struct {
2080  uint16_t cipher_suite;
2081  uint8_t compression_method;
2082  char next[0];
2083  } __attribute__ (( packed )) *hello_b;
2084  const struct {
2085  uint16_t len;
2086  uint8_t data[0];
2087  } __attribute__ (( packed )) *exts;
2088  const struct {
2089  uint16_t type;
2090  uint16_t len;
2091  uint8_t data[0];
2092  } __attribute__ (( packed )) *ext;
2093  const struct {
2094  uint8_t len;
2095  uint8_t data[0];
2096  } __attribute__ (( packed )) *reneg = NULL;
2097  uint16_t version;
2098  size_t exts_len;
2099  size_t ext_len;
2100  size_t remaining;
2101  int rc;
2102 
2103  /* Parse header */
2104  if ( ( sizeof ( *hello_a ) > len ) ||
2105  ( hello_a->session_id_len > ( len - sizeof ( *hello_a ) ) ) ||
2106  ( sizeof ( *hello_b ) > ( len - sizeof ( *hello_a ) -
2107  hello_a->session_id_len ) ) ) {
2108  DBGC ( tls, "TLS %p received underlength Server Hello\n", tls );
2109  DBGC_HD ( tls, data, len );
2110  return -EINVAL_HELLO;
2111  }
2112  session_id = hello_a->session_id;
2113  hello_b = ( ( void * ) ( session_id + hello_a->session_id_len ) );
2114 
2115  /* Parse extensions, if present */
2116  remaining = ( len - sizeof ( *hello_a ) - hello_a->session_id_len -
2117  sizeof ( *hello_b ) );
2118  if ( remaining ) {
2119 
2120  /* Parse extensions length */
2121  exts = ( ( void * ) hello_b->next );
2122  if ( ( sizeof ( *exts ) > remaining ) ||
2123  ( ( exts_len = ntohs ( exts->len ) ) >
2124  ( remaining - sizeof ( *exts ) ) ) ) {
2125  DBGC ( tls, "TLS %p received underlength extensions\n",
2126  tls );
2127  DBGC_HD ( tls, data, len );
2128  return -EINVAL_HELLO;
2129  }
2130 
2131  /* Parse extensions */
2132  for ( ext = ( ( void * ) exts->data ), remaining = exts_len ;
2133  remaining ;
2134  ext = ( ( ( void * ) ext ) + sizeof ( *ext ) + ext_len ),
2135  remaining -= ( sizeof ( *ext ) + ext_len ) ) {
2136 
2137  /* Parse extension length */
2138  if ( ( sizeof ( *ext ) > remaining ) ||
2139  ( ( ext_len = ntohs ( ext->len ) ) >
2140  ( remaining - sizeof ( *ext ) ) ) ) {
2141  DBGC ( tls, "TLS %p received underlength "
2142  "extension\n", tls );
2143  DBGC_HD ( tls, data, len );
2144  return -EINVAL_HELLO;
2145  }
2146 
2147  /* Record known extensions */
2148  switch ( ext->type ) {
2149  case htons ( TLS_RENEGOTIATION_INFO ) :
2150  reneg = ( ( void * ) ext->data );
2151  if ( ( sizeof ( *reneg ) > ext_len ) ||
2152  ( reneg->len >
2153  ( ext_len - sizeof ( *reneg ) ) ) ) {
2154  DBGC ( tls, "TLS %p received "
2155  "underlength renegotiation "
2156  "info\n", tls );
2157  DBGC_HD ( tls, data, len );
2158  return -EINVAL_HELLO;
2159  }
2160  break;
2161  }
2162  }
2163  }
2164 
2165  /* Check and store protocol version */
2166  version = ntohs ( hello_a->version );
2167  if ( version < TLS_VERSION_MIN ) {
2168  DBGC ( tls, "TLS %p does not support protocol version %d.%d\n",
2169  tls, ( version >> 8 ), ( version & 0xff ) );
2170  return -ENOTSUP_VERSION;
2171  }
2172  if ( version > tls->version ) {
2173  DBGC ( tls, "TLS %p server attempted to illegally upgrade to "
2174  "protocol version %d.%d\n",
2175  tls, ( version >> 8 ), ( version & 0xff ) );
2176  return -EPROTO_VERSION;
2177  }
2178  tls->version = version;
2179  DBGC ( tls, "TLS %p using protocol version %d.%d\n",
2180  tls, ( version >> 8 ), ( version & 0xff ) );
2181 
2182  /* Select cipher suite */
2183  if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 )
2184  return rc;
2185 
2186  /* Add preceding Client Hello to handshake digest */
2187  if ( ( rc = tls_client_hello ( tls, tls_add_handshake ) ) != 0 )
2188  return rc;
2189 
2190  /* Copy out server random bytes */
2191  memcpy ( &tls->server_random, &hello_a->random,
2192  sizeof ( tls->server_random ) );
2193 
2194  /* Check session ID */
2195  if ( hello_a->session_id_len &&
2196  ( hello_a->session_id_len == tls->session_id_len ) &&
2197  ( memcmp ( session_id, tls->session_id,
2198  tls->session_id_len ) == 0 ) ) {
2199 
2200  /* Session ID match: reuse master secret */
2201  DBGC ( tls, "TLS %p resuming session ID:\n", tls );
2202  DBGC_HDA ( tls, 0, tls->session_id, tls->session_id_len );
2203  if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
2204  return rc;
2205 
2206  } else {
2207 
2208  /* Record new session ID, if present */
2209  if ( hello_a->session_id_len &&
2210  ( hello_a->session_id_len <= sizeof ( tls->session_id ))){
2211  tls->session_id_len = hello_a->session_id_len;
2212  memcpy ( tls->session_id, session_id,
2213  tls->session_id_len );
2214  DBGC ( tls, "TLS %p new session ID:\n", tls );
2215  DBGC_HDA ( tls, 0, tls->session_id,
2216  tls->session_id_len );
2217  }
2218  }
2219 
2220  /* Handle secure renegotiation */
2221  if ( tls->secure_renegotiation ) {
2222 
2223  /* Secure renegotiation is expected; verify data */
2224  if ( ( reneg == NULL ) ||
2225  ( reneg->len != sizeof ( tls->verify ) ) ||
2226  ( memcmp ( reneg->data, &tls->verify,
2227  sizeof ( tls->verify ) ) != 0 ) ) {
2228  DBGC ( tls, "TLS %p server failed secure "
2229  "renegotiation\n", tls );
2230  return -EPERM_RENEG_VERIFY;
2231  }
2232 
2233  } else if ( reneg != NULL ) {
2234 
2235  /* Secure renegotiation is being enabled */
2236  if ( reneg->len != 0 ) {
2237  DBGC ( tls, "TLS %p server provided non-empty initial "
2238  "renegotiation\n", tls );
2239  return -EPERM_RENEG_VERIFY;
2240  }
2241  tls->secure_renegotiation = 1;
2242  }
2243 
2244  return 0;
2245 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:397
#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 int tls_select_cipher(struct tls_connection *tls, unsigned int cipher_suite)
Select next cipher suite.
Definition: tls.c:918
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:139
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define EINVAL_HELLO
Definition: tls.c:65
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:790
#define ENOTSUP_VERSION
Definition: tls.c:157
#define DBGC(...)
Definition: compiler.h:505
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:379
uint8_t session_id[32]
Session ID.
Definition: tls.h:353
#define EPROTO_VERSION
Definition: tls.c:189
#define ntohs(value)
Definition: byteswap.h:136
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
#define DBGC_HD(...)
Definition: compiler.h:507
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
unsigned char uint8_t
Definition: stdint.h:10
#define EPERM_RENEG_VERIFY
Definition: tls.c:181
u32 version
Driver version.
Definition: ath9k_hw.c:1983
uint16_t ext
Extended status.
Definition: ena.h:20
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:664
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:1151
uint32_t len
Length.
Definition: ena.h:14
uint32_t type
Operating system type.
Definition: ena.h:12
uint16_t version
Protocol version.
Definition: tls.h:367
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:395
size_t session_id_len
Length of session ID.
Definition: tls.h:355
#define TLS_VERSION_MIN
Minimum TLS version.
Definition: crypto.h:13
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135

References __attribute__, data, DBGC, DBGC_HD, DBGC_HDA, EINVAL_HELLO, ENOTSUP_VERSION, EPERM_RENEG_VERIFY, EPROTO_VERSION, ext, htons, len, memcmp(), memcpy(), next, ntohs, NULL, random(), rc, tls_connection::secure_renegotiation, tls_connection::server_random, tls_connection::session_id, tls_connection::session_id_len, tls_add_handshake(), tls_client_hello(), 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 2255 of file tls.c.

2256  {
2257  const struct {
2259  uint16_t len;
2260  uint8_t ticket[0];
2261  } __attribute__ (( packed )) *new_session_ticket = data;
2262  size_t ticket_len;
2263 
2264  /* Parse header */
2265  if ( sizeof ( *new_session_ticket ) > len ) {
2266  DBGC ( tls, "TLS %p received underlength New Session Ticket\n",
2267  tls );
2268  DBGC_HD ( tls, data, len );
2269  return -EINVAL_TICKET;
2270  }
2271  ticket_len = ntohs ( new_session_ticket->len );
2272  if ( ticket_len > ( len - sizeof ( *new_session_ticket ) ) ) {
2273  DBGC ( tls, "TLS %p received overlength New Session Ticket\n",
2274  tls );
2275  DBGC_HD ( tls, data, len );
2276  return -EINVAL_TICKET;
2277  }
2278 
2279  /* Free any unapplied new session ticket */
2280  free ( tls->new_session_ticket );
2281  tls->new_session_ticket = NULL;
2282  tls->new_session_ticket_len = 0;
2283 
2284  /* Record ticket */
2285  tls->new_session_ticket = malloc ( ticket_len );
2286  if ( ! tls->new_session_ticket )
2287  return -ENOMEM;
2288  memcpy ( tls->new_session_ticket, new_session_ticket->ticket,
2289  ticket_len );
2290  tls->new_session_ticket_len = ticket_len;
2291  DBGC ( tls, "TLS %p new session ticket:\n", tls );
2292  DBGC_HDA ( tls, 0, tls->new_session_ticket,
2293  tls->new_session_ticket_len );
2294 
2295  return 0;
2296 }
#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:359
#define ntohs(value)
Definition: byteswap.h:136
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * new_session_ticket
New session ticket.
Definition: tls.h:357
#define DBGC_HDA(...)
Definition: compiler.h:506
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
Definition: wpa.h:54
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_TICKET
Definition: tls.c:105
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_new_handshake().

◆ tls_parse_chain()

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

Parse certificate chain.

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

Definition at line 2306 of file tls.c.

2307  {
2308  size_t remaining = len;
2309  int rc;
2310 
2311  /* Free any existing certificate chain */
2312  x509_chain_put ( tls->chain );
2313  tls->chain = NULL;
2314 
2315  /* Create certificate chain */
2316  tls->chain = x509_alloc_chain();
2317  if ( ! tls->chain ) {
2318  rc = -ENOMEM_CHAIN;
2319  goto err_alloc_chain;
2320  }
2321 
2322  /* Add certificates to chain */
2323  while ( remaining ) {
2324  const struct {
2325  tls24_t length;
2326  uint8_t data[0];
2327  } __attribute__ (( packed )) *certificate = data;
2328  size_t certificate_len;
2329  size_t record_len;
2330  struct x509_certificate *cert;
2331 
2332  /* Parse header */
2333  if ( sizeof ( *certificate ) > remaining ) {
2334  DBGC ( tls, "TLS %p underlength certificate:\n", tls );
2335  DBGC_HDA ( tls, 0, data, remaining );
2337  goto err_underlength;
2338  }
2339  certificate_len = tls_uint24 ( &certificate->length );
2340  if ( certificate_len > ( remaining - sizeof ( *certificate ) )){
2341  DBGC ( tls, "TLS %p overlength certificate:\n", tls );
2342  DBGC_HDA ( tls, 0, data, remaining );
2344  goto err_overlength;
2345  }
2346  record_len = ( sizeof ( *certificate ) + certificate_len );
2347 
2348  /* Add certificate to chain */
2349  if ( ( rc = x509_append_raw ( tls->chain, certificate->data,
2350  certificate_len ) ) != 0 ) {
2351  DBGC ( tls, "TLS %p could not append certificate: %s\n",
2352  tls, strerror ( rc ) );
2353  DBGC_HDA ( tls, 0, data, remaining );
2354  goto err_parse;
2355  }
2356  cert = x509_last ( tls->chain );
2357  DBGC ( tls, "TLS %p found certificate %s\n",
2358  tls, x509_name ( cert ) );
2359 
2360  /* Move to next certificate in list */
2361  data += record_len;
2362  remaining -= record_len;
2363  }
2364 
2365  return 0;
2366 
2367  err_parse:
2368  err_overlength:
2369  err_underlength:
2370  x509_chain_put ( tls->chain );
2371  tls->chain = NULL;
2372  err_alloc_chain:
2373  return rc;
2374 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:291
#define __attribute__(x)
Definition: compiler.h:10
u16 length
Definition: sky2.h:9
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:402
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:230
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:1668
#define DBGC(...)
Definition: compiler.h:505
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1620
#define ENOMEM_CHAIN
Definition: tls.c:125
#define EINVAL_CERTIFICATE
Definition: tls.c:69
#define DBGC_HDA(...)
Definition: compiler.h:506
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition: x509.h:316
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:207
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:215
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:145
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References __attribute__, tls_connection::chain, data, DBGC, DBGC_HDA, EINVAL_CERTIFICATE, ENOMEM_CHAIN, len, length, NULL, rc, 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 2384 of file tls.c.

2385  {
2386  const struct {
2387  tls24_t length;
2388  uint8_t certificates[0];
2389  } __attribute__ (( packed )) *certificate = data;
2390  size_t certificates_len;
2391  int rc;
2392 
2393  /* Parse header */
2394  if ( sizeof ( *certificate ) > len ) {
2395  DBGC ( tls, "TLS %p received underlength Server Certificate\n",
2396  tls );
2397  DBGC_HD ( tls, data, len );
2398  return -EINVAL_CERTIFICATES;
2399  }
2400  certificates_len = tls_uint24 ( &certificate->length );
2401  if ( certificates_len > ( len - sizeof ( *certificate ) ) ) {
2402  DBGC ( tls, "TLS %p received overlength Server Certificate\n",
2403  tls );
2404  DBGC_HD ( tls, data, len );
2405  return -EINVAL_CERTIFICATES;
2406  }
2407 
2408  /* Parse certificate chain */
2409  if ( ( rc = tls_parse_chain ( tls, certificate->certificates,
2410  certificates_len ) ) != 0 )
2411  return rc;
2412 
2413  return 0;
2414 }
#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:230
#define DBGC(...)
Definition: compiler.h:505
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:215
uint32_t len
Length.
Definition: ena.h:14
static int tls_parse_chain(struct tls_connection *tls, const void *data, size_t len)
Parse certificate chain.
Definition: tls.c:2306
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_CERTIFICATES
Definition: tls.c:73

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

2425  {
2426 
2427  /* Free any existing server key exchange record */
2428  free ( tls->server_key );
2429  tls->server_key_len = 0;
2430 
2431  /* Allocate copy of server key exchange record */
2432  tls->server_key = malloc ( len );
2433  if ( ! tls->server_key )
2434  return -ENOMEM;
2435 
2436  /* Store copy of server key exchange record for later
2437  * processing. We cannot verify the signature at this point
2438  * since the certificate validation will not yet have
2439  * completed.
2440  */
2441  memcpy ( tls->server_key, data, len );
2442  tls->server_key_len = len;
2443 
2444  return 0;
2445 }
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * server_key
Server Key Exchange record (if any)
Definition: tls.h:383
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t server_key_len
Server Key Exchange record length.
Definition: tls.h:385

References data, ENOMEM, free, len, malloc(), memcpy(), tls_connection::server_key, and tls_connection::server_key_len.

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

2457  {
2458  struct x509_certificate *cert;
2459  int rc;
2460 
2461  /* We can only send a single certificate, so there is no point
2462  * in parsing the Certificate Request.
2463  */
2464 
2465  /* Free any existing client certificate chain */
2466  x509_chain_put ( tls->certs );
2467  tls->certs = NULL;
2468 
2469  /* Determine client certificate to be sent */
2470  cert = certstore_find_key ( tls->key );
2471  if ( ! cert ) {
2472  DBGC ( tls, "TLS %p could not find certificate corresponding "
2473  "to private key\n", tls );
2474  rc = -EPERM_CLIENT_CERT;
2475  goto err_find;
2476  }
2477  x509_get ( cert );
2478  DBGC ( tls, "TLS %p selected client certificate %s\n",
2479  tls, x509_name ( cert ) );
2480 
2481  /* Create client certificate chain */
2482  tls->certs = x509_alloc_chain();
2483  if ( ! tls->certs ) {
2484  rc = -ENOMEM;
2485  goto err_alloc;
2486  }
2487 
2488  /* Append client certificate to chain */
2489  if ( ( rc = x509_append ( tls->certs, cert ) ) != 0 )
2490  goto err_append;
2491 
2492  /* Append any relevant issuer certificates */
2493  if ( ( rc = x509_auto_append ( tls->certs, &certstore ) ) != 0 )
2494  goto err_auto_append;
2495 
2496  /* Drop local reference to client certificate */
2497  x509_put ( cert );
2498 
2499  return 0;
2500 
2501  err_auto_append:
2502  err_append:
2503  x509_chain_put ( tls->certs );
2504  tls->certs = NULL;
2505  err_alloc:
2506  x509_put ( cert );
2507  err_find:
2508  return rc;
2509 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:291
#define EPERM_CLIENT_CERT
Definition: tls.c:173
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_certificate * certstore_find_key(struct private_key *key)
Find certificate in store corresponding to a private key.
Definition: certstore.c:119
struct x509_chain certstore
Certificate store.
Definition: certstore.c:73
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition: x509.h:258
#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:1643
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1620
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:393
An X.509 certificate.
Definition: x509.h:207
struct private_key * key
Private key.
Definition: tls.h:391
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:145
int x509_auto_append(struct x509_chain *chain, struct x509_chain *certs)
Append X.509 certificates to X.509 certificate chain.
Definition: x509.c:1748
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:269
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References tls_connection::certs, certstore, certstore_find_key(), DBGC, ENOMEM, EPERM_CLIENT_CERT, tls_connection::key, NULL, rc, x509_alloc_chain(), x509_append(), x509_auto_append(), x509_chain_put(), x509_get(), x509_name(), and x509_put().

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

2520  {
2521  const struct {
2522  char next[0];
2523  } __attribute__ (( packed )) *hello_done = data;
2524  int rc;
2525 
2526  /* Sanity check */
2527  if ( sizeof ( *hello_done ) != len ) {
2528  DBGC ( tls, "TLS %p received overlength Server Hello Done\n",
2529  tls );
2530  DBGC_HD ( tls, data, len );
2531  return -EINVAL_HELLO_DONE;
2532  }
2533 
2534  /* Begin certificate validation */
2535  if ( ( rc = create_validator ( &tls->validator, tls->chain,
2536  tls->root ) ) != 0 ) {
2537  DBGC ( tls, "TLS %p could not start certificate validation: "
2538  "%s\n", tls, strerror ( rc ) );
2539  return rc;
2540  }
2541  pending_get ( &tls->validation );
2542 
2543  return 0;
2544 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:402
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
#define EINVAL_HELLO_DONE
Definition: tls.c:77
struct x509_root * root
Root of trust.
Definition: tls.h:400
int create_validator(struct interface *job, struct x509_chain *chain, struct x509_root *root)
Instantiate a certificate validator.
Definition: validator.c:757
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:411
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC_HD(...)
Definition: compiler.h:507
uint32_t len
Length.
Definition: ena.h:14
struct interface validator
Certificate validator.
Definition: tls.h:404
uint8_t data[48]
Additional event data.
Definition: ena.h:22
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45

References __attribute__, tls_connection::chain, create_validator(), data, DBGC, DBGC_HD, EINVAL_HELLO_DONE, len, next, pending_get(), rc, tls_connection::root, strerror(), tls_connection::validation, and tls_connection::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 2554 of file tls.c.

2555  {
2556  struct tls_session *session = tls->session;
2557  struct digest_algorithm *digest = tls->handshake_digest;
2558  const struct {
2559  uint8_t verify_data[ sizeof ( tls->verify.server ) ];
2560  char next[0];
2561  } __attribute__ (( packed )) *finished = data;
2562  uint8_t digest_out[ digest->digestsize ];
2563 
2564  /* Sanity check */
2565  if ( sizeof ( *finished ) != len ) {
2566  DBGC ( tls, "TLS %p received overlength Finished\n", tls );
2567  DBGC_HD ( tls, data, len );
2568  return -EINVAL_FINISHED;
2569  }
2570 
2571  /* Verify data */
2572  tls_verify_handshake ( tls, digest_out );
2573  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
2574  tls->verify.server, sizeof ( tls->verify.server ),
2575  "server finished", digest_out, sizeof ( digest_out ) );
2576  if ( memcmp ( tls->verify.server, finished->verify_data,
2577  sizeof ( tls->verify.server ) ) != 0 ) {
2578  DBGC ( tls, "TLS %p verification failed\n", tls );
2579  return -EPERM_VERIFY;
2580  }
2581 
2582  /* Mark server as finished */
2583  pending_put ( &tls->server_negotiation );
2584 
2585  /* If we are resuming a session (i.e. if the server Finished
2586  * arrives before the client Finished is sent), then schedule
2587  * transmission of Change Cipher and Finished.
2588  */
2589  if ( is_pending ( &tls->client_negotiation ) ) {
2591  tls_tx_resume ( tls );
2592  }
2593 
2594  /* Record session ID, ticket, and master secret, if applicable */
2595  if ( tls->session_id_len || tls->new_session_ticket_len ) {
2596  memcpy ( session->master_secret, tls->master_secret,
2597  sizeof ( session->master_secret ) );
2598  }
2599  if ( tls->session_id_len ) {
2600  session->id_len = tls->session_id_len;
2601  memcpy ( session->id, tls->session_id, sizeof ( session->id ) );
2602  }
2603  if ( tls->new_session_ticket_len ) {
2604  free ( session->ticket );
2605  session->ticket = tls->new_session_ticket;
2606  session->ticket_len = tls->new_session_ticket_len;
2607  tls->new_session_ticket = NULL;
2608  tls->new_session_ticket_len = 0;
2609  }
2610 
2611  /* Move to end of session's connection list and allow other
2612  * connections to start making progress.
2613  */
2614  list_del ( &tls->list );
2615  list_add_tail ( &tls->list, &session->conn );
2617 
2618  /* Send notification of a window change */
2619  xfer_window_changed ( &tls->plainstream );
2620 
2621  return 0;
2622 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:397
#define __attribute__(x)
Definition: compiler.h:10
static void tls_tx_resume_all(struct tls_session *session)
Resume TX state machine for all connections within a session.
Definition: tls.c:1099
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:407
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1090
struct tls_session * session
Session.
Definition: tls.h:349
uint32_t next
Next descriptor address.
Definition: myson.h:18
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:806
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
#define DBGC(...)
Definition: compiler.h:505
size_t new_session_ticket_len
Length of new session ticket.
Definition: tls.h:359
uint8_t session_id[32]
Session ID.
Definition: tls.h:353
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct ntlm_data session
Session key.
Definition: ntlm.h:24
void * new_session_ticket
New session ticket.
Definition: tls.h:357
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define EINVAL_FINISHED
Definition: tls.c:81
struct list_head list
List of connections within the same session.
Definition: tls.h:351
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
#define EPERM_VERIFY
Definition: tls.c:169
uint8_t master_secret[48]
Master secret.
Definition: tls.h:377
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:409
unsigned int tx_pending
TX pending transmissions.
Definition: tls.h:416
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:387
uint32_t len
Length.
Definition: ena.h:14
A TLS session.
Definition: tls.h:315
size_t digestsize
Digest size.
Definition: crypto.h:25
A message digest algorithm.
Definition: crypto.h:17
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t server[12]
Server verification data.
Definition: tls.h:154
size_t session_id_len
Length of session ID.
Definition: tls.h:355
struct interface plainstream
Plaintext stream.
Definition: tls.h:362
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:616

References __attribute__, tls_connection::client_negotiation, data, DBGC, DBGC_HD, digest, digest_algorithm::digestsize, EINVAL_FINISHED, EPERM_VERIFY, free, tls_connection::handshake_digest, is_pending(), len, tls_connection::list, list_add_tail, list_del, tls_connection::master_secret, memcmp(), memcpy(), tls_connection::new_session_ticket, tls_connection::new_session_ticket_len, next, NULL, pending_put(), tls_connection::plainstream, tls_verify_data::server, tls_connection::server_negotiation, session, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, tls_prf_label, TLS_TX_CHANGE_CIPHER, TLS_TX_FINISHED, tls_tx_resume(), tls_tx_resume_all(), tls_verify_handshake(), tls_connection::tx_pending, 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 2631 of file tls.c.

2632  {
2633  size_t remaining;
2634  int rc;
2635 
2636  while ( ( remaining = iob_len ( iobuf ) ) ) {
2637  const struct {
2638  uint8_t type;
2639  tls24_t length;
2640  uint8_t payload[0];
2641  } __attribute__ (( packed )) *handshake = iobuf->data;
2642  const void *payload;
2643  size_t payload_len;
2644  size_t record_len;
2645 
2646  /* Parse header */
2647  if ( sizeof ( *handshake ) > remaining ) {
2648  /* Leave remaining fragment unconsumed */
2649  break;
2650  }
2651  payload_len = tls_uint24 ( &handshake->length );
2652  if ( payload_len > ( remaining - sizeof ( *handshake ) ) ) {
2653  /* Leave remaining fragment unconsumed */
2654  break;
2655  }
2656  payload = &handshake->payload;
2657  record_len = ( sizeof ( *handshake ) + payload_len );
2658 
2659  /* Handle payload */
2660  switch ( handshake->type ) {
2661  case TLS_HELLO_REQUEST:
2662  rc = tls_new_hello_request ( tls, payload,
2663  payload_len );
2664  break;
2665  case TLS_SERVER_HELLO:
2666  rc = tls_new_server_hello ( tls, payload, payload_len );
2667  break;
2669  rc = tls_new_session_ticket ( tls, payload,
2670  payload_len );
2671  break;
2672  case TLS_CERTIFICATE:
2673  rc = tls_new_certificate ( tls, payload, payload_len );
2674  break;
2676  rc = tls_new_server_key_exchange ( tls, payload,
2677  payload_len );
2678  break;
2680  rc = tls_new_certificate_request ( tls, payload,
2681  payload_len );
2682  break;
2683  case TLS_SERVER_HELLO_DONE:
2684  rc = tls_new_server_hello_done ( tls, payload,
2685  payload_len );
2686  break;
2687  case TLS_FINISHED:
2688  rc = tls_new_finished ( tls, payload, payload_len );
2689  break;
2690  default:
2691  DBGC ( tls, "TLS %p ignoring handshake type %d\n",
2692  tls, handshake->type );
2693  rc = 0;
2694  break;
2695  }
2696 
2697  /* Add to handshake digest (except for Hello Requests,
2698  * which are explicitly excluded).
2699  */
2700  if ( handshake->type != TLS_HELLO_REQUEST )
2701  tls_add_handshake ( tls, handshake, record_len );
2702 
2703  /* Abort on failure */
2704  if ( rc != 0 )
2705  return rc;
2706 
2707  /* Move to next handshake record */
2708  iob_pull ( iobuf, record_len );
2709  }
2710 
2711  return 0;
2712 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#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:230
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:790
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:72
#define TLS_SERVER_HELLO_DONE
Definition: tls.h:75
#define TLS_CERTIFICATE_REQUEST
Definition: tls.h:74
static int tls_new_hello_request(struct tls_connection *tls, const void *data __unused, size_t len __unused)
Receive new Hello Request handshake record.
Definition: tls.c:2039
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:2255
#define TLS_HELLO_REQUEST
Definition: tls.h:68
static int tls_new_finished(struct tls_connection *tls, const void *data, size_t len)
Receive new Finished handshake record.
Definition: tls.c:2554
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
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:2070
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:2455
#define TLS_NEW_SESSION_TICKET
Definition: tls.h:71
A TLS 24-bit integer.
Definition: tls.c:215
uint32_t type
Operating system type.
Definition: ena.h:12
#define TLS_SERVER_KEY_EXCHANGE
Definition: tls.h:73
void * data
Start of data.
Definition: iobuf.h:48
static int tls_new_certificate(struct tls_connection *tls, const void *data, size_t len)
Receive new Certificate handshake record.
Definition: tls.c:2384
#define TLS_SERVER_HELLO
Definition: tls.h:70
static int tls_new_server_hello_done(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Hello Done handshake record.
Definition: tls.c:2519
#define TLS_FINISHED
Definition: tls.h:78
static int tls_new_server_key_exchange(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Key Exchange handshake record.
Definition: tls.c:2424

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

2722  {
2723 
2724  /* RFC4346 says that we should just ignore unknown record types */
2725  iob_pull ( iobuf, iob_len ( iobuf ) );
2726  return 0;
2727 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155

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

2737  {
2738  struct io_buffer *iobuf;
2739  int rc;
2740 
2741  /* Fail unless we are ready to receive data */
2742  if ( ! tls_ready ( tls ) )
2743  return -ENOTCONN;
2744 
2745  /* Deliver each I/O buffer in turn */
2746  while ( ( iobuf = list_first_entry ( rx_data, struct io_buffer,
2747  list ) ) ) {
2748  list_del ( &iobuf->list );
2749  if ( ( rc = xfer_deliver_iob ( &tls->plainstream,
2750  iobuf ) ) != 0 ) {
2751  DBGC ( tls, "TLS %p could not deliver data: "
2752  "%s\n", tls, strerror ( rc ) );
2753  return rc;
2754  }
2755  }
2756 
2757  return 0;
2758 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:255
#define DBGC(...)
Definition: compiler.h:505
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:253
struct interface plainstream
Plaintext stream.
Definition: tls.h:362
A persistent I/O buffer.
Definition: iobuf.h:33

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

2769  {
2770  int ( * handler ) ( struct tls_connection *tls,
2771  struct io_buffer *iobuf );
2772  struct io_buffer *tmp = NULL;
2773  struct io_buffer **iobuf;
2774  int rc;
2775 
2776  /* Deliver data records as-is to the plainstream interface */
2777  if ( type == TLS_TYPE_DATA )
2778  return tls_new_data ( tls, rx_data );
2779 
2780  /* Determine handler and fragment buffer */
2781  iobuf = &tmp;
2782  switch ( type ) {
2784  handler = tls_new_change_cipher;
2785  break;
2786  case TLS_TYPE_ALERT:
2787  handler = tls_new_alert;
2788  break;
2789  case TLS_TYPE_HANDSHAKE:
2790  handler = tls_new_handshake;
2791  iobuf = &tls->rx_handshake;
2792  break;
2793  default:
2794  DBGC ( tls, "TLS %p unknown record type %d\n", tls, type );
2795  handler = tls_new_unknown;
2796  break;
2797  }
2798 
2799  /* Merge into a single I/O buffer */
2800  if ( *iobuf )
2801  list_add ( &(*iobuf)->list, rx_data );
2802  *iobuf = iob_concatenate ( rx_data );
2803  if ( ! *iobuf ) {
2804  DBGC ( tls, "TLS %p could not concatenate non-data record "
2805  "type %d\n", tls, type );
2806  rc = -ENOMEM_RX_CONCAT;
2807  goto err_concatenate;
2808  }
2809 
2810  /* Handle record */
2811  if ( ( rc = handler ( tls, *iobuf ) ) != 0 )
2812  goto err_handle;
2813 
2814  /* Discard I/O buffer if empty */
2815  if ( ! iob_len ( *iobuf ) ) {
2816  free_iob ( *iobuf );
2817  *iobuf = NULL;
2818  }
2819 
2820  /* Sanity check */
2821  assert ( tmp == NULL );
2822 
2823  return 0;
2824 
2825  err_handle:
2826  free_iob ( *iobuf );
2827  *iobuf = NULL;
2828  err_concatenate:
2829  return rc;
2830 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define DBGC(...)
Definition: compiler.h:505
#define ENOMEM_RX_CONCAT
Definition: tls.c:141
unsigned long tmp
Definition: linux_pci.h:53
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
Definition: tls.h:53
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static int tls_new_alert(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Alert record.
Definition: tls.c:1997
static int tls_new_data(struct tls_connection *tls, struct list_head *rx_data)
Receive new data record.
Definition: tls.c:2736
static int tls_new_change_cipher(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Change Cipher record.
Definition: tls.c:1961
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
Definition: iobuf.c:243
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:62
static int tls_new_handshake(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Handshake record.
Definition: tls.c:2631
uint32_t type
Operating system type.
Definition: ena.h:12
struct io_buffer * rx_handshake
Received handshake fragment.
Definition: tls.h:431
A TLS connection.
Definition: tls.h:344
#define TLS_TYPE_DATA
Application data content type.
Definition: tls.h:65
#define TLS_TYPE_ALERT
Alert content type.
Definition: tls.h:59
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static int tls_new_unknown(struct tls_connection *tls __unused, struct io_buffer *iobuf)
Receive new unknown record.
Definition: tls.c:2721
A persistent I/O buffer.
Definition: iobuf.h:33

References assert(), DBGC, ENOMEM_RX_CONCAT, free_iob(), iob_concatenate(), iob_len(), list_add, NULL, rc, tls_connection::rx_handshake, 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 2846 of file tls.c.

2847  {
2848  struct tls_cipher_suite *suite = cipherspec->suite;
2849  struct digest_algorithm *digest = suite->digest;
2850 
2851  hmac_init ( digest, ctx, cipherspec->mac_secret, suite->mac_len );
2852  hmac_update ( digest, ctx, authhdr, sizeof ( *authhdr ) );
2853 }
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition: hmac.c:57
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:195
A TLS cipher suite.
Definition: tls.h:187
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint8_t mac_len
MAC length.
Definition: tls.h:207
A message digest algorithm.
Definition: crypto.h:17
void * mac_secret
MAC secret.
Definition: tls.h:248

References ctx, tls_cipher_suite::digest, 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 2863 of file tls.c.

2864  {
2865  struct digest_algorithm *digest = cipherspec->suite->digest;
2866 
2867  hmac_update ( digest, ctx, data, len );
2868 }
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:195
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint32_t len
Length.
Definition: ena.h:14
A message digest algorithm.
Definition: crypto.h:17
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References ctx, data, tls_cipher_suite::digest, 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 2877 of file tls.c.

2878  {
2879  struct digest_algorithm *digest = cipherspec->suite->digest;
2880 
2881  hmac_final ( digest, ctx, hmac );
2882 }
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:195
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
A message digest algorithm.
Definition: crypto.h:17
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition: hmac.c:87

References ctx, tls_cipher_suite::digest, 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 2893 of file tls.c.

2895  {
2896  struct digest_algorithm *digest = cipherspec->suite->digest;
2897  uint8_t ctx[ hmac_ctxsize ( digest ) ];
2898 
2899  tls_hmac_init ( cipherspec, ctx, authhdr );
2900  tls_hmac_update ( cipherspec, ctx, data, len );
2901  tls_hmac_final ( cipherspec, ctx, hmac );
2902 }
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition: tls.c:2877
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2863
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:195
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition: tls.c:2846
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
A message digest algorithm.
Definition: crypto.h:17
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

Referenced by tls_send_plaintext().

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

2914  {
2915  struct digest_algorithm *digest = cipherspec->suite->digest;
2916  uint8_t ctx[ hmac_ctxsize ( digest ) ];
2917  struct io_buffer *iobuf;
2918 
2919  tls_hmac_init ( cipherspec, ctx, authhdr );
2920  list_for_each_entry ( iobuf, list, list ) {
2921  tls_hmac_update ( cipherspec, ctx, iobuf->data,
2922  iob_len ( iobuf ) );
2923  }
2924  tls_hmac_final ( cipherspec, ctx, hmac );
2925 }
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition: tls.c:2877
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2863
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:195
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition: tls.c:2846
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
unsigned char uint8_t
Definition: stdint.h:10
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
void * data
Start of data.
Definition: iobuf.h:48
A message digest algorithm.
Definition: crypto.h:17
A persistent I/O buffer.
Definition: iobuf.h:33

References ctx, io_buffer::data, tls_cipher_suite::digest, digest, 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_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 3072 of file tls.c.

3073  {
3074  uint8_t *padding;
3075  unsigned int pad;
3076  unsigned int i;
3077  size_t len;
3078 
3079  /* Extract and verify padding */
3080  padding = ( iobuf->tail - 1 );
3081  pad = *padding;
3082  len = ( pad + 1 );
3083  if ( len > iob_len ( iobuf ) ) {
3084  DBGC ( tls, "TLS %p received underlength padding\n", tls );
3085  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3086  return -EINVAL_PADDING;
3087  }
3088  for ( i = 0 ; i < pad ; i++ ) {
3089  if ( *(--padding) != pad ) {
3090  DBGC ( tls, "TLS %p received bad padding\n", tls );
3091  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3092  return -EINVAL_PADDING;
3093  }
3094  }
3095 
3096  return len;
3097 }
#define EINVAL_PADDING
Definition: tls.c:93
#define DBGC(...)
Definition: compiler.h:505
u32 pad[9]
Padding.
Definition: ar9003_mac.h:90
void * tail
End of data.
Definition: iobuf.h:50
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:48

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

3109  {
3110  struct tls_cipherspec *cipherspec = &tls->rx_cipherspec;
3111  struct tls_cipher_suite *suite = cipherspec->suite;
3112  struct cipher_algorithm *cipher = suite->cipher;
3113  struct digest_algorithm *digest = suite->digest;
3114  size_t len = ntohs ( tlshdr->length );
3115  struct {
3116  uint8_t fixed[suite->fixed_iv_len];
3117  uint8_t record[suite->record_iv_len];
3118  } __attribute__ (( packed )) iv;
3119  struct tls_auth_header authhdr;
3120  uint8_t verify_mac[digest->digestsize];
3121  uint8_t verify_auth[cipher->authsize];
3122  struct io_buffer *first;
3123  struct io_buffer *last;
3124  struct io_buffer *iobuf;
3125  void *mac;
3126  void *auth;
3127  size_t check_len;
3128  int pad_len;
3129  int rc;
3130 
3131  /* Locate first and last data buffers */
3132  assert ( ! list_empty ( rx_data ) );
3133  first = list_first_entry ( rx_data, struct io_buffer, list );
3134  last = list_last_entry ( rx_data, struct io_buffer, list );
3135 
3136  /* Extract initialisation vector */
3137  if ( iob_len ( first ) < sizeof ( iv.record ) ) {
3138  DBGC ( tls, "TLS %p received underlength IV\n", tls );
3139  DBGC_HD ( tls, first->data, iob_len ( first ) );
3140  return -EINVAL_IV;
3141  }
3142  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
3143  memcpy ( iv.record, first->data, sizeof ( iv.record ) );
3144  iob_pull ( first, sizeof ( iv.record ) );
3145  len -= sizeof ( iv.record );
3146 
3147  /* Extract unencrypted authentication tag */
3148  if ( iob_len ( last ) < cipher->authsize ) {
3149  DBGC ( tls, "TLS %p received underlength authentication tag\n",
3150  tls );
3151  DBGC_HD ( tls, last->data, iob_len ( last ) );
3152  return -EINVAL_MAC;
3153  }
3154  iob_unput ( last, cipher->authsize );
3155  len -= cipher->authsize;
3156  auth = last->tail;
3157 
3158  /* Construct authentication data */
3159  authhdr.seq = cpu_to_be64 ( tls->rx_seq );
3160  authhdr.header.type = tlshdr->type;
3161  authhdr.header.version = tlshdr->version;
3162  authhdr.header.length = htons ( len );
3163 
3164  /* Set initialisation vector */
3165  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv, sizeof ( iv ) );
3166 
3167  /* Process authentication data, if applicable */
3168  if ( is_auth_cipher ( cipher ) ) {
3169  cipher_decrypt ( cipher, cipherspec->cipher_ctx, &authhdr,
3170  NULL, sizeof ( authhdr ) );
3171  }
3172 
3173  /* Decrypt the received data */
3174  check_len = 0;
3175  list_for_each_entry ( iobuf, &tls->rx_data, list ) {
3176  cipher_decrypt ( cipher, cipherspec->cipher_ctx,
3177  iobuf->data, iobuf->data, iob_len ( iobuf ) );
3178  check_len += iob_len ( iobuf );
3179  }
3180  assert ( check_len == len );
3181 
3182  /* Strip block padding, if applicable */
3183  if ( is_block_cipher ( cipher ) ) {
3184  pad_len = tls_verify_padding ( tls, last );
3185  if ( pad_len < 0 ) {
3186  /* Assume zero padding length to avoid timing attacks */
3187  pad_len = 0;
3188  }
3189  iob_unput ( last, pad_len );
3190  len -= pad_len;
3191  }
3192 
3193  /* Extract decrypted MAC */
3194  if ( iob_len ( last ) < suite->mac_len ) {
3195  DBGC ( tls, "TLS %p received underlength MAC\n", tls );
3196  DBGC_HD ( tls, last->data, iob_len ( last ) );
3197  return -EINVAL_MAC;
3198  }
3199  iob_unput ( last, suite->mac_len );
3200  len -= suite->mac_len;
3201  mac = last->tail;
3202 
3203  /* Dump received data */
3204  DBGC2 ( tls, "Received plaintext data:\n" );
3205  check_len = 0;
3206  list_for_each_entry ( iobuf, rx_data, list ) {
3207  DBGC2_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3208  check_len += iob_len ( iobuf );
3209  }
3210  assert ( check_len == len );
3211 
3212  /* Generate MAC */
3213  authhdr.header.length = htons ( len );
3214  if ( suite->mac_len )
3215  tls_hmac_list ( cipherspec, &authhdr, rx_data, verify_mac );
3216 
3217  /* Generate authentication tag */
3218  cipher_auth ( cipher, cipherspec->cipher_ctx, verify_auth );
3219 
3220  /* Verify MAC */
3221  if ( memcmp ( mac, verify_mac, suite->mac_len ) != 0 ) {
3222  DBGC ( tls, "TLS %p failed MAC verification\n", tls );
3223  return -EINVAL_MAC;
3224  }
3225 
3226  /* Verify authentication tag */
3227  if ( memcmp ( auth, verify_auth, cipher->authsize ) != 0 ) {
3228  DBGC ( tls, "TLS %p failed authentication tag verification\n",
3229  tls );
3230  return -EINVAL_MAC;
3231  }
3232 
3233  /* Process plaintext record */
3234  if ( ( rc = tls_new_record ( tls, tlshdr->type, rx_data ) ) != 0 )
3235  return rc;
3236 
3237  return 0;
3238 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:205
uint64_t rx_seq
RX sequence number.
Definition: tls.h:421
uint8_t type
Content type.
Definition: tls.h:33
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:40
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition: eltorito.h:13
#define ntohs(value)
Definition: byteswap.h:136
TLS authentication header.
Definition: tls.h:142
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:238
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:346
static void void * auth
Definition: crypto.h:264
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
static void tls_hmac_list(struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, struct list_head *list, void *hmac)
Calculate HMAC over list of I/O buffers.
Definition: tls.c:2912
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
size_t authsize
Authentication tag size.
Definition: crypto.h:73
#define EINVAL_MAC
Definition: tls.c:101
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:246
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:195
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:203
A TLS cipher suite.
Definition: tls.h:187
#define iob_unput(iobuf, len)
Definition: iobuf.h:135
#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:155
#define DBGC_HD(...)
Definition: compiler.h:507
uint8_t mac_len
MAC length.
Definition: tls.h:207
unsigned char uint8_t
Definition: stdint.h:10
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:258
uint32_t last
Length to read in last segment, or zero.
Definition: pccrc.h:30
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:373
long pad_len
Definition: bigint.h:30
struct list_head rx_data
List of received data buffers.
Definition: tls.h:429
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
#define EINVAL_IV
Definition: tls.c:89
uint32_t len
Length.
Definition: ena.h:14
static void const void * iv
Definition: crypto.h:238
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:25
void * data
Start of data.
Definition: iobuf.h:48
uint16_t version
Protocol version.
Definition: tls.h:38
A message digest algorithm.
Definition: crypto.h:17
#define cpu_to_be64(value)
Definition: byteswap.h:111
A cipher algorithm.
Definition: crypto.h:49
static int tls_new_record(struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
Receive new record.
Definition: tls.c:2768
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:193
static int tls_verify_padding(struct tls_connection *tls, struct io_buffer *iobuf)
Verify block padding.
Definition: tls.c:3072
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:250
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23
A persistent I/O buffer.
Definition: iobuf.h:33

References __attribute__, assert(), auth, cipher_algorithm::authsize, tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_decrypt, cpu_to_be64, io_buffer::data, DBGC, DBGC2, DBGC2_HD, DBGC_HD, tls_cipher_suite::digest, 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, iv, last, 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_cipherspec, tls_connection::rx_data, tls_connection::rx_seq, tls_auth_header::seq, tls_cipherspec::suite, 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 3253 of file tls.c.

3253  {
3254 
3255  /* Block window unless we are ready to accept data */
3256  if ( ! tls_ready ( tls ) )
3257  return 0;
3258 
3259  return xfer_window ( &tls->cipherstream );
3260 }
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:364
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:253

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

3272  {
3273  int rc;
3274 
3275  /* Refuse unless we are ready to accept data */
3276  if ( ! tls_ready ( tls ) ) {
3277  rc = -ENOTCONN;
3278  goto done;
3279  }
3280 
3281  if ( ( rc = tls_send_plaintext ( tls, TLS_TYPE_DATA, iobuf->data,
3282  iob_len ( iobuf ) ) ) != 0 )
3283  goto done;
3284 
3285  done:
3286  free_iob ( iobuf );
3287  return rc;
3288 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:2936
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
void * data
Start of data.
Definition: iobuf.h:48
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:253
#define TLS_TYPE_DATA
Application data content type.
Definition: tls.h:65
struct bofm_section_header done
Definition: bofm_test.c:46

References io_buffer::data, done, ENOTCONN, free_iob(), iob_len(), rc, tls_ready(), tls_send_plaintext(), 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 3297 of file tls.c.

3298  {
3299 
3300  /* Return cipherstream or validator progress as applicable */
3301  if ( is_pending ( &tls->validation ) ) {
3302  return job_progress ( &tls->validator, progress );
3303  } else {
3304  return job_progress ( &tls->cipherstream, progress );
3305  }
3306 }
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:411
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:364
struct interface validator
Certificate validator.
Definition: tls.h:404
int job_progress(struct interface *intf, struct job_progress *progress)
Get job progress.
Definition: job.c:43

References tls_connection::cipherstream, is_pending(), job_progress(), tls_connection::validation, and tls_connection::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 3336 of file tls.c.

3336  {
3337  struct tls_cipherspec *cipherspec = &tls->rx_cipherspec;
3338  struct cipher_algorithm *cipher = cipherspec->suite->cipher;
3339  size_t iv_len = cipherspec->suite->record_iv_len;
3340  size_t data_len = ntohs ( tls->rx_header.length );
3341  size_t remaining = data_len;
3342  size_t frag_len;
3343  size_t reserve;
3344  struct io_buffer *iobuf;
3345  struct io_buffer *tmp;
3346  int rc;
3347 
3348  /* Sanity check */
3349  assert ( ( TLS_RX_BUFSIZE % cipher->alignsize ) == 0 );
3350 
3351  /* Calculate alignment reservation at start of first data buffer */
3352  reserve = ( ( -iv_len ) & ( cipher->alignsize - 1 ) );
3353  remaining += reserve;
3354 
3355  /* Allocate data buffers now that we know the length */
3356  assert ( list_empty ( &tls->rx_data ) );
3357  while ( remaining ) {
3358 
3359  /* Calculate fragment length. Ensure that no block is
3360  * smaller than TLS_RX_MIN_BUFSIZE (by increasing the
3361  * allocation length if necessary).
3362  */
3363  frag_len = remaining;
3364  if ( frag_len > TLS_RX_BUFSIZE )
3365  frag_len = TLS_RX_BUFSIZE;
3366  remaining -= frag_len;
3367  if ( remaining < TLS_RX_MIN_BUFSIZE ) {
3368  frag_len += remaining;
3369  remaining = 0;
3370  }
3371 
3372  /* Allocate buffer */
3373  iobuf = alloc_iob_raw ( frag_len, TLS_RX_ALIGN, 0 );
3374  if ( ! iobuf ) {
3375  DBGC ( tls, "TLS %p could not allocate %zd of %zd "
3376  "bytes for receive buffer\n", tls,
3377  remaining, data_len );
3378  rc = -ENOMEM_RX_DATA;
3379  goto err;
3380  }
3381 
3382  /* Ensure tailroom is exactly what we asked for. This
3383  * will result in unaligned I/O buffers when the
3384  * fragment length is unaligned, which can happen only
3385  * before we switch to using a block cipher.
3386  */
3387  iob_reserve ( iobuf, ( iob_tailroom ( iobuf ) - frag_len ) );
3388 
3389  /* Ensure first buffer length will be aligned to a
3390  * multiple of the cipher alignment size after
3391  * stripping the record IV.
3392  */
3393  iob_reserve ( iobuf, reserve );
3394  reserve = 0;
3395 
3396  /* Add I/O buffer to list */
3397  list_add_tail ( &iobuf->list, &tls->rx_data );
3398  }
3399 
3400  /* Move to data state */
3401  tls->rx_state = TLS_RX_DATA;
3402 
3403  return 0;
3404 
3405  err:
3406  list_for_each_entry_safe ( iobuf, tmp, &tls->rx_data, list ) {
3407  list_del ( &iobuf->list );
3408  free_iob ( iobuf );
3409  }
3410  return rc;
3411 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:205
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
struct io_buffer * alloc_iob_raw(size_t len, size_t align, size_t offset)
Allocate I/O buffer with specified alignment and offset.
Definition: iobuf.c:48
size_t alignsize
Alignment size.
Definition: crypto.h:71
#define DBGC(...)
Definition: compiler.h:505
struct tls_header rx_header
Current received record header.
Definition: tls.h:425
uint16_t length
Length of payload.
Definition: tls.h:40
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
#define ntohs(value)
Definition: byteswap.h:136
A TLS cipher specification.
Definition: tls.h:238
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:53
enum tls_rx_state rx_state
RX state.
Definition: tls.h:423
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define ENOMEM_RX_DATA
Definition: tls.c:137
#define TLS_RX_ALIGN
RX I/O buffer alignment.
Definition: tls.h:453
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
#define TLS_RX_BUFSIZE
RX I/O buffer size.
Definition: tls.h:442
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:175
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:373
#define TLS_RX_MIN_BUFSIZE
Minimum RX I/O buffer size.
Definition: tls.h:450
struct list_head rx_data
List of received data buffers.
Definition: tls.h:429
#define iob_reserve(iobuf, len)
Definition: iobuf.h:67
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
A cipher algorithm.
Definition: crypto.h:49
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:193
A persistent I/O buffer.
Definition: iobuf.h:33

References cipher_algorithm::alignsize, alloc_iob_raw(), assert(), tls_cipher_suite::cipher, data_len, DBGC, ENOMEM_RX_DATA, free_iob(), 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_cipherspec, tls_connection::rx_data, tls_connection::rx_header, tls_connection::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 3419 of file tls.c.

3419  {
3420  struct io_buffer *iobuf;
3421  int rc;
3422 
3423  /* Move current buffer to end of list */
3424  iobuf = list_first_entry ( &tls->rx_data, struct io_buffer, list );
3425  list_del ( &iobuf->list );
3426  list_add_tail ( &iobuf->list, &tls->rx_data );
3427 
3428  /* Continue receiving data if any space remains */
3429  iobuf = list_first_entry ( &tls->rx_data, struct io_buffer, list );
3430  if ( iob_tailroom ( iobuf ) )
3431  return 0;
3432 
3433  /* Process record */
3434  if ( ( rc = tls_new_ciphertext ( tls, &tls->rx_header,
3435  &tls->rx_data ) ) != 0 )
3436  return rc;
3437 
3438  /* Increment RX sequence number */
3439  tls->rx_seq += 1;
3440 
3441  /* Return to header state */
3442  assert ( list_empty ( &tls->rx_data ) );
3443  tls->rx_state = TLS_RX_HEADER;
3444  iob_unput ( &tls->rx_header_iobuf, sizeof ( tls->rx_header ) );
3445 
3446  return 0;
3447 }
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:3107
struct io_buffer rx_header_iobuf
Current received record header (static I/O buffer)
Definition: tls.h:427
uint64_t rx_seq
RX sequence number.
Definition: tls.h:421
struct tls_header rx_header
Current received record header.
Definition: tls.h:425
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
enum tls_rx_state rx_state
RX state.
Definition: tls.h:423
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define iob_unput(iobuf, len)
Definition: iobuf.h:135
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:175
struct list_head rx_data
List of received data buffers.
Definition: tls.h:429
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
A persistent I/O buffer.
Definition: iobuf.h:33

References assert(), iob_tailroom(), iob_unput, io_buffer::list, list_add_tail, list_del, list_empty, list_first_entry, rc, tls_connection::rx_data, tls_connection::rx_header, tls_connection::rx_header_iobuf, tls_connection::rx_seq, tls_connection::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 3455 of file tls.c.

3455  {
3456 
3457  /* Open window until we are ready to accept data */
3458  if ( ! tls_ready ( tls ) )
3459  return -1UL;
3460 
3461  return xfer_window ( &tls->plainstream );
3462 }
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:253
struct interface plainstream
Plaintext stream.
Definition: tls.h:362

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

3474  {
3475  size_t frag_len;
3476  int ( * process ) ( struct tls_connection *tls );
3477  struct io_buffer *dest;
3478  int rc;
3479 
3480  while ( iob_len ( iobuf ) ) {
3481 
3482  /* Select buffer according to current state */
3483  switch ( tls->rx_state ) {
3484  case TLS_RX_HEADER:
3485  dest = &tls->rx_header_iobuf;
3487  break;
3488  case TLS_RX_DATA:
3489  dest = list_first_entry ( &tls->rx_data,
3490  struct io_buffer, list );
3491  assert ( dest != NULL );
3493  break;
3494  default:
3495  assert ( 0 );
3496  rc = -EINVAL_RX_STATE;
3497  goto done;
3498  }
3499 
3500  /* Copy data portion to buffer */
3501  frag_len = iob_len ( iobuf );
3502  if ( frag_len > iob_tailroom ( dest ) )
3503  frag_len = iob_tailroom ( dest );
3504  memcpy ( iob_put ( dest, frag_len ), iobuf->data, frag_len );
3505  iob_pull ( iobuf, frag_len );
3506 
3507  /* Process data if buffer is now full */
3508  if ( iob_tailroom ( dest ) == 0 ) {
3509  if ( ( rc = process ( tls ) ) != 0 ) {
3510  tls_close ( tls, rc );
3511  goto done;
3512  }
3513  }
3514  }
3515  rc = 0;
3516 
3517  done:
3518  free_iob ( iobuf );
3519  return rc;
3520 }
A process.
Definition: process.h:17
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:120
static int tls_newdata_process_header(struct tls_connection *tls)
Handle received TLS header.
Definition: tls.c:3336
struct io_buffer rx_header_iobuf
Current received record header (static I/O buffer)
Definition: tls.h:427
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:415
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
enum tls_rx_state rx_state
RX state.
Definition: tls.h:423
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:3419
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define EINVAL_RX_STATE
Definition: tls.c:97
static void * dest
Definition: strings.h:176
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:175
struct list_head rx_data
List of received data buffers.
Definition: tls.h:429
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
void * data
Start of data.
Definition: iobuf.h:48
A TLS connection.
Definition: tls.h:344
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct bofm_section_header done
Definition: bofm_test.c:46
A persistent I/O buffer.
Definition: iobuf.h:33

References assert(), io_buffer::data, dest, done, EINVAL_RX_STATE, free_iob(), iob_len(), iob_pull, iob_put, iob_tailroom(), io_buffer::list, list_first_entry, memcpy(), NULL, rc, tls_connection::rx_data, tls_connection::rx_header_iobuf, tls_connection::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 3551 of file tls.c.

3551  {
3552  struct tls_session *session = tls->session;
3553  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
3554  struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
3555  struct x509_certificate *cert;
3556 
3557  /* Mark validation as complete */
3558  pending_put ( &tls->validation );
3559 
3560  /* Close validator interface */
3561  intf_restart ( &tls->validator, rc );
3562 
3563  /* Check for validation failure */
3564  if ( rc != 0 ) {
3565  DBGC ( tls, "TLS %p certificate validation failed: %s\n",
3566  tls, strerror ( rc ) );
3567  goto err;
3568  }
3569  DBGC ( tls, "TLS %p certificate validation succeeded\n", tls );
3570 
3571  /* Extract first certificate */
3572  cert = x509_first ( tls->chain );
3573  assert ( cert != NULL );
3574 
3575  /* Verify server name */
3576  if ( ( rc = x509_check_name ( cert, session->name ) ) != 0 ) {
3577  DBGC ( tls, "TLS %p server certificate does not match %s: %s\n",
3578  tls, session->name, strerror ( rc ) );
3579  goto err;
3580  }
3581 
3582  /* Initialise public key algorithm */
3583  if ( ( rc = pubkey_init ( pubkey, cipherspec->pubkey_ctx,
3584  cert->subject.public_key.raw.data,
3585  cert->subject.public_key.raw.len ) ) != 0 ) {
3586  DBGC ( tls, "TLS %p cannot initialise public key: %s\n",
3587  tls, strerror ( rc ) );
3588  goto err;
3589  }
3590 
3591  /* Schedule Client Key Exchange, Change Cipher, and Finished */
3594  TLS_TX_FINISHED );
3595  if ( tls->certs ) {
3596  tls->tx_pending |= ( TLS_TX_CERTIFICATE |
3598  }
3599  tls_tx_resume ( tls );
3600 
3601  return;
3602 
3603  err:
3604  tls_close ( tls, rc );
3605  return;
3606 }
struct asn1_cursor raw
Raw public key information.
Definition: x509.h:50
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:402
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1090
struct tls_session * session
Session.
Definition: tls.h:349
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition: x509.c:1569
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:415
A TLS cipher specification.
Definition: tls.h:238
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:191
size_t len
Length of data.
Definition: asn1.h:24
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct ntlm_data session
Session key.
Definition: ntlm.h:24
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:240
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:393
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:411
struct x509_public_key public_key
Public key information.
Definition: x509.h:64
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:207
struct x509_subject subject
Subject.
Definition: x509.h:236
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:244
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
unsigned int tx_pending
TX pending transmissions.
Definition: tls.h:416
struct interface validator
Certificate validator.
Definition: tls.h:404
A TLS session.
Definition: tls.h:315
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:302
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
A public key algorithm.
Definition: crypto.h:120

References assert(), tls_connection::certs, tls_connection::chain, asn1_cursor::data, DBGC, intf_restart(), asn1_cursor::len, NULL, pending_put(), tls_cipher_suite::pubkey, tls_cipherspec::pubkey_ctx, x509_subject::public_key, x509_public_key::raw, rc, session, tls_connection::session, strerror(), x509_certificate::subject, tls_cipherspec::suite, 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_cipherspec_pending, tls_connection::tx_pending, tls_connection::validation, tls_connection::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 3629 of file tls.c.

3629  {
3630  struct tls_session *session = tls->session;
3631  struct tls_connection *conn;
3632  int rc;
3633 
3634  /* Wait for cipherstream to become ready */
3635  if ( ! xfer_window ( &tls->cipherstream ) )
3636  return;
3637 
3638  /* Send first pending transmission */
3639  if ( tls->tx_pending & TLS_TX_CLIENT_HELLO ) {
3640  /* Serialise server negotiations within a session, to
3641  * provide a consistent view of session IDs and
3642  * session tickets.
3643  */
3644  list_for_each_entry ( conn, &session->conn, list ) {
3645  if ( conn == tls )
3646  break;
3647  if ( is_pending ( &conn->server_negotiation ) )
3648  return;
3649  }
3650  /* Record or generate session ID and associated master secret */
3651  if ( session->id_len ) {
3652  /* Attempt to resume an existing session */
3653  memcpy ( tls->session_id, session->id,
3654  sizeof ( tls->session_id ) );
3655  tls->session_id_len = session->id_len;
3656  memcpy ( tls->master_secret, session->master_secret,
3657  sizeof ( tls->master_secret ) );
3658  } else {
3659  /* No existing session: use a random session ID */
3660  assert ( sizeof ( tls->session_id ) ==
3661  sizeof ( tls->client_random ) );
3662  memcpy ( tls->session_id, &tls->client_random,
3663  sizeof ( tls->session_id ) );
3664  tls->session_id_len = sizeof ( tls->session_id );
3665  }
3666  /* Send Client Hello */
3667  if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
3668  DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
3669  tls, strerror ( rc ) );
3670  goto err;
3671  }
3673  } else if ( tls->tx_pending & TLS_TX_CERTIFICATE ) {
3674  /* Send Certificate */
3675  if ( ( rc = tls_send_certificate ( tls ) ) != 0 ) {
3676  DBGC ( tls, "TLS %p cold not send Certificate: %s\n",
3677  tls, strerror ( rc ) );
3678  goto err;
3679  }
3680  tls->tx_pending &= ~TLS_TX_CERTIFICATE;
3681  } else if ( tls->tx_pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
3682  /* Send Client Key Exchange */
3683  if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
3684  DBGC ( tls, "TLS %p could not send Client Key "
3685  "Exchange: %s\n", tls, strerror ( rc ) );
3686  goto err;
3687  }
3689  } else if ( tls->tx_pending & TLS_TX_CERTIFICATE_VERIFY ) {
3690  /* Send Certificate Verify */
3691  if ( ( rc = tls_send_certificate_verify ( tls ) ) != 0 ) {
3692  DBGC ( tls, "TLS %p could not send Certificate "
3693  "Verify: %s\n", tls, strerror ( rc ) );
3694  goto err;
3695  }
3697  } else if ( tls->tx_pending & TLS_TX_CHANGE_CIPHER ) {
3698  /* Send Change Cipher, and then change the cipher in use */
3699  if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
3700  DBGC ( tls, "TLS %p could not send Change Cipher: "
3701  "%s\n", tls, strerror ( rc ) );
3702  goto err;
3703  }
3704  if ( ( rc = tls_change_cipher ( tls,
3705  &tls->tx_cipherspec_pending,
3706  &tls->tx_cipherspec )) != 0 ){
3707  DBGC ( tls, "TLS %p could not activate TX cipher: "
3708  "%s\n", tls, strerror ( rc ) );
3709  goto err;
3710  }
3711  tls->tx_seq = 0;
3713  } else if ( tls->tx_pending & TLS_TX_FINISHED ) {
3714  /* Send Finished */
3715  if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
3716  DBGC ( tls, "TLS %p could not send Finished: %s\n",
3717  tls, strerror ( rc ) );
3718  goto err;
3719  }
3720  tls->tx_pending &= ~TLS_TX_FINISHED;
3721  }
3722 
3723  /* Reschedule process if pending transmissions remain,
3724  * otherwise send notification of a window change.
3725  */
3726  if ( tls->tx_pending ) {
3727  tls_tx_resume ( tls );
3728  } else {
3729  xfer_window_changed ( &tls->plainstream );
3730  }
3731 
3732  return;
3733 
3734  err:
3735  tls_close ( tls, rc );
3736 }
static int tls_send_certificate(struct tls_connection *tls)
Transmit Certificate record.
Definition: tls.c:1332
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1090
struct tls_session * session
Session.
Definition: tls.h:349
#define DBGC(...)
Definition: compiler.h:505
uint8_t session_id[32]
Session ID.
Definition: tls.h:353
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:415
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:369
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct ntlm_data session
Session key.
Definition: ntlm.h:24
static int tls_send_change_cipher(struct tls_connection *tls)
Transmit Change Cipher record.
Definition: tls.c:1903
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct list_head list
List of connections within the same session.
Definition: tls.h:351
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
uint8_t master_secret[48]
Master secret.
Definition: tls.h:377
static int tls_send_client_key_exchange(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition: tls.c:1785
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:381
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:364
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec *pending, struct tls_cipherspec *active)
Activate next cipher suite.
Definition: tls.c:962
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:409
unsigned int tx_pending
TX pending transmissions.
Definition: tls.h:416
static int tls_send_certificate_verify(struct tls_connection *tls)
Transmit Certificate Verify record.
Definition: tls.c:1813
A TLS session.
Definition: tls.h:315
A TLS connection.
Definition: tls.h:344
static int tls_send_finished(struct tls_connection *tls)
Transmit Finished record.
Definition: tls.c:1920
static int tls_send_client_hello(struct tls_connection *tls)
Transmit Client Hello record.
Definition: tls.c:1321
size_t session_id_len
Length of session ID.
Definition: tls.h:355
struct interface plainstream
Plaintext stream.
Definition: tls.h:362
uint64_t tx_seq
TX sequence number.
Definition: tls.h:414

References assert(), tls_connection::cipherstream, tls_connection::client_random, DBGC, is_pending(), tls_connection::list, list_for_each_entry, tls_connection::master_secret, memcpy(), tls_connection::plainstream, rc, tls_connection::server_negotiation, session, 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_cipherspec, tls_connection::tx_cipherspec_pending, tls_connection::tx_pending, tls_connection::tx_seq, 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 3756 of file tls.c.

3756  {
3757  struct tls_session *session;
3758  char *name_copy;
3759  int rc;
3760 
3761  /* Find existing matching session, if any */
3762  list_for_each_entry ( session, &tls_sessions, list ) {
3763  if ( ( strcmp ( name, session->name ) == 0 ) &&
3764  ( tls->root == session->root ) &&
3765  ( tls->key == session->key ) ) {
3766  ref_get ( &session->refcnt );
3767  tls->session = session;
3768  DBGC ( tls, "TLS %p joining session %s\n", tls, name );
3769  return 0;
3770  }
3771  }
3772 
3773  /* Create new session */
3774  session = zalloc ( sizeof ( *session ) + strlen ( name )
3775  + 1 /* NUL */ );
3776  if ( ! session ) {
3777  rc = -ENOMEM;
3778  goto err_alloc;
3779  }
3780  ref_init ( &session->refcnt, free_tls_session );
3781  name_copy = ( ( ( void * ) session ) + sizeof ( *session ) );
3782  strcpy ( name_copy, name );
3783  session->name = name_copy;
3784  session->root = x509_root_get ( tls->root );
3785  session->key = privkey_get ( tls->key );
3786  INIT_LIST_HEAD ( &session->conn );
3787  list_add ( &session->list, &tls_sessions );
3788 
3789  /* Record session */
3790  tls->session = session;
3791 
3792  DBGC ( tls, "TLS %p created session %s\n", tls, name );
3793  return 0;
3794 
3795  ref_put ( &session->refcnt );
3796  err_alloc:
3797  return rc;
3798 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
struct tls_session * session
Session.
Definition: tls.h:349
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
#define DBGC(...)
Definition: compiler.h:505
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
Definition: privkey.h:30
struct x509_root * root
Root of trust.
Definition: tls.h:400
static void free_tls_session(struct refcnt *refcnt)
Free TLS session.
Definition: tls.c:352
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct ntlm_data session
Session key.
Definition: ntlm.h:24
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:326
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:384
struct list_head list
List of sessions.
Definition: tls.h:319
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
struct private_key * key
Private key.
Definition: tls.h:391
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
A TLS session.
Definition: tls.h:315
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References DBGC, ENOMEM, free_tls_session(), INIT_LIST_HEAD, tls_connection::key, tls_session::list, list_add, list_for_each_entry, name, privkey_get(), rc, ref_get, ref_init, ref_put, tls_connection::root, session, 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 3816 of file tls.c.

3817  {
3818  struct tls_connection *tls;
3819  int rc;
3820 
3821  /* Allocate and initialise TLS structure */
3822  tls = malloc ( sizeof ( *tls ) );
3823  if ( ! tls ) {
3824  rc = -ENOMEM;
3825  goto err_alloc;
3826  }
3827  memset ( tls, 0, sizeof ( *tls ) );
3828  ref_init ( &tls->refcnt, free_tls );
3829  INIT_LIST_HEAD ( &tls->list );
3830  intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt );
3832  intf_init ( &tls->validator, &tls_validator_desc, &tls->refcnt );
3834  &tls->refcnt );
3835  tls->key = privkey_get ( key ? key : &private_key );
3836  tls->root = x509_root_get ( root ? root : &root_certificates );
3837  tls->version = TLS_VERSION_MAX;
3838  tls_clear_cipher ( tls, &tls->tx_cipherspec );
3839  tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );
3840  tls_clear_cipher ( tls, &tls->rx_cipherspec );
3841  tls_clear_cipher ( tls, &tls->rx_cipherspec_pending );
3842  tls_clear_handshake ( tls );
3843  tls->client_random.gmt_unix_time = time ( NULL );
3844  iob_populate ( &tls->rx_header_iobuf, &tls->rx_header, 0,
3845  sizeof ( tls->rx_header ) );
3846  INIT_LIST_HEAD ( &tls->rx_data );
3847  if ( ( rc = tls_generate_random ( tls, &tls->client_random.random,
3848  ( sizeof ( tls->client_random.random ) ) ) ) != 0 ) {
3849  goto err_random;
3850  }
3851  if ( ( rc = tls_session ( tls, name ) ) != 0 )
3852  goto err_session;
3853  list_add_tail ( &tls->list, &tls->session->conn );
3854 
3855  /* Start negotiation */
3856  tls_restart ( tls );
3857 
3858  /* Attach to parent interface, mortalise self, and return */
3859  intf_insert ( xfer, &tls->plainstream, &tls->cipherstream );
3860  ref_put ( &tls->refcnt );
3861  return 0;
3862 
3863  err_session:
3864  err_random:
3865  ref_put ( &tls->refcnt );
3866  err_alloc:
3867  return rc;
3868 }
static void free_tls(struct refcnt *refcnt)
Free TLS connection.
Definition: tls.c:376
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
struct process process
TX process.
Definition: tls.h:418
struct tls_session * session
Session.
Definition: tls.h:349
struct io_buffer rx_header_iobuf
Current received record header (static I/O buffer)
Definition: tls.h:427
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition: tls.c:1111
struct stp_switch root
Root switch.
Definition: stp.h:26
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
struct refcnt refcnt
Reference counter.
Definition: tls.h:346
struct x509_root root_certificates
Root certificates.
Definition: rootcert.c:73
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
Definition: privkey.h:30
struct tls_header rx_header
Current received record header.
Definition: tls.h:425
struct x509_root * root
Root of trust.
Definition: tls.h:400
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:190
static struct interface_descriptor tls_cipherstream_desc
TLS ciphertext stream interface descriptor.
Definition: tls.c:3534
static struct interface_descriptor tls_validator_desc
TLS certificate validator interface descriptor.
Definition: tls.c:3614
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:369
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct list_head list
List of connections within the same session.
Definition: tls.h:351
uint32_t gmt_unix_time
GMT Unix time.
Definition: tls.h:287
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:384
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:381
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:364
struct private_key * key
Private key.
Definition: tls.h:391
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:373
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:371
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
struct list_head rx_data
List of received data buffers.
Definition: tls.h:429
static struct interface_descriptor tls_plainstream_desc
TLS plaintext stream interface descriptor.
Definition: tls.c:3319
void intf_insert(struct interface *intf, struct interface *upper, struct interface *lower)
Insert a filter interface.
Definition: interface.c:401
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
uint8_t random[28]
Random data.
Definition: tls.h:289
struct interface validator
Certificate validator.
Definition: tls.h:404
A TLS session.
Definition: tls.h:315
static struct process_descriptor tls_process_desc
TLS TX process descriptor.
Definition: tls.c:3739
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:375
uint16_t version
Protocol version.
Definition: tls.h:367
static void tls_clear_handshake(struct tls_connection *tls)
Clear handshake digest algorithm.
Definition: tls.c:749
A private key.
Definition: privkey.h:16
A TLS connection.
Definition: tls.h:344
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct list_head conn
List of connections.
Definition: tls.h:340
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:453
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
struct interface plainstream
Plaintext stream.
Definition: tls.h:362
uint64_t time
Current time.
Definition: ntlm.h:20
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @382 key
Sense key.
Definition: crypto.h:284
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
void * memset(void *dest, int character, size_t len) __nonnull

References tls_connection::cipherstream, tls_connection::client_random, tls_session::conn, ENOMEM, free_tls(), tls_client_random::gmt_unix_time, INIT_LIST_HEAD, intf_init(), intf_insert(), iob_populate(), key, tls_connection::key, tls_connection::list, list_add_tail, malloc(), memset(), name, NULL, tls_connection::plainstream, privkey_get(), tls_connection::process, process_init_stopped(), tls_client_random::random, rc, ref_init, ref_put, tls_connection::refcnt, root, tls_connection::root, root_certificates, tls_connection::rx_cipherspec, tls_connection::rx_cipherspec_pending, tls_connection::rx_data, tls_connection::rx_header, tls_connection::rx_header_iobuf, tls_connection::session, time, 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_cipherspec, tls_connection::tx_cipherspec_pending, tls_connection::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:293
static void md5_sha1_final(void *ctx, void *out)
Generate MD5+SHA1 digest.
Definition: tls.c:314
static void md5_sha1_init(void *ctx)
Initialise MD5+SHA1 algorithm.
Definition: tls.c:287
An MD5+SHA1 digest.
Definition: tls.h:304
static void md5_sha1_update(void *ctx, const void *data, size_t len)
Accumulate data with MD5+SHA1 algorithm.
Definition: tls.c:301

Hybrid MD5+SHA1 digest algorithm.

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

RSA digestInfo prefix for MD5+SHA1 algorithm.

Definition at line 334 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:135
struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm
Public key exchange algorithm.
Definition: tls.c:1447
struct digest_algorithm digest_null
Definition: crypto_null.c:48
struct cipher_algorithm cipher_null
Definition: crypto_null.c:83

Null cipher suite.

Definition at line 822 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:1394

Public key exchange algorithm.

Definition at line 1447 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:1547

Ephemeral Diffie-Hellman key exchange algorithm.

Definition at line 1661 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:1672

Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm.

Definition at line 1774 of file tls.c.

◆ tls_plainstream_ops

struct interface_operation tls_plainstream_ops[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:415
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
static int tls_progress(struct tls_connection *tls, struct job_progress *progress)
Report job progress.
Definition: tls.c:3297
Job progress.
Definition: job.h:15
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
static int tls_plainstream_deliver(struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Deliver datagram as raw data.
Definition: tls.c:3270
A TLS connection.
Definition: tls.h:344
static size_t tls_plainstream_window(struct tls_connection *tls)
Check flow control window.
Definition: tls.c:3253

TLS plaintext stream interface operations.

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

TLS plaintext stream interface descriptor.

Definition at line 3319 of file tls.c.

Referenced by add_tls().

◆ tls_cipherstream_ops

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

TLS ciphertext stream interface operations.

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

TLS ciphertext stream interface descriptor.

Definition at line 3534 of file tls.c.

Referenced by add_tls().

◆ tls_validator_ops

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

TLS certificate validator interface operations.

Definition at line 3609 of file tls.c.

◆ tls_validator_desc

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

TLS certificate validator interface descriptor.

Definition at line 3614 of file tls.c.

Referenced by add_tls().

◆ tls_process_desc

struct process_descriptor tls_process_desc
static
Initial value:
=
A process.
Definition: process.h:17
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition: process.h:97
static void tls_tx_step(struct tls_connection *tls)
TLS TX state machine.
Definition: tls.c:3629
A TLS connection.
Definition: tls.h:344

TLS TX process descriptor.

Definition at line 3739 of file tls.c.

Referenced by add_tls().