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

Transport Layer Security Protocol. More...

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

Go to the source code of this file.

Data Structures

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

Macros

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )
 
#define EINFO_EINVAL_CHANGE_CIPHER
 
#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )
 
#define EINFO_EINVAL_ALERT
 
#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )
 
#define EINFO_EINVAL_HELLO
 
#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )
 
#define EINFO_EINVAL_CERTIFICATE
 
#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )
 
#define EINFO_EINVAL_CERTIFICATES
 
#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )
 
#define EINFO_EINVAL_HELLO_DONE
 
#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )
 
#define EINFO_EINVAL_FINISHED
 
#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )
 
#define EINFO_EINVAL_HANDSHAKE
 
#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )
 
#define EINFO_EINVAL_IV
 
#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )
 
#define EINFO_EINVAL_PADDING
 
#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )
 
#define EINFO_EINVAL_RX_STATE
 
#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )
 
#define EINFO_EINVAL_MAC
 
#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )
 
#define EINFO_EINVAL_TICKET
 
#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )
 
#define EINFO_EINVAL_KEY_EXCHANGE
 
#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )
 
#define EINFO_EIO_ALERT
 
#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )
 
#define EINFO_ENOMEM_CONTEXT
 
#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )
 
#define EINFO_ENOMEM_CERTIFICATE
 
#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )
 
#define EINFO_ENOMEM_CHAIN
 
#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )
 
#define EINFO_ENOMEM_TX_PLAINTEXT
 
#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )
 
#define EINFO_ENOMEM_TX_CIPHERTEXT
 
#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )
 
#define EINFO_ENOMEM_RX_DATA
 
#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )
 
#define EINFO_ENOMEM_RX_CONCAT
 
#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )
 
#define EINFO_ENOTSUP_CIPHER
 
#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )
 
#define EINFO_ENOTSUP_NULL
 
#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )
 
#define EINFO_ENOTSUP_SIG_HASH
 
#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )
 
#define EINFO_ENOTSUP_VERSION
 
#define ENOTSUP_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )
 
#define EINFO_ENOTSUP_CURVE
 
#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )
 
#define EINFO_EPERM_ALERT
 
#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )
 
#define EINFO_EPERM_VERIFY
 
#define EPERM_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_pair *pair)
 Activate next cipher suite. More...
 
static struct tls_signature_hash_algorithmtls_signature_hash_algorithm (struct pubkey_algorithm *pubkey, struct digest_algorithm *digest)
 Find TLS signature and hash algorithm. More...
 
static struct pubkey_algorithmtls_signature_hash_pubkey (struct tls_signature_hash_id code)
 Find TLS signature algorithm. More...
 
static struct digest_algorithmtls_signature_hash_digest (struct tls_signature_hash_id code)
 Find TLS hash algorithm. More...
 
static struct tls_named_curvetls_find_named_curve (unsigned int named_curve)
 Identify named curve. More...
 
static void tls_tx_resume (struct tls_connection *tls)
 Resume TX state machine. More...
 
static void tls_restart (struct tls_connection *tls)
 Restart negotiation. More...
 
static int tls_send_handshake (struct tls_connection *tls, const void *data, size_t len)
 Transmit Handshake record. More...
 
static int tls_client_hello (struct tls_connection *tls, int(*action)(struct tls_connection *tls, const void *data, size_t len))
 Digest or transmit Client Hello record. More...
 
static int tls_send_client_hello (struct tls_connection *tls)
 Transmit Client Hello record. More...
 
static int tls_send_certificate (struct tls_connection *tls)
 Transmit Certificate record. More...
 
static int tls_send_client_key_exchange_pubkey (struct tls_connection *tls)
 Transmit Client Key Exchange record using public key exchange. More...
 
static int tls_verify_dh_params (struct tls_connection *tls, size_t param_len)
 Verify Diffie-Hellman parameter signature. More...
 
static int tls_send_client_key_exchange_dhe (struct tls_connection *tls)
 Transmit Client Key Exchange record using DHE key exchange. More...
 
static int tls_send_client_key_exchange_ecdhe (struct tls_connection *tls)
 Transmit Client Key Exchange record using ECDHE key exchange. More...
 
static int tls_send_client_key_exchange (struct tls_connection *tls)
 Transmit Client Key Exchange record. More...
 
static int tls_send_certificate_verify (struct tls_connection *tls)
 Transmit Certificate Verify record. More...
 
static int tls_send_change_cipher (struct tls_connection *tls)
 Transmit Change Cipher record. More...
 
static int tls_send_finished (struct tls_connection *tls)
 Transmit Finished record. More...
 
static int tls_new_change_cipher (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Change Cipher record. More...
 
static int tls_new_alert (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Alert record. More...
 
static int tls_new_hello_request (struct tls_connection *tls, const void *data __unused, size_t len __unused)
 Receive new Hello Request handshake record. More...
 
static int tls_new_server_hello (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Hello handshake record. More...
 
static int tls_new_session_ticket (struct tls_connection *tls, const void *data, size_t len)
 Receive New Session Ticket handshake record. More...
 
static int tls_parse_chain (struct tls_connection *tls, const void *data, size_t len)
 Parse certificate chain. More...
 
static int tls_new_certificate (struct tls_connection *tls, const void *data, size_t len)
 Receive new Certificate handshake record. More...
 
static int tls_new_server_key_exchange (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Key Exchange handshake record. More...
 
static int tls_new_certificate_request (struct tls_connection *tls, const void *data __unused, size_t len __unused)
 Receive new Certificate Request handshake record. More...
 
static int tls_new_server_hello_done (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Hello Done handshake record. More...
 
static int tls_new_finished (struct tls_connection *tls, const void *data, size_t len)
 Receive new Finished handshake record. More...
 
static int tls_new_handshake (struct tls_connection *tls, struct io_buffer *iobuf)
 Receive new Handshake record. More...
 
static int tls_new_unknown (struct tls_connection *tls __unused, struct io_buffer *iobuf)
 Receive new unknown record. More...
 
static int tls_new_data (struct tls_connection *tls, struct list_head *rx_data)
 Receive new data record. More...
 
static int tls_new_record (struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
 Receive new record. More...
 
static void tls_hmac_init (struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
 Initialise HMAC. More...
 
static void tls_hmac_update (struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
 Update HMAC. More...
 
static void tls_hmac_final (struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
 Finalise HMAC. More...
 
static void tls_hmac (struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, const void *data, size_t len, void *hmac)
 Calculate HMAC. More...
 
static void tls_hmac_list (struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, struct list_head *list, void *hmac)
 Calculate HMAC over list of I/O buffers. More...
 
static int tls_verify_padding (struct tls_connection *tls, struct io_buffer *iobuf)
 Verify block padding. More...
 
static int tls_new_ciphertext (struct tls_connection *tls, struct tls_header *tlshdr, struct list_head *rx_data)
 Receive new ciphertext record. More...
 
static size_t tls_plainstream_window (struct tls_connection *tls)
 Check flow control window. More...
 
static int tls_plainstream_deliver (struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Deliver datagram as raw data. More...
 
static int tls_progress (struct tls_connection *tls, struct job_progress *progress)
 Report job progress. More...
 
static int tls_newdata_process_header (struct tls_connection *tls)
 Handle received TLS header. More...
 
static int tls_newdata_process_data (struct tls_connection *tls)
 Handle received TLS data payload. More...
 
static size_t tls_cipherstream_window (struct tls_connection *tls)
 Check flow control window. More...
 
static int tls_cipherstream_deliver (struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *xfer __unused)
 Receive new ciphertext. More...
 
static void tls_validator_done (struct tls_connection *tls, int rc)
 Handle certificate validation completion. More...
 
static void tls_tx_step (struct tls_connection *tls)
 TLS TX state machine. More...
 
static int tls_session (struct tls_connection *tls, const char *name)
 Find or create session for TLS connection. More...
 
int add_tls (struct interface *xfer, const char *name, struct x509_root *root, struct private_key *key)
 Add TLS on an interface. More...
 
 REQUIRING_SYMBOL (add_tls)
 
 REQUIRE_OBJECT (config_crypto)
 

Variables

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

Detailed Description

Transport Layer Security Protocol.

Definition in file tls.c.

Macro Definition Documentation

◆ EINVAL_CHANGE_CIPHER

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )

Definition at line 58 of file tls.c.

◆ EINFO_EINVAL_CHANGE_CIPHER

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

Definition at line 59 of file tls.c.

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

Definition at line 62 of file tls.c.

◆ EINFO_EINVAL_ALERT

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

Definition at line 63 of file tls.c.

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

Definition at line 66 of file tls.c.

◆ EINFO_EINVAL_HELLO

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

Definition at line 67 of file tls.c.

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

Definition at line 70 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATE

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

Definition at line 71 of file tls.c.

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

Definition at line 74 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATES

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

Definition at line 75 of file tls.c.

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

Definition at line 78 of file tls.c.

◆ EINFO_EINVAL_HELLO_DONE

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

Definition at line 79 of file tls.c.

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

Definition at line 82 of file tls.c.

◆ EINFO_EINVAL_FINISHED

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

Definition at line 83 of file tls.c.

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

Definition at line 86 of file tls.c.

◆ EINFO_EINVAL_HANDSHAKE

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

Definition at line 87 of file tls.c.

◆ EINVAL_IV

#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )

Definition at line 90 of file tls.c.

◆ EINFO_EINVAL_IV

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

Definition at line 91 of file tls.c.

◆ EINVAL_PADDING

#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )

Definition at line 94 of file tls.c.

◆ EINFO_EINVAL_PADDING

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

Definition at line 95 of file tls.c.

◆ EINVAL_RX_STATE

#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )

Definition at line 98 of file tls.c.

◆ EINFO_EINVAL_RX_STATE

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

Definition at line 99 of file tls.c.

◆ EINVAL_MAC

#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )

Definition at line 102 of file tls.c.

◆ EINFO_EINVAL_MAC

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

Definition at line 103 of file tls.c.

◆ EINVAL_TICKET

#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )

Definition at line 106 of file tls.c.

◆ EINFO_EINVAL_TICKET

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

Definition at line 107 of file tls.c.

◆ EINVAL_KEY_EXCHANGE

#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )

Definition at line 110 of file tls.c.

◆ EINFO_EINVAL_KEY_EXCHANGE

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

Definition at line 111 of file tls.c.

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

Definition at line 114 of file tls.c.

◆ EINFO_EIO_ALERT

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

Definition at line 115 of file tls.c.

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

Definition at line 118 of file tls.c.

◆ EINFO_ENOMEM_CONTEXT

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

Definition at line 119 of file tls.c.

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

Definition at line 122 of file tls.c.

◆ EINFO_ENOMEM_CERTIFICATE

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

Definition at line 123 of file tls.c.

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

Definition at line 126 of file tls.c.

◆ EINFO_ENOMEM_CHAIN

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

Definition at line 127 of file tls.c.

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

Definition at line 130 of file tls.c.

◆ EINFO_ENOMEM_TX_PLAINTEXT

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

Definition at line 131 of file tls.c.

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

Definition at line 134 of file tls.c.

◆ EINFO_ENOMEM_TX_CIPHERTEXT

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

Definition at line 135 of file tls.c.

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

Definition at line 138 of file tls.c.

◆ EINFO_ENOMEM_RX_DATA

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

Definition at line 139 of file tls.c.

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

Definition at line 142 of file tls.c.

◆ EINFO_ENOMEM_RX_CONCAT

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

Definition at line 143 of file tls.c.

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

Definition at line 146 of file tls.c.

◆ EINFO_ENOTSUP_CIPHER

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

Definition at line 147 of file tls.c.

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

Definition at line 150 of file tls.c.

◆ EINFO_ENOTSUP_NULL

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

Definition at line 151 of file tls.c.

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

Definition at line 154 of file tls.c.

◆ EINFO_ENOTSUP_SIG_HASH

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

Definition at line 155 of file tls.c.

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

Definition at line 158 of file tls.c.

◆ EINFO_ENOTSUP_VERSION

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

Definition at line 159 of file tls.c.

◆ ENOTSUP_CURVE

#define ENOTSUP_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )

Definition at line 162 of file tls.c.

◆ EINFO_ENOTSUP_CURVE

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

Definition at line 163 of file tls.c.

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

Definition at line 166 of file tls.c.

◆ EINFO_EPERM_ALERT

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

Definition at line 167 of file tls.c.

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

Definition at line 170 of file tls.c.

◆ EINFO_EPERM_VERIFY

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

Definition at line 171 of file tls.c.

◆ EPERM_CLIENT_CERT

#define EPERM_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )

Definition at line 174 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 175 of file tls.c.

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

Definition at line 178 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 179 of file tls.c.

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

Definition at line 182 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 183 of file tls.c.

◆ EPERM_KEY_EXCHANGE

#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )

Definition at line 186 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 187 of file tls.c.

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

Definition at line 190 of file tls.c.

◆ EINFO_EPROTO_VERSION

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

Definition at line 191 of file tls.c.

◆ tls_prf_label

#define tls_prf_label (   tls,
  secret,
  secret_len,
  out,
  out_len,
  label,
  ... 
)
Value:
tls_prf ( (tls), (secret), (secret_len), (out), (out_len), \
label, ( sizeof ( label ) - 1 ), __VA_ARGS__, NULL )
A text label widget.
Definition: label.h:16
__be32 out[4]
Definition: CIB_PRM.h:36
static void tls_prf(struct tls_connection *tls, const void *secret, size_t secret_len, void *out, size_t out_len,...)
Generate secure pseudo-random data.
Definition: tls.c:561
#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 617 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 831 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 977 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 1049 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 1091 of file tls.c.

1091  {
1092  struct tls_connection *tls;
1093 
1094  list_for_each_entry ( tls, &session->conn, list )
1095  tls_tx_resume ( tls );
1096 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1082
struct tls_session * session
Session.
Definition: tls.h:428
#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:430
A TLS connection.
Definition: tls.h:423
struct list_head conn
List of connections.
Definition: tls.h:355

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

Referenced by tls_close(), and tls_new_finished().

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

2940  {
2941  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.active;
2942  struct tls_cipher_suite *suite = cipherspec->suite;
2943  struct cipher_algorithm *cipher = suite->cipher;
2944  struct digest_algorithm *digest = suite->digest;
2945  struct {
2946  uint8_t fixed[suite->fixed_iv_len];
2947  uint8_t record[suite->record_iv_len];
2948  } __attribute__ (( packed )) iv;
2949  struct tls_auth_header authhdr;
2950  struct tls_header *tlshdr;
2951  void *plaintext;
2952  size_t plaintext_len;
2953  struct io_buffer *ciphertext;
2954  size_t ciphertext_len;
2955  size_t padding_len;
2956  uint8_t mac[digest->digestsize];
2957  void *tmp;
2958  int rc;
2959 
2960  /* Construct initialisation vector */
2961  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
2962  if ( ( rc = tls_generate_random ( tls, iv.record,
2963  sizeof ( iv.record ) ) ) != 0 ) {
2964  goto err_random;
2965  }
2966 
2967  /* Construct authentication data */
2968  authhdr.seq = cpu_to_be64 ( tls->tx.seq );
2969  authhdr.header.type = type;
2970  authhdr.header.version = htons ( tls->version );
2971  authhdr.header.length = htons ( len );
2972 
2973  /* Calculate padding length */
2974  plaintext_len = ( len + suite->mac_len );
2975  if ( is_block_cipher ( cipher ) ) {
2976  padding_len = ( ( ( cipher->blocksize - 1 ) &
2977  -( plaintext_len + 1 ) ) + 1 );
2978  } else {
2979  padding_len = 0;
2980  }
2981  plaintext_len += padding_len;
2982 
2983  /* Allocate plaintext */
2984  plaintext = malloc ( plaintext_len );
2985  if ( ! plaintext ) {
2986  DBGC ( tls, "TLS %p could not allocate %zd bytes for "
2987  "plaintext\n", tls, plaintext_len );
2989  goto err_plaintext;
2990  }
2991 
2992  /* Assemble plaintext */
2993  tmp = plaintext;
2994  memcpy ( tmp, data, len );
2995  tmp += len;
2996  if ( suite->mac_len )
2997  tls_hmac ( cipherspec, &authhdr, data, len, mac );
2998  memcpy ( tmp, mac, suite->mac_len );
2999  tmp += suite->mac_len;
3000  memset ( tmp, ( padding_len - 1 ), padding_len );
3001  tmp += padding_len;
3002  assert ( tmp == ( plaintext + plaintext_len ) );
3003  DBGC2 ( tls, "Sending plaintext data:\n" );
3004  DBGC2_HD ( tls, plaintext, plaintext_len );
3005 
3006  /* Set initialisation vector */
3007  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv, sizeof ( iv ) );
3008 
3009  /* Process authentication data, if applicable */
3010  if ( is_auth_cipher ( cipher ) ) {
3011  cipher_encrypt ( cipher, cipherspec->cipher_ctx, &authhdr,
3012  NULL, sizeof ( authhdr ) );
3013  }
3014 
3015  /* Allocate ciphertext */
3016  ciphertext_len = ( sizeof ( *tlshdr ) + sizeof ( iv.record ) +
3017  plaintext_len + cipher->authsize );
3018  ciphertext = xfer_alloc_iob ( &tls->cipherstream, ciphertext_len );
3019  if ( ! ciphertext ) {
3020  DBGC ( tls, "TLS %p could not allocate %zd bytes for "
3021  "ciphertext\n", tls, ciphertext_len );
3023  goto err_ciphertext;
3024  }
3025 
3026  /* Assemble ciphertext */
3027  tlshdr = iob_put ( ciphertext, sizeof ( *tlshdr ) );
3028  tlshdr->type = type;
3029  tlshdr->version = htons ( tls->version );
3030  tlshdr->length = htons ( ciphertext_len - sizeof ( *tlshdr ) );
3031  memcpy ( iob_put ( ciphertext, sizeof ( iv.record ) ), iv.record,
3032  sizeof ( iv.record ) );
3033  cipher_encrypt ( cipher, cipherspec->cipher_ctx, plaintext,
3034  iob_put ( ciphertext, plaintext_len ), plaintext_len );
3035  cipher_auth ( cipher, cipherspec->cipher_ctx,
3036  iob_put ( ciphertext, cipher->authsize ) );
3037  assert ( iob_len ( ciphertext ) == ciphertext_len );
3038 
3039  /* Free plaintext as soon as possible to conserve memory */
3040  free ( plaintext );
3041  plaintext = NULL;
3042 
3043  /* Send ciphertext */
3044  if ( ( rc = xfer_deliver_iob ( &tls->cipherstream,
3045  iob_disown ( ciphertext ) ) ) != 0 ) {
3046  DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
3047  tls, strerror ( rc ) );
3048  goto err_deliver;
3049  }
3050 
3051  /* Update TX state machine to next record */
3052  tls->tx.seq += 1;
3053 
3054  assert ( plaintext == NULL );
3055  assert ( ciphertext == NULL );
3056  return 0;
3057 
3058  err_deliver:
3059  free_iob ( ciphertext );
3060  err_ciphertext:
3061  free ( plaintext );
3062  err_plaintext:
3063  err_random:
3064  return rc;
3065 }
#define __attribute__(x)
Definition: compiler.h:10
static int is_auth_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:266
size_t blocksize
Block size.
Definition: crypto.h:60
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:207
uint8_t type
Content type.
Definition: tls.h:33
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:40
struct 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:144
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:247
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
unsigned long tmp
Definition: linux_pci.h:63
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:235
size_t authsize
Authentication tag size.
Definition: crypto.h:74
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
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:253
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:197
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:205
A TLS cipher suite.
Definition: tls.h:189
#define ENOMEM_TX_CIPHERTEXT
Definition: tls.c:134
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint64_t seq
Sequence number.
Definition: tls.h:363
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:443
#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
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition: crypto.h:225
uint8_t mac_len
MAC length.
Definition: tls.h:209
unsigned char uint8_t
Definition: stdint.h:10
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:599
A TLS header.
Definition: tls.h:28
struct tls_tx tx
Transmit state.
Definition: tls.h:459
#define ENOMEM_TX_PLAINTEXT
Definition: tls.c:130
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:2896
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:26
uint16_t version
Protocol version.
Definition: tls.h:38
A message digest algorithm.
Definition: crypto.h:18
uint16_t version
Protocol version.
Definition: tls.h:446
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define cpu_to_be64(value)
Definition: byteswap.h:111
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:263
A cipher algorithm.
Definition: crypto.h:50
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition: crypto.h:251
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:195
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:454
uint32_t len
Length.
Definition: ena.h:14
#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:257
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:261
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33

References __attribute__, tls_cipherspec_pair::active, assert(), cipher_algorithm::authsize, cipher_algorithm::blocksize, tls_cipher_suite::cipher, cipher_auth(), tls_cipherspec::cipher_ctx, cipher_encrypt, cipher_setiv(), tls_tx::cipherspec, tls_connection::cipherstream, cpu_to_be64, data, DBGC, DBGC2, DBGC2_HD, tls_cipher_suite::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, is_auth_cipher(), is_block_cipher(), 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, tls_tx::seq, strerror(), tls_cipherspec::suite, tls_generate_random(), tls_hmac(), tmp, tls_connection::tx, 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 231 of file tls.c.

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

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

242  {
243 
244  field24->high = ( value >> 16 );
245  field24->low = cpu_to_be16 ( value );
246 }
#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:220
uint8_t high
High byte.
Definition: tls.c:218

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

254  {
255  return ( ( ! is_pending ( &tls->client.negotiation ) ) &&
256  ( ! is_pending ( &tls->server.negotiation ) ) );
257 }
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:397
struct tls_server server
Server state.
Definition: tls.h:465
struct tls_client client
Client state.
Definition: tls.h:463
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:419

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

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

◆ tls_version()

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

Check for TLS version.

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

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

Definition at line 271 of file tls.c.

271  {
272  return ( ( TLS_VERSION_MIN >= version ) ||
273  ( tls->version >= version ) );
274 }
u32 version
Driver version.
Definition: ath9k_hw.c:1983
uint16_t version
Protocol version.
Definition: tls.h:446
#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 288 of file tls.c.

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

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

◆ md5_sha1_update()

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

Accumulate data with MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context
dataData
lenLength of data

Definition at line 302 of file tls.c.

302  {
303  struct md5_sha1_context *context = ctx;
304 
305  digest_update ( &md5_algorithm, context->md5, data, len );
306  digest_update ( &sha1_algorithm, context->sha1, data, len );
307 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:208
An MD5+SHA1 context.
Definition: tls.h:308
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:312
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:310
uint32_t len
Length.
Definition: ena.h:14
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257

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

◆ md5_sha1_final()

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

Generate MD5+SHA1 digest.

Parameters
ctxMD5+SHA1 context
outOutput buffer

Definition at line 315 of file tls.c.

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

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

◆ free_tls_session()

static void free_tls_session ( struct refcnt refcnt)
static

Free TLS session.

Parameters
refcntReference counter

Definition at line 353 of file tls.c.

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

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

Referenced by tls_session().

◆ free_tls()

static void free_tls ( struct refcnt refcnt)
static

Free TLS connection.

Parameters
refcntReference counter

Definition at line 377 of file tls.c.

377  {
378  struct tls_connection *tls =
380  struct tls_session *session = tls->session;
381  struct io_buffer *iobuf;
382  struct io_buffer *tmp;
383 
384  /* Free dynamically-allocated resources */
385  free ( tls->new_session_ticket );
386  tls_clear_cipher ( tls, &tls->tx.cipherspec.active );
387  tls_clear_cipher ( tls, &tls->tx.cipherspec.pending );
388  tls_clear_cipher ( tls, &tls->rx.cipherspec.active );
389  tls_clear_cipher ( tls, &tls->rx.cipherspec.pending );
390  free ( tls->server.exchange );
391  free ( tls->handshake_ctx );
392  list_for_each_entry_safe ( iobuf, tmp, &tls->rx.data, list ) {
393  list_del ( &iobuf->list );
394  free_iob ( iobuf );
395  }
396  free_iob ( tls->rx.handshake );
397  privkey_put ( tls->client.key );
398  x509_chain_put ( tls->client.chain );
399  x509_chain_put ( tls->server.chain );
400  x509_root_put ( tls->server.root );
401 
402  /* Drop reference to session */
403  assert ( list_empty ( &tls->list ) );
404  ref_put ( &session->refcnt );
405 
406  /* Free TLS structure itself */
407  free ( tls );
408 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:299
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition: privkey.h:41
struct tls_session * session
Session.
Definition: tls.h:428
struct list_head data
List of received data buffers.
Definition: tls.h:383
struct io_buffer * handshake
Received handshake fragment.
Definition: tls.h:385
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:373
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:405
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition: x509.h:403
A reference counter.
Definition: refcnt.h:26
struct private_key * key
Private key (if used)
Definition: tls.h:393
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:63
struct tls_server server
Server state.
Definition: tls.h:465
struct refcnt refcnt
Reference counter.
Definition: tls.h:332
#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:452
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
void * new_session_ticket
New session ticket.
Definition: tls.h:436
struct tls_client client
Client state.
Definition: tls.h:463
struct list_head list
List of connections within the same session.
Definition: tls.h:430
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct x509_chain * chain
Certificate chain.
Definition: tls.h:411
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:265
struct tls_rx rx
Receive state.
Definition: tls.h:461
struct tls_tx tx
Transmit state.
Definition: tls.h:459
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
A TLS session.
Definition: tls.h:330
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:395
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:263
A TLS connection.
Definition: tls.h:423
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
struct x509_root * root
Root of trust.
Definition: tls.h:409

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

Referenced by add_tls().

◆ tls_close()

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

Finish with TLS connection.

Parameters
tlsTLS connection
rcStatus code

Definition at line 416 of file tls.c.

416  {
417 
418  /* Remove pending operations, if applicable */
419  pending_put ( &tls->client.negotiation );
420  pending_put ( &tls->server.negotiation );
421  pending_put ( &tls->server.validation );
422 
423  /* Remove process */
424  process_del ( &tls->tx.process );
425 
426  /* Close all interfaces */
427  intf_shutdown ( &tls->cipherstream, rc );
428  intf_shutdown ( &tls->plainstream, rc );
429  intf_shutdown ( &tls->server.validator, rc );
430 
431  /* Remove from session */
432  list_del ( &tls->list );
433  INIT_LIST_HEAD ( &tls->list );
434 
435  /* Resume all other connections, in case we were the lead connection */
436  tls_tx_resume_all ( tls->session );
437 }
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:1091
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:278
struct process process
Transmit process.
Definition: tls.h:367
struct tls_session * session
Session.
Definition: tls.h:428
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:397
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
struct tls_server server
Server state.
Definition: tls.h:465
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
struct tls_client client
Client state.
Definition: tls.h:463
struct list_head list
List of connections within the same session.
Definition: tls.h:430
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:443
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:419
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:417
struct tls_tx tx
Transmit state.
Definition: tls.h:459
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
struct interface validator
Certificate validator.
Definition: tls.h:415
struct interface plainstream
Plaintext stream.
Definition: tls.h:441

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

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

◆ tls_generate_random()

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

Generate random data.

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

Definition at line 454 of file tls.c.

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

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

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

Referenced by tls_p_hash_va().

◆ tls_p_hash_va()

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

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

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

Definition at line 499 of file tls.c.

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

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

Referenced by tls_prf().

◆ tls_prf()

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

Generate secure pseudo-random data.

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

Definition at line 561 of file tls.c.

562  {
563  va_list seeds;
564  va_list tmp;
565  size_t subsecret_len;
566  const void *md5_secret;
567  const void *sha1_secret;
568  uint8_t buf[out_len];
569  unsigned int i;
570 
571  va_start ( seeds, out_len );
572 
573  if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
574  /* Use handshake digest PRF for TLSv1.2 and later */
575  tls_p_hash_va ( tls, tls->handshake_digest, secret, secret_len,
576  out, out_len, seeds );
577  } else {
578  /* Use combination of P_MD5 and P_SHA-1 for TLSv1.1
579  * and earlier
580  */
581 
582  /* Split secret into two, with an overlap of up to one byte */
583  subsecret_len = ( ( secret_len + 1 ) / 2 );
584  md5_secret = secret;
585  sha1_secret = ( secret + secret_len - subsecret_len );
586 
587  /* Calculate MD5 portion */
588  va_copy ( tmp, seeds );
589  tls_p_hash_va ( tls, &md5_algorithm, md5_secret,
590  subsecret_len, out, out_len, seeds );
591  va_end ( tmp );
592 
593  /* Calculate SHA1 portion */
594  va_copy ( tmp, seeds );
595  tls_p_hash_va ( tls, &sha1_algorithm, sha1_secret,
596  subsecret_len, buf, out_len, seeds );
597  va_end ( tmp );
598 
599  /* XOR the two portions together into the final output buffer */
600  for ( i = 0 ; i < out_len ; i++ )
601  *( ( uint8_t * ) out + i ) ^= buf[i];
602  }
603 
604  va_end ( seeds );
605 }
#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:63
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:271
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:450
__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:499
#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 637 of file tls.c.

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

References tls_connection::client, DBGC, DBGC_HD, tls_connection::master_secret, tls_client::random, tls_server::random, tls_connection::server, 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 665 of file tls.c.

665  {
666  struct tls_cipherspec *tx_cipherspec = &tls->tx.cipherspec.pending;
667  struct tls_cipherspec *rx_cipherspec = &tls->rx.cipherspec.pending;
668  size_t hash_size = tx_cipherspec->suite->mac_len;
669  size_t key_size = tx_cipherspec->suite->key_len;
670  size_t iv_size = tx_cipherspec->suite->fixed_iv_len;
671  size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
672  uint8_t key_block[total];
673  uint8_t *key;
674  int rc;
675 
676  /* Generate key block */
677  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
678  key_block, sizeof ( key_block ), "key expansion",
679  &tls->server.random, sizeof ( tls->server.random ),
680  &tls->client.random, sizeof ( tls->client.random ) );
681 
682  /* Split key block into portions */
683  key = key_block;
684 
685  /* TX MAC secret */
686  memcpy ( tx_cipherspec->mac_secret, key, hash_size );
687  DBGC ( tls, "TLS %p TX MAC secret:\n", tls );
688  DBGC_HD ( tls, key, hash_size );
689  key += hash_size;
690 
691  /* RX MAC secret */
692  memcpy ( rx_cipherspec->mac_secret, key, hash_size );
693  DBGC ( tls, "TLS %p RX MAC secret:\n", tls );
694  DBGC_HD ( tls, key, hash_size );
695  key += hash_size;
696 
697  /* TX key */
698  if ( ( rc = cipher_setkey ( tx_cipherspec->suite->cipher,
699  tx_cipherspec->cipher_ctx,
700  key, key_size ) ) != 0 ) {
701  DBGC ( tls, "TLS %p could not set TX key: %s\n",
702  tls, strerror ( rc ) );
703  return rc;
704  }
705  DBGC ( tls, "TLS %p TX key:\n", tls );
706  DBGC_HD ( tls, key, key_size );
707  key += key_size;
708 
709  /* RX key */
710  if ( ( rc = cipher_setkey ( rx_cipherspec->suite->cipher,
711  rx_cipherspec->cipher_ctx,
712  key, key_size ) ) != 0 ) {
713  DBGC ( tls, "TLS %p could not set TX key: %s\n",
714  tls, strerror ( rc ) );
715  return rc;
716  }
717  DBGC ( tls, "TLS %p RX key:\n", tls );
718  DBGC_HD ( tls, key, key_size );
719  key += key_size;
720 
721  /* TX initialisation vector */
722  memcpy ( tx_cipherspec->fixed_iv, key, iv_size );
723  DBGC ( tls, "TLS %p TX IV:\n", tls );
724  DBGC_HD ( tls, key, iv_size );
725  key += iv_size;
726 
727  /* RX initialisation vector */
728  memcpy ( rx_cipherspec->fixed_iv, key, iv_size );
729  DBGC ( tls, "TLS %p RX IV:\n", tls );
730  DBGC_HD ( tls, key, iv_size );
731  key += iv_size;
732 
733  assert ( ( key_block + total ) == key );
734 
735  return 0;
736 }
uint8_t random[32]
Random bytes.
Definition: tls.h:403
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:373
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:247
struct tls_server server
Server state.
Definition: tls.h:465
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:463
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:253
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:205
uint8_t master_secret[48]
Master secret.
Definition: tls.h:448
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
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:209
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:265
struct tls_rx rx
Receive state.
Definition: tls.h:461
struct tls_tx tx
Transmit state.
Definition: tls.h:459
struct tls_client_random random
Random bytes.
Definition: tls.h:391
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:195
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:617
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:257
union @383 key
Sense key.
Definition: scsi.h:18
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:219
void * mac_secret
MAC secret.
Definition: tls.h:255
uint8_t key_len
Key length.
Definition: tls.h:203

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

Referenced by tls_new_server_hello(), and tls_send_client_key_exchange().

◆ tls_clear_handshake()

static void tls_clear_handshake ( struct tls_connection tls)
static

Clear handshake digest algorithm.

Parameters
tlsTLS connection

Definition at line 750 of file tls.c.

750  {
751 
752  /* Select null digest algorithm */
754 
755  /* Free any existing context */
756  free ( tls->handshake_ctx );
757  tls->handshake_ctx = NULL;
758 }
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:452
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:450
#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 767 of file tls.c.

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

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

Referenced by tls_select_cipher().

◆ tls_add_handshake()

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

Add handshake record to verification hash.

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

Definition at line 791 of file tls.c.

792  {
793  struct digest_algorithm *digest = tls->handshake_digest;
794 
795  digest_update ( digest, tls->handshake_ctx, data, len );
796  return 0;
797 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:208
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:452
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:450
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint32_t len
Length.
Definition: ena.h:14

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

Referenced by tls_new_handshake(), tls_new_server_hello(), and tls_send_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 807 of file tls.c.

807  {
808  struct digest_algorithm *digest = tls->handshake_digest;
809  uint8_t ctx[ digest->ctxsize ];
810 
811  memcpy ( ctx, tls->handshake_ctx, sizeof ( ctx ) );
812  digest_final ( digest, ctx, out );
813 }
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:214
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
__be32 out[4]
Definition: CIB_PRM.h:36
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:452
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned char uint8_t
Definition: stdint.h:10
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:450
size_t ctxsize
Context size.
Definition: crypto.h:22
A message digest algorithm.
Definition: crypto.h:18

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

Referenced by tls_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 840 of file tls.c.

840  {
841  struct tls_cipher_suite *suite;
842 
843  /* Identify cipher suite */
845  if ( suite->code == cipher_suite )
846  return suite;
847  }
848 
849  return NULL;
850 }
A TLS cipher suite.
Definition: tls.h:189
#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:213
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:201

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

858  {
859 
860  free ( cipherspec->dynamic );
861  memset ( cipherspec, 0, sizeof ( *cipherspec ) );
862  cipherspec->suite = &tls_cipher_suite_null;
863 }
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:823
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:251
void * memset(void *dest, int character, size_t len) __nonnull

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

◆ tls_set_cipher()

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

Set cipher suite.

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

Definition at line 873 of file tls.c.

875  {
876  struct cipher_algorithm *cipher = suite->cipher;
877  size_t total;
878  void *dynamic;
879 
880  /* Clear out old cipher contents, if any */
881  tls_clear_cipher ( tls, cipherspec );
882 
883  /* Allocate dynamic storage */
884  total = ( cipher->ctxsize + suite->mac_len + suite->fixed_iv_len );
885  dynamic = zalloc ( total );
886  if ( ! dynamic ) {
887  DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto "
888  "context\n", tls, total );
889  return -ENOMEM_CONTEXT;
890  }
891 
892  /* Assign storage */
893  cipherspec->dynamic = dynamic;
894  cipherspec->cipher_ctx = dynamic; dynamic += cipher->ctxsize;
895  cipherspec->mac_secret = dynamic; dynamic += suite->mac_len;
896  cipherspec->fixed_iv = dynamic; dynamic += suite->fixed_iv_len;
897  assert ( ( cipherspec->dynamic + total ) == dynamic );
898 
899  /* Store parameters */
900  cipherspec->suite = suite;
901 
902  return 0;
903 }
#define DBGC(...)
Definition: compiler.h:505
#define ENOMEM_CONTEXT
Definition: tls.c:118
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:253
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:205
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:640
uint8_t mac_len
MAC length.
Definition: tls.h:209
size_t ctxsize
Context size.
Definition: crypto.h:54
A cipher algorithm.
Definition: crypto.h:50
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:195
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:251
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:257
void * mac_secret
MAC secret.
Definition: tls.h:255

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

Referenced by tls_select_cipher().

◆ tls_select_cipher()

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

Select next cipher suite.

Parameters
tlsTLS connection
cipher_suiteCipher suite specification
Return values
rcReturn status code

Definition at line 912 of file tls.c.

913  {
914  struct tls_cipher_suite *suite;
915  struct digest_algorithm *digest;
916  int rc;
917 
918  /* Identify cipher suite */
919  suite = tls_find_cipher_suite ( cipher_suite );
920  if ( ! suite ) {
921  DBGC ( tls, "TLS %p does not support cipher %04x\n",
922  tls, ntohs ( cipher_suite ) );
923  return -ENOTSUP_CIPHER;
924  }
925 
926  /* Set handshake digest algorithm */
927  digest = ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ?
928  suite->handshake : &md5_sha1_algorithm );
929  if ( ( rc = tls_select_handshake ( tls, digest ) ) != 0 )
930  return rc;
931 
932  /* Set ciphers */
933  if ( ( rc = tls_set_cipher ( tls, &tls->tx.cipherspec.pending,
934  suite ) ) != 0 )
935  return rc;
936  if ( ( rc = tls_set_cipher ( tls, &tls->rx.cipherspec.pending,
937  suite ) ) != 0 )
938  return rc;
939 
940  DBGC ( tls, "TLS %p selected %s-%s-%s-%d-%s\n", tls,
941  suite->exchange->name, suite->pubkey->name,
942  suite->cipher->name, ( suite->key_len * 8 ),
943  suite->digest->name );
944 
945  return 0;
946 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:191
static struct tls_cipher_suite * tls_find_cipher_suite(unsigned int cipher_suite)
Identify cipher suite.
Definition: tls.c:840
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:373
#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:178
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:193
#define ENOTSUP_CIPHER
Definition: tls.c:146
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:197
A TLS cipher suite.
Definition: tls.h:189
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:324
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:265
struct tls_rx rx
Receive state.
Definition: tls.h:461
struct tls_tx tx
Transmit state.
Definition: tls.h:459
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:271
const char * name
Algorithm name.
Definition: crypto.h:20
struct digest_algorithm * handshake
Handshake digest algorithm (for TLSv1.2 and above)
Definition: tls.h:199
A message digest algorithm.
Definition: crypto.h:18
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:195
const char * name
Algorithm name.
Definition: crypto.h:52
static int tls_set_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
Set cipher suite.
Definition: tls.c:873
static int tls_select_handshake(struct tls_connection *tls, struct digest_algorithm *digest)
Select handshake digest algorithm.
Definition: tls.c:767
const char * name
Algorithm name.
Definition: crypto.h:123
uint8_t key_len
Key length.
Definition: tls.h:203

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

Referenced by tls_new_server_hello().

◆ tls_change_cipher()

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

Activate next cipher suite.

Parameters
tlsTLS connection
pairCipher specification pair
Return values
rcReturn status code

Definition at line 955 of file tls.c.

956  {
957 
958  /* Sanity check */
959  if ( pair->pending.suite == &tls_cipher_suite_null ) {
960  DBGC ( tls, "TLS %p refusing to use null cipher\n", tls );
961  return -ENOTSUP_NULL;
962  }
963 
964  tls_clear_cipher ( tls, &pair->active );
965  memswap ( &pair->active, &pair->pending, sizeof ( pair->active ) );
966  return 0;
967 }
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:823
#define DBGC(...)
Definition: compiler.h:505
#define ENOTSUP_NULL
Definition: tls.c:150
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:265
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:263
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)

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

Referenced by tls_new_change_cipher(), and tls_tx_step().

◆ tls_signature_hash_algorithm()

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

Find TLS signature and hash algorithm.

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

Definition at line 988 of file tls.c.

989  {
990  struct tls_signature_hash_algorithm *sig_hash;
991 
992  /* Identify signature and hash algorithm */
994  if ( ( sig_hash->pubkey == pubkey ) &&
995  ( sig_hash->digest == digest ) ) {
996  return sig_hash;
997  }
998  }
999 
1000  return NULL;
1001 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:279
A TLS signature algorithm.
Definition: tls.h:277
#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:291
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:281
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_send_certificate_verify().

◆ tls_signature_hash_pubkey()

static struct pubkey_algorithm* tls_signature_hash_pubkey ( struct tls_signature_hash_id  code)
static

Find TLS signature algorithm.

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

Definition at line 1010 of file tls.c.

1010  {
1011  struct tls_signature_hash_algorithm *sig_hash;
1012 
1013  /* Identify signature and hash algorithm */
1015  if ( sig_hash->code.signature == code.signature )
1016  return sig_hash->pubkey;
1017  }
1018 
1019  return NULL;
1020 }
static unsigned int code
Response code.
Definition: hyperv.h:26
A TLS signature algorithm.
Definition: tls.h:277
#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:273
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:291
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:283
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:281
#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 1029 of file tls.c.

1029  {
1030  struct tls_signature_hash_algorithm *sig_hash;
1031 
1032  /* Identify signature and hash algorithm */
1034  if ( sig_hash->code.hash == code.hash )
1035  return sig_hash->digest;
1036  }
1037 
1038  return NULL;
1039 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:279
static unsigned int code
Response code.
Definition: hyperv.h:26
A TLS signature algorithm.
Definition: tls.h:277
uint8_t hash
Hash algorithm.
Definition: tls.h:271
#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:291
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:283
#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 1058 of file tls.c.

1058  {
1059  struct tls_named_curve *curve;
1060 
1061  /* Identify named curve */
1063  if ( curve->code == named_curve )
1064  return curve;
1065  }
1066 
1067  return NULL;
1068 }
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:239
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:229
#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:227
#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 1082 of file tls.c.

1082  {
1083  process_add ( &tls->tx.process );
1084 }
struct process process
Transmit process.
Definition: tls.h:367
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
struct tls_tx tx
Transmit state.
Definition: tls.h:459

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

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

◆ tls_restart()

static void tls_restart ( struct tls_connection tls)
static

Restart negotiation.

Parameters
tlsTLS connection

Definition at line 1103 of file tls.c.

1103  {
1104 
1105  /* Sanity check */
1106  assert ( ! tls->tx.pending );
1107  assert ( ! is_pending ( &tls->client.negotiation ) );
1108  assert ( ! is_pending ( &tls->server.negotiation ) );
1109  assert ( ! is_pending ( &tls->server.validation ) );
1110 
1111  /* (Re)start negotiation */
1113  tls_tx_resume ( tls );
1114  pending_get ( &tls->client.negotiation );
1115  pending_get ( &tls->server.negotiation );
1116 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1082
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:397
struct tls_server server
Server state.
Definition: tls.h:465
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:463
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:419
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:417
unsigned int pending
Pending transmissions.
Definition: tls.h:365
struct tls_tx tx
Transmit state.
Definition: tls.h:459
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45

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

Referenced by add_tls(), and tls_new_hello_request().

◆ tls_send_handshake()

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

Transmit Handshake record.

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

Definition at line 1126 of file tls.c.

1127  {
1128 
1129  /* Add to handshake digest */
1130  tls_add_handshake ( tls, data, len );
1131 
1132  /* Send record */
1133  return tls_send_plaintext ( tls, TLS_TYPE_HANDSHAKE, data, len );
1134 }
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:791
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:2939
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:62
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint32_t len
Length.
Definition: ena.h:14

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

1146  {
1147  struct tls_session *session = tls->session;
1148  size_t name_len = strlen ( session->name );
1149  struct {
1150  uint16_t type;
1151  uint16_t len;
1152  struct {
1153  uint16_t len;
1154  struct {
1155  uint8_t type;
1156  uint16_t len;
1157  uint8_t name[name_len];
1158  } __attribute__ (( packed )) list[1];
1159  } __attribute__ (( packed )) data;
1160  } __attribute__ (( packed )) *server_name_ext;
1161  struct {
1162  uint16_t type;
1163  uint16_t len;
1164  struct {
1165  uint8_t max;
1166  } __attribute__ (( packed )) data;
1167  } __attribute__ (( packed )) *max_fragment_length_ext;
1168  struct {
1169  uint16_t type;
1170  uint16_t len;
1171  struct {
1172  uint16_t len;
1173  struct tls_signature_hash_id
1175  } __attribute__ (( packed )) data;
1176  } __attribute__ (( packed )) *signature_algorithms_ext;
1177  struct {
1178  uint16_t type;
1179  uint16_t len;
1180  struct {
1181  uint8_t len;
1183  sizeof ( tls->verify.client ) :0 ];
1184  } __attribute__ (( packed )) data;
1185  } __attribute__ (( packed )) *renegotiation_info_ext;
1186  struct {
1187  uint16_t type;
1188  uint16_t len;
1189  struct {
1190  uint8_t data[session->ticket_len];
1191  } __attribute__ (( packed )) data;
1192  } __attribute__ (( packed )) *session_ticket_ext;
1193  struct {
1194  uint16_t type;
1195  uint16_t len;
1196  struct {
1197  uint16_t len;
1199  } __attribute__ (( packed )) data;
1200  } __attribute__ (( packed )) *named_curve_ext;
1201  struct {
1202  typeof ( *server_name_ext ) server_name;
1203  typeof ( *max_fragment_length_ext ) max_fragment_length;
1204  typeof ( *signature_algorithms_ext ) signature_algorithms;
1205  typeof ( *renegotiation_info_ext ) renegotiation_info;
1206  typeof ( *session_ticket_ext ) session_ticket;
1207  typeof ( *named_curve_ext )
1208  named_curve[TLS_NUM_NAMED_CURVES ? 1 : 0];
1209  } __attribute__ (( packed )) *extensions;
1210  struct {
1211  uint32_t type_length;
1212  uint16_t version;
1213  uint8_t random[32];
1214  uint8_t session_id_len;
1215  uint8_t session_id[tls->session_id_len];
1216  uint16_t cipher_suite_len;
1217  uint16_t cipher_suites[TLS_NUM_CIPHER_SUITES];
1218  uint8_t compression_methods_len;
1219  uint8_t compression_methods[1];
1220  uint16_t extensions_len;
1221  typeof ( *extensions ) extensions;
1222  } __attribute__ (( packed )) hello;
1223  struct tls_cipher_suite *suite;
1224  struct tls_signature_hash_algorithm *sighash;
1225  struct tls_named_curve *curve;
1226  unsigned int i;
1227 
1228  /* Construct record */
1229  memset ( &hello, 0, sizeof ( hello ) );
1230  hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) |
1231  htonl ( sizeof ( hello ) -
1232  sizeof ( hello.type_length ) ) );
1233  hello.version = htons ( TLS_VERSION_MAX );
1234  memcpy ( &hello.random, &tls->client.random, sizeof ( hello.random ) );
1235  hello.session_id_len = tls->session_id_len;
1236  memcpy ( hello.session_id, tls->session_id,
1237  sizeof ( hello.session_id ) );
1238  hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) );
1239  i = 0 ; for_each_table_entry ( suite, TLS_CIPHER_SUITES )
1240  hello.cipher_suites[i++] = suite->code;
1241  hello.compression_methods_len = sizeof ( hello.compression_methods );
1242  hello.extensions_len = htons ( sizeof ( hello.extensions ) );
1243  extensions = &hello.extensions;
1244 
1245  /* Construct server name extension */
1246  server_name_ext = &extensions->server_name;
1247  server_name_ext->type = htons ( TLS_SERVER_NAME );
1248  server_name_ext->len = htons ( sizeof ( server_name_ext->data ) );
1249  server_name_ext->data.len
1250  = htons ( sizeof ( server_name_ext->data.list ) );
1251  server_name_ext->data.list[0].type = TLS_SERVER_NAME_HOST_NAME;
1252  server_name_ext->data.list[0].len
1253  = htons ( sizeof ( server_name_ext->data.list[0].name ) );
1254  memcpy ( server_name_ext->data.list[0].name, session->name,
1255  sizeof ( server_name_ext->data.list[0].name ) );
1256 
1257  /* Construct maximum fragment length extension */
1258  max_fragment_length_ext = &extensions->max_fragment_length;
1259  max_fragment_length_ext->type = htons ( TLS_MAX_FRAGMENT_LENGTH );
1260  max_fragment_length_ext->len
1261  = htons ( sizeof ( max_fragment_length_ext->data ) );
1262  max_fragment_length_ext->data.max = TLS_MAX_FRAGMENT_LENGTH_4096;
1263 
1264  /* Construct supported signature algorithms extension */
1265  signature_algorithms_ext = &extensions->signature_algorithms;
1266  signature_algorithms_ext->type = htons ( TLS_SIGNATURE_ALGORITHMS );
1267  signature_algorithms_ext->len
1268  = htons ( sizeof ( signature_algorithms_ext->data ) );
1269  signature_algorithms_ext->data.len
1270  = htons ( sizeof ( signature_algorithms_ext->data.code ) );
1271  i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
1272  signature_algorithms_ext->data.code[i++] = sighash->code;
1273 
1274  /* Construct renegotiation information extension */
1275  renegotiation_info_ext = &extensions->renegotiation_info;
1276  renegotiation_info_ext->type = htons ( TLS_RENEGOTIATION_INFO );
1277  renegotiation_info_ext->len
1278  = htons ( sizeof ( renegotiation_info_ext->data ) );
1279  renegotiation_info_ext->data.len
1280  = sizeof ( renegotiation_info_ext->data.data );
1281  memcpy ( renegotiation_info_ext->data.data, tls->verify.client,
1282  sizeof ( renegotiation_info_ext->data.data ) );
1283 
1284  /* Construct session ticket extension */
1285  session_ticket_ext = &extensions->session_ticket;
1286  session_ticket_ext->type = htons ( TLS_SESSION_TICKET );
1287  session_ticket_ext->len
1288  = htons ( sizeof ( session_ticket_ext->data ) );
1289  memcpy ( session_ticket_ext->data.data, session->ticket,
1290  sizeof ( session_ticket_ext->data.data ) );
1291 
1292  /* Construct named curves extension, if applicable */
1293  if ( sizeof ( extensions->named_curve ) ) {
1294  named_curve_ext = &extensions->named_curve[0];
1295  named_curve_ext->type = htons ( TLS_NAMED_CURVE );
1296  named_curve_ext->len
1297  = htons ( sizeof ( named_curve_ext->data ) );
1298  named_curve_ext->data.len
1299  = htons ( sizeof ( named_curve_ext->data.code ) );
1301  named_curve_ext->data.code[i++] = curve->code;
1302  }
1303 
1304  return action ( tls, &hello, sizeof ( hello ) );
1305 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:456
#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:831
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:141
#define max(x, y)
Definition: ath.h:39
struct tls_session * session
Session.
Definition: tls.h:428
#define TLS_NUM_NAMED_CURVES
Number of supported named curves.
Definition: tls.c:1049
uint32_t type
Operating system type.
Definition: ena.h:12
#define TLS_CLIENT_HELLO
Definition: tls.h:69
uint8_t session_id[32]
Session ID.
Definition: tls.h:432
static unsigned int code
Response code.
Definition: hyperv.h:26
#define htonl(value)
Definition: byteswap.h:133
#define TLS_MAX_FRAGMENT_LENGTH
Definition: tls.h:122
#define TLS_NAMED_CURVE
Definition: tls.h:129
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Driver version.
Definition: ath9k_hw.c:1983
struct tls_client client
Client state.
Definition: tls.h:463
#define TLS_SESSION_TICKET
Definition: tls.h:138
A TLS cipher suite.
Definition: tls.h:189
#define TLS_SERVER_NAME
Definition: tls.h:118
A TLS signature algorithm.
Definition: tls.h:277
size_t ticket_len
Length of session ticket.
Definition: tls.h:350
struct list_head list
List of sessions.
Definition: tls.h:334
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:239
#define TLS_NUM_SIG_HASH_ALGORITHMS
Number of supported signature and hash algorithms.
Definition: tls.c:977
void * ticket
Session ticket.
Definition: tls.h:348
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:229
#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:291
uint16_t hello
Hello time.
Definition: stp.h:38
unsigned int uint32_t
Definition: stdint.h:12
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:283
#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:154
A TLS session.
Definition: tls.h:330
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct tls_client_random random
Random bytes.
Definition: tls.h:391
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:454
A TLS named curve.
Definition: tls.h:227
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:337
A TLS signature and hash algorithm identifier.
Definition: tls.h:269
size_t session_id_len
Length of session ID.
Definition: tls.h:434
uint32_t len
Length.
Definition: ena.h:14
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:213
#define htons(value)
Definition: byteswap.h:135
#define TLS_SIGNATURE_ALGORITHMS
Definition: tls.h:135
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:201
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, tls_verify_data::client, tls_connection::client, code, tls_cipher_suite::code, tls_signature_hash_algorithm::code, cpu_to_le32, tls_named_curve::curve, data, for_each_table_entry, hello, htonl, htons, len, tls_session::list, max, memcpy(), memset(), tls_session::name, random(), tls_client::random, tls_connection::secure_renegotiation, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, strlen(), tls_session::ticket, tls_session::ticket_len, TLS_CIPHER_SUITES, TLS_CLIENT_HELLO, TLS_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 1313 of file tls.c.

1313  {
1314 
1315  return tls_client_hello ( tls, tls_send_handshake );
1316 }
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1126
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:1143

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

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

References __attribute__, tls_client::chain, tls_connection::client, 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 1386 of file tls.c.

1386  {
1387  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1388  struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1389  size_t max_len = pubkey_max_len ( pubkey, &tls->server.key );
1390  struct {
1391  uint16_t version;
1392  uint8_t random[46];
1393  } __attribute__ (( packed )) pre_master_secret;
1394  struct {
1395  uint32_t type_length;
1396  uint16_t encrypted_pre_master_secret_len;
1397  uint8_t encrypted_pre_master_secret[max_len];
1398  } __attribute__ (( packed )) key_xchg;
1399  size_t unused;
1400  int len;
1401  int rc;
1402 
1403  /* Generate pre-master secret */
1404  pre_master_secret.version = htons ( TLS_VERSION_MAX );
1405  if ( ( rc = tls_generate_random ( tls, &pre_master_secret.random,
1406  ( sizeof ( pre_master_secret.random ) ) ) ) != 0 ) {
1407  return rc;
1408  }
1409 
1410  /* Generate master secret */
1411  tls_generate_master_secret ( tls, &pre_master_secret,
1412  sizeof ( pre_master_secret ) );
1413 
1414  /* Encrypt pre-master secret using server's public key */
1415  memset ( &key_xchg, 0, sizeof ( key_xchg ) );
1416  len = pubkey_encrypt ( pubkey, &tls->server.key, &pre_master_secret,
1417  sizeof ( pre_master_secret ),
1418  key_xchg.encrypted_pre_master_secret );
1419  if ( len < 0 ) {
1420  rc = len;
1421  DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
1422  tls, strerror ( rc ) );
1423  return rc;
1424  }
1425  unused = ( max_len - len );
1426  key_xchg.type_length =
1428  htonl ( sizeof ( key_xchg ) -
1429  sizeof ( key_xchg.type_length ) - unused ) );
1430  key_xchg.encrypted_pre_master_secret_len =
1431  htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) -
1432  unused );
1433 
1434  return tls_send_handshake ( tls, &key_xchg,
1435  ( sizeof ( key_xchg ) - unused ) );
1436 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:413
static int pubkey_encrypt(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const void *data, size_t len, void *out)
Definition: crypto.h:277
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:637
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:247
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:193
#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:1126
struct tls_server server
Server state.
Definition: tls.h:465
u32 version
Driver version.
Definition: ath9k_hw.c:1983
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
#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
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:265
unsigned int uint32_t
Definition: stdint.h:12
uint8_t unused
Unused.
Definition: librm.h:254
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
struct tls_tx tx
Transmit state.
Definition: tls.h:459
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:454
static size_t pubkey_max_len(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key)
Definition: crypto.h:271
uint32_t len
Length.
Definition: ena.h:14
A public key algorithm.
Definition: crypto.h:121
#define htons(value)
Definition: byteswap.h:135
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:77
size_t(* max_len)(const struct asn1_cursor *key)
Calculate maximum output length.
Definition: crypto.h:129
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, tls_tx::cipherspec, cpu_to_le32, DBGC, htonl, htons, tls_server::key, len, pubkey_algorithm::max_len, memset(), tls_cipherspec_pair::pending, tls_cipher_suite::pubkey, pubkey_encrypt(), pubkey_max_len(), random(), rc, tls_connection::server, strerror(), tls_cipherspec::suite, TLS_CLIENT_KEY_EXCHANGE, tls_generate_master_secret(), tls_generate_random(), tls_send_handshake(), TLS_VERSION_MAX, tls_connection::tx, 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 1451 of file tls.c.

1452  {
1453  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1454  struct pubkey_algorithm *pubkey;
1455  struct digest_algorithm *digest;
1456  int use_sig_hash = tls_version ( tls, TLS_VERSION_TLS_1_2 );
1457  const struct {
1458  struct tls_signature_hash_id sig_hash[use_sig_hash];
1459  uint16_t signature_len;
1460  uint8_t signature[0];
1461  } __attribute__ (( packed )) *sig;
1462  const void *data;
1463  size_t remaining;
1464  int rc;
1465 
1466  /* Signature follows parameters */
1467  assert ( param_len <= tls->server.exchange_len );
1468  data = ( tls->server.exchange + param_len );
1469  remaining = ( tls->server.exchange_len - param_len );
1470 
1471  /* Parse signature from ServerKeyExchange */
1472  sig = data;
1473  if ( ( sizeof ( *sig ) > remaining ) ||
1474  ( ntohs ( sig->signature_len ) > ( remaining -
1475  sizeof ( *sig ) ) ) ) {
1476  DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1477  tls );
1478  DBGC_HDA ( tls, 0, tls->server.exchange,
1479  tls->server.exchange_len );
1480  return -EINVAL_KEY_EXCHANGE;
1481  }
1482 
1483  /* Identify signature and hash algorithm */
1484  if ( use_sig_hash ) {
1485  pubkey = tls_signature_hash_pubkey ( sig->sig_hash[0] );
1486  digest = tls_signature_hash_digest ( sig->sig_hash[0] );
1487  if ( ( ! pubkey ) || ( ! digest ) ) {
1488  DBGC ( tls, "TLS %p ServerKeyExchange unsupported "
1489  "signature and hash algorithm\n", tls );
1490  return -ENOTSUP_SIG_HASH;
1491  }
1492  if ( pubkey != cipherspec->suite->pubkey ) {
1493  DBGC ( tls, "TLS %p ServerKeyExchange incorrect "
1494  "signature algorithm %s (expected %s)\n", tls,
1495  pubkey->name, cipherspec->suite->pubkey->name );
1496  return -EPERM_KEY_EXCHANGE;
1497  }
1498  } else {
1499  pubkey = cipherspec->suite->pubkey;
1500  digest = &md5_sha1_algorithm;
1501  }
1502 
1503  /* Verify signature */
1504  {
1505  const void *signature = sig->signature;
1506  size_t signature_len = ntohs ( sig->signature_len );
1507  uint8_t ctx[digest->ctxsize];
1508  uint8_t hash[digest->digestsize];
1509 
1510  /* Calculate digest */
1511  digest_init ( digest, ctx );
1512  digest_update ( digest, ctx, &tls->client.random,
1513  sizeof ( tls->client.random ) );
1514  digest_update ( digest, ctx, tls->server.random,
1515  sizeof ( tls->server.random ) );
1516  digest_update ( digest, ctx, tls->server.exchange, param_len );
1517  digest_final ( digest, ctx, hash );
1518 
1519  /* Verify signature */
1520  if ( ( rc = pubkey_verify ( pubkey, &tls->server.key,
1521  digest, hash, signature,
1522  signature_len ) ) != 0 ) {
1523  DBGC ( tls, "TLS %p ServerKeyExchange failed "
1524  "verification\n", tls );
1525  DBGC_HDA ( tls, 0, tls->server.exchange,
1526  tls->server.exchange_len );
1527  return -EPERM_KEY_EXCHANGE;
1528  }
1529  }
1530 
1531  return 0;
1532 }
#define __attribute__(x)
Definition: compiler.h:10
uint8_t random[32]
Random bytes.
Definition: tls.h:403
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
pseudo_bit_t hash[0x00010]
Definition: arbel.h:13
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:208
unsigned short uint16_t
Definition: stdint.h:11
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:413
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
Definition: crypto.h:296
static struct pubkey_algorithm * tls_signature_hash_pubkey(struct tls_signature_hash_id code)
Find TLS signature algorithm.
Definition: tls.c:1010
u8 sig
Definition: CIB_PRM.h:43
#define EPERM_KEY_EXCHANGE
Definition: tls.c:186
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:214
#define DBGC(...)
Definition: compiler.h:505
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:405
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
static struct digest_algorithm * tls_signature_hash_digest(struct tls_signature_hash_id code)
Find TLS hash algorithm.
Definition: tls.c:1029
#define ntohs(value)
Definition: byteswap.h:136
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
A TLS cipher specification.
Definition: tls.h:247
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:193
struct tls_server server
Server state.
Definition: tls.h:465
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:463
#define DBGC_HDA(...)
Definition: compiler.h:506
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:324
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:203
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:265
struct tls_tx tx
Transmit state.
Definition: tls.h:459
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:271
size_t ctxsize
Context size.
Definition: crypto.h:22
size_t digestsize
Digest size.
Definition: crypto.h:26
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct tls_client_random random
Random bytes.
Definition: tls.h:391
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:110
A TLS signature and hash algorithm identifier.
Definition: tls.h:269
#define ENOTSUP_SIG_HASH
Definition: tls.c:154
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:407
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
A public key algorithm.
Definition: crypto.h:121
const char * name
Algorithm name.
Definition: crypto.h:123

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

Referenced by tls_send_client_key_exchange_dhe(), and tls_send_client_key_exchange_ecdhe().

◆ tls_send_client_key_exchange_dhe()

static int tls_send_client_key_exchange_dhe ( struct tls_connection tls)
static

Transmit Client Key Exchange record using DHE key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1540 of file tls.c.

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

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

◆ tls_send_client_key_exchange_ecdhe()

static int tls_send_client_key_exchange_ecdhe ( struct tls_connection tls)
static

Transmit Client Key Exchange record using ECDHE key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1665 of file tls.c.

1665  {
1666  struct tls_named_curve *curve;
1667  const struct {
1668  uint8_t curve_type;
1669  uint16_t named_curve;
1670  uint8_t public_len;
1671  uint8_t public[0];
1672  } __attribute__ (( packed )) *ecdh;
1673  size_t param_len;
1674  size_t pointsize;
1675  size_t keysize;
1676  size_t offset;
1677  int rc;
1678 
1679  /* Parse ServerKeyExchange record */
1680  ecdh = tls->server.exchange;
1681  if ( ( sizeof ( *ecdh ) > tls->server.exchange_len ) ||
1682  ( ecdh->public_len > ( tls->server.exchange_len -
1683  sizeof ( *ecdh ) ) ) ) {
1684  DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1685  tls );
1686  DBGC_HDA ( tls, 0, tls->server.exchange,
1687  tls->server.exchange_len );
1688  return -EINVAL_KEY_EXCHANGE;
1689  }
1690  param_len = ( sizeof ( *ecdh ) + ecdh->public_len );
1691 
1692  /* Verify parameter signature */
1693  if ( ( rc = tls_verify_dh_params ( tls, param_len ) ) != 0 )
1694  return rc;
1695 
1696  /* Identify named curve */
1697  if ( ecdh->curve_type != TLS_NAMED_CURVE_TYPE ) {
1698  DBGC ( tls, "TLS %p unsupported curve type %d\n",
1699  tls, ecdh->curve_type );
1700  DBGC_HDA ( tls, 0, tls->server.exchange,
1701  tls->server.exchange_len );
1702  return -ENOTSUP_CURVE;
1703  }
1704  curve = tls_find_named_curve ( ecdh->named_curve );
1705  if ( ! curve ) {
1706  DBGC ( tls, "TLS %p unsupported named curve %d\n",
1707  tls, ntohs ( ecdh->named_curve ) );
1708  DBGC_HDA ( tls, 0, tls->server.exchange,
1709  tls->server.exchange_len );
1710  return -ENOTSUP_CURVE;
1711  }
1712  DBGC ( tls, "TLS %p using named curve %s\n", tls, curve->curve->name );
1713  pointsize = curve->curve->pointsize;
1714  keysize = curve->curve->keysize;
1715  offset = ( curve->format ? 1 : 0 );
1716 
1717  /* Check key length */
1718  if ( ecdh->public_len != ( offset + pointsize ) ) {
1719  DBGC ( tls, "TLS %p invalid %s key\n",
1720  tls, curve->curve->name );
1721  DBGC_HDA ( tls, 0, tls->server.exchange,
1722  tls->server.exchange_len );
1723  return -EINVAL_KEY_EXCHANGE;
1724  }
1725 
1726  /* Check curve point format byte (if present) */
1727  if ( curve->format && ( ecdh->public[0] != curve->format ) ) {
1728  DBGC ( tls, "TLS %p invalid %s curve point format\n",
1729  tls, curve->curve->name );
1730  DBGC_HDA ( tls, 0, tls->server.exchange,
1731  tls->server.exchange_len );
1732  return -EINVAL_KEY_EXCHANGE;
1733  }
1734 
1735  /* Construct pre-master secret and ClientKeyExchange record */
1736  {
1737  uint8_t private[keysize];
1738  uint8_t pre_master_secret[pointsize];
1739  struct {
1740  uint32_t type_length;
1741  uint8_t public_len;
1742  uint8_t public[ecdh->public_len];
1743  } __attribute__ (( packed )) key_xchg;
1744 
1745  /* Generate ephemeral private key */
1746  if ( ( rc = tls_generate_random ( tls, private,
1747  sizeof ( private ) ) ) != 0){
1748  return rc;
1749  }
1750 
1751  /* Exchange keys */
1752  if ( ( rc = ecdhe_key ( curve->curve, ( ecdh->public + offset ),
1753  private, ( key_xchg.public + offset ),
1754  pre_master_secret ) ) != 0 ) {
1755  DBGC ( tls, "TLS %p could not exchange ECDHE key: %s\n",
1756  tls, strerror ( rc ) );
1757  return rc;
1758  }
1759 
1760  /* Generate master secret */
1761  tls_generate_master_secret ( tls, pre_master_secret,
1762  curve->pre_master_secret_len );
1763 
1764  /* Generate Client Key Exchange record */
1765  key_xchg.type_length =
1767  htonl ( sizeof ( key_xchg ) -
1768  sizeof ( key_xchg.type_length ) ) );
1769  key_xchg.public_len = sizeof ( key_xchg.public );
1770  if ( curve->format )
1771  key_xchg.public[0] = curve->format;
1772 
1773  /* Transmit Client Key Exchange record */
1774  if ( ( rc = tls_send_handshake ( tls, &key_xchg,
1775  sizeof ( key_xchg ) ) ) !=0){
1776  return rc;
1777  }
1778  }
1779 
1780  return 0;
1781 }
#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:1058
#define ENOTSUP_CURVE
Definition: tls.c:162
static void tls_generate_master_secret(struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
Generate master secret.
Definition: tls.c:637
#define DBGC(...)
Definition: compiler.h:505
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:405
#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:1126
struct tls_server server
Server state.
Definition: tls.h:465
#define TLS_NAMED_CURVE_TYPE
TLS named curved type.
Definition: tls.h:221
#define DBGC_HDA(...)
Definition: compiler.h:506
const char * name
Curve name.
Definition: crypto.h:186
#define cpu_to_le32(value)
Definition: byteswap.h:107
int ecdhe_key(struct elliptic_curve *curve, const void *partner, const void *private, void *public, void *shared)
Calculate ECDHE key.
Definition: ecdhe.c:45
uint8_t pre_master_secret_len
Pre-master secret length.
Definition: tls.h:235
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:190
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:229
static int tls_verify_dh_params(struct tls_connection *tls, size_t param_len)
Verify Diffie-Hellman parameter signature.
Definition: tls.c:1451
unsigned char uint8_t
Definition: stdint.h:10
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
unsigned int uint32_t
Definition: stdint.h:12
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
A TLS named curve.
Definition: tls.h:227
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:110
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:454
size_t pointsize
Point (and public key) size.
Definition: crypto.h:188
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:407
uint8_t format
Curve point format byte (if any)
Definition: tls.h:233
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:77

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

◆ tls_send_client_key_exchange()

static int tls_send_client_key_exchange ( struct tls_connection tls)
static

Transmit Client Key Exchange record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1795 of file tls.c.

1795  {
1796  struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
1797  struct tls_cipher_suite *suite = cipherspec->suite;
1798  int rc;
1799 
1800  /* Transmit Client Key Exchange record via key exchange algorithm */
1801  if ( ( rc = suite->exchange->exchange ( tls ) ) != 0 ) {
1802  DBGC ( tls, "TLS %p could not exchange keys: %s\n",
1803  tls, strerror ( rc ) );
1804  return rc;
1805  }
1806 
1807  /* Generate keys from master secret */
1808  if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
1809  DBGC ( tls, "TLS %p could not generate keys: %s\n",
1810  tls, strerror ( rc ) );
1811  return rc;
1812  }
1813 
1814  return 0;
1815 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:191
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:247
int(* exchange)(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition: tls.h:185
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
A TLS cipher suite.
Definition: tls.h:189
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:265
struct tls_tx tx
Transmit state.
Definition: tls.h:459
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:665

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

Referenced by tls_tx_step().

◆ tls_send_certificate_verify()

static int tls_send_certificate_verify ( struct tls_connection tls)
static

Transmit Certificate Verify record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1823 of file tls.c.

1823  {
1824  struct digest_algorithm *digest = tls->handshake_digest;
1825  struct x509_certificate *cert = x509_first ( tls->client.chain );
1826  struct pubkey_algorithm *pubkey = cert->signature_algorithm->pubkey;
1827  struct asn1_cursor *key = privkey_cursor ( tls->client.key );
1828  uint8_t digest_out[ digest->digestsize ];
1829  struct tls_signature_hash_algorithm *sig_hash = NULL;
1830  int rc;
1831 
1832  /* Generate digest to be signed */
1833  tls_verify_handshake ( tls, digest_out );
1834 
1835  /* TLSv1.2 and later use explicit algorithm identifiers */
1836  if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
1837  sig_hash = tls_signature_hash_algorithm ( pubkey, digest );
1838  if ( ! sig_hash ) {
1839  DBGC ( tls, "TLS %p could not identify (%s,%s) "
1840  "signature and hash algorithm\n", tls,
1841  pubkey->name, digest->name );
1842  rc = -ENOTSUP_SIG_HASH;
1843  goto err_sig_hash;
1844  }
1845  }
1846 
1847  /* Generate and transmit record */
1848  {
1849  size_t max_len = pubkey_max_len ( pubkey, key );
1850  int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
1851  struct {
1852  uint32_t type_length;
1853  struct tls_signature_hash_id sig_hash[use_sig_hash];
1854  uint16_t signature_len;
1855  uint8_t signature[max_len];
1856  } __attribute__ (( packed )) certificate_verify;
1857  size_t unused;
1858  int len;
1859 
1860  /* Sign digest */
1861  len = pubkey_sign ( pubkey, key, digest, digest_out,
1862  certificate_verify.signature );
1863  if ( len < 0 ) {
1864  rc = len;
1865  DBGC ( tls, "TLS %p could not sign %s digest using %s "
1866  "client private key: %s\n", tls, digest->name,
1867  pubkey->name, strerror ( rc ) );
1868  goto err_pubkey_sign;
1869  }
1870  unused = ( max_len - len );
1871 
1872  /* Construct Certificate Verify record */
1873  certificate_verify.type_length =
1875  htonl ( sizeof ( certificate_verify ) -
1876  sizeof ( certificate_verify.type_length ) -
1877  unused ) );
1878  if ( use_sig_hash ) {
1879  memcpy ( &certificate_verify.sig_hash[0],
1880  &sig_hash->code,
1881  sizeof ( certificate_verify.sig_hash[0] ) );
1882  }
1883  certificate_verify.signature_len =
1884  htons ( sizeof ( certificate_verify.signature ) -
1885  unused );
1886 
1887  /* Transmit record */
1888  rc = tls_send_handshake ( tls, &certificate_verify,
1889  ( sizeof ( certificate_verify ) - unused ) );
1890  }
1891 
1892  err_pubkey_sign:
1893  err_sig_hash:
1894  return rc;
1895 }
#define __attribute__(x)
Definition: compiler.h:10
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:279
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:807
struct asn1_algorithm * signature_algorithm
Signature algorithm.
Definition: x509.h:238
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
#define htonl(value)
Definition: byteswap.h:133
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1126
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition: privkey.h:52
struct private_key * key
Private key (if used)
Definition: tls.h:393
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:383
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:988
struct tls_client client
Client state.
Definition: tls.h:463
A TLS signature algorithm.
Definition: tls.h:277
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:215
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
uint8_t unused
Unused.
Definition: librm.h:254
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:283
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:271
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:450
size_t digestsize
Digest size.
Definition: crypto.h:26
const char * name
Algorithm name.
Definition: crypto.h:20
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:310
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:395
A message digest algorithm.
Definition: crypto.h:18
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:281
static size_t pubkey_max_len(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key)
Definition: crypto.h:271
A TLS signature and hash algorithm identifier.
Definition: tls.h:269
#define TLS_CERTIFICATE_VERIFY
Definition: tls.h:76
#define ENOTSUP_SIG_HASH
Definition: tls.c:154
static int pubkey_sign(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, void *signature)
Definition: crypto.h:289
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
uint32_t len
Length.
Definition: ena.h:14
#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:121
#define htons(value)
Definition: byteswap.h:135
union @383 key
Sense key.
Definition: scsi.h:18
const char * name
Algorithm name.
Definition: crypto.h:123

References __attribute__, tls_client::chain, tls_connection::client, tls_signature_hash_algorithm::code, cpu_to_le32, DBGC, tls_signature_hash_algorithm::digest, digest_algorithm::digestsize, ENOTSUP_SIG_HASH, tls_connection::handshake_digest, htonl, htons, key, tls_client::key, len, memcpy(), digest_algorithm::name, pubkey_algorithm::name, NULL, privkey_cursor(), tls_signature_hash_algorithm::pubkey, asn1_algorithm::pubkey, pubkey_max_len(), pubkey_sign(), rc, signature, x509_certificate::signature_algorithm, strerror(), TLS_CERTIFICATE_VERIFY, tls_send_handshake(), tls_signature_hash_algorithm(), tls_verify_handshake(), tls_version(), TLS_VERSION_TLS_1_2, 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:2939
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:456
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:397
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:807
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:1126
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct tls_client client
Client state.
Definition: tls.h:463
uint8_t master_secret[48]
Master secret.
Definition: tls.h:448
#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:154
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:450
size_t digestsize
Digest size.
Definition: crypto.h:26
A message digest algorithm.
Definition: crypto.h:18
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:617
#define TLS_FINISHED
Definition: tls.h:78
void * memset(void *dest, int character, size_t len) __nonnull

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

Referenced by tls_tx_step().

◆ tls_new_change_cipher()

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

Receive new Change Cipher record.

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

Definition at line 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 ) ) != 0 ) {
1980  DBGC ( tls, "TLS %p could not activate RX cipher: %s\n",
1981  tls, strerror ( rc ) );
1982  return rc;
1983  }
1984  tls->rx.seq = ~( ( uint64_t ) 0 );
1985 
1986  return 0;
1987 }
#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
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec_pair *pair)
Activate next cipher suite.
Definition: tls.c:955
uint16_t spec
ENA specification version.
Definition: ena.h:26
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:373
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
#define EINVAL_CHANGE_CIPHER
Definition: tls.c:58
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
struct tls_rx rx
Receive state.
Definition: tls.h:461
uint64_t seq
Sequence number.
Definition: tls.h:375
void * data
Start of data.
Definition: iobuf.h:48
uint32_t len
Length.
Definition: ena.h:14
#define TLS_CHANGE_CIPHER_SPEC
Change cipher spec magic byte.
Definition: tls.h:56

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

Referenced by tls_new_record().

◆ tls_new_alert()

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

Receive new Alert record.

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

Definition at line 1996 of file tls.c.

1997  {
1998  const struct {
1999  uint8_t level;
2000  uint8_t description;
2001  char next[0];
2002  } __attribute__ (( packed )) *alert = iobuf->data;
2003  size_t len = iob_len ( iobuf );
2004 
2005  /* Sanity check */
2006  if ( sizeof ( *alert ) != len ) {
2007  DBGC ( tls, "TLS %p received overlength Alert\n", tls );
2008  DBGC_HD ( tls, alert, len );
2009  return -EINVAL_ALERT;
2010  }
2011  iob_pull ( iobuf, sizeof ( *alert ) );
2012 
2013  /* Handle alert */
2014  switch ( alert->level ) {
2015  case TLS_ALERT_WARNING:
2016  DBGC ( tls, "TLS %p received warning alert %d\n",
2017  tls, alert->description );
2018  return 0;
2019  case TLS_ALERT_FATAL:
2020  DBGC ( tls, "TLS %p received fatal alert %d\n",
2021  tls, alert->description );
2022  return -EPERM_ALERT;
2023  default:
2024  DBGC ( tls, "TLS %p received unknown alert level %d"
2025  "(alert %d)\n", tls, alert->level, alert->description );
2026  return -EIO_ALERT;
2027  }
2028 }
#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
void alert(unsigned int row, const char *fmt,...)
Show alert message.
Definition: message.c:103
#define EIO_ALERT
Definition: tls.c:114
#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:62
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_ALERT_FATAL
Definition: tls.h:82
void * data
Start of data.
Definition: iobuf.h:48
#define EPERM_ALERT
Definition: tls.c:166
uint32_t len
Length.
Definition: ena.h:14

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

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

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

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

2255  {
2256  const struct {
2258  uint16_t len;
2259  uint8_t ticket[0];
2260  } __attribute__ (( packed )) *new_session_ticket = data;
2261  size_t ticket_len;
2262 
2263  /* Parse header */
2264  if ( sizeof ( *new_session_ticket ) > len ) {
2265  DBGC ( tls, "TLS %p received underlength New Session Ticket\n",
2266  tls );
2267  DBGC_HD ( tls, data, len );
2268  return -EINVAL_TICKET;
2269  }
2270  ticket_len = ntohs ( new_session_ticket->len );
2271  if ( ticket_len > ( len - sizeof ( *new_session_ticket ) ) ) {
2272  DBGC ( tls, "TLS %p received overlength New Session Ticket\n",
2273  tls );
2274  DBGC_HD ( tls, data, len );
2275  return -EINVAL_TICKET;
2276  }
2277 
2278  /* Free any unapplied new session ticket */
2279  free ( tls->new_session_ticket );
2280  tls->new_session_ticket = NULL;
2281  tls->new_session_ticket_len = 0;
2282 
2283  /* Record ticket */
2284  tls->new_session_ticket = malloc ( ticket_len );
2285  if ( ! tls->new_session_ticket )
2286  return -ENOMEM;
2287  memcpy ( tls->new_session_ticket, new_session_ticket->ticket,
2288  ticket_len );
2289  tls->new_session_ticket_len = ticket_len;
2290  DBGC ( tls, "TLS %p new session ticket:\n", tls );
2291  DBGC_HDA ( tls, 0, tls->new_session_ticket,
2292  tls->new_session_ticket_len );
2293 
2294  return 0;
2295 }
#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:438
#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:436
#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:599
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_TICKET
Definition: tls.c:106
uint32_t len
Length.
Definition: ena.h:14
#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 2305 of file tls.c.

2306  {
2307  size_t remaining = len;
2308  int rc;
2309 
2310  /* Free any existing certificate chain */
2311  memset ( &tls->server.key, 0, sizeof ( tls->server.key ) );
2312  x509_chain_put ( tls->server.chain );
2313  tls->server.chain = NULL;
2314 
2315  /* Create certificate chain */
2316  tls->server.chain = x509_alloc_chain();
2317  if ( ! tls->server.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->server.chain,
2350  certificate->data,
2351  certificate_len ) ) != 0 ) {
2352  DBGC ( tls, "TLS %p could not append certificate: %s\n",
2353  tls, strerror ( rc ) );
2354  DBGC_HDA ( tls, 0, data, remaining );
2355  goto err_parse;
2356  }
2357  cert = x509_last ( tls->server.chain );
2358  DBGC ( tls, "TLS %p found certificate %s\n",
2359  tls, x509_name ( cert ) );
2360 
2361  /* Move to next certificate in list */
2362  data += record_len;
2363  remaining -= record_len;
2364  }
2365 
2366  return 0;
2367 
2368  err_parse:
2369  err_overlength:
2370  err_underlength:
2371  memset ( &tls->server.key, 0, sizeof ( tls->server.key ) );
2372  x509_chain_put ( tls->server.chain );
2373  tls->server.chain = NULL;
2374  err_alloc_chain:
2375  return rc;
2376 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:299
#define __attribute__(x)
Definition: compiler.h:10
u16 length
Definition: sky2.h:9
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:413
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:231
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:1660
#define DBGC(...)
Definition: compiler.h:505
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1612
#define ENOMEM_CHAIN
Definition: tls.c:126
#define EINVAL_CERTIFICATE
Definition: tls.c:70
struct tls_server server
Server state.
Definition: tls.h:465
#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:324
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:215
struct x509_chain * chain
Certificate chain.
Definition: tls.h:411
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:216
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:146
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint32_t len
Length.
Definition: ena.h:14
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * memset(void *dest, int character, size_t len) __nonnull

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

Referenced by tls_new_certificate().

◆ tls_new_certificate()

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

Receive new Certificate handshake record.

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

Definition at line 2386 of file tls.c.

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

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

2427  {
2428 
2429  /* Free any existing server key exchange record */
2430  free ( tls->server.exchange );
2431  tls->server.exchange_len = 0;
2432 
2433  /* Allocate copy of server key exchange record */
2434  tls->server.exchange = malloc ( len );
2435  if ( ! tls->server.exchange )
2436  return -ENOMEM;
2437 
2438  /* Store copy of server key exchange record for later
2439  * processing. We cannot verify the signature at this point
2440  * since the certificate validation will not yet have
2441  * completed.
2442  */
2443  memcpy ( tls->server.exchange, data, len );
2444  tls->server.exchange_len = len;
2445 
2446  return 0;
2447 }
void * exchange
Server Key Exchange record (if any)
Definition: tls.h:405
struct tls_server server
Server state.
Definition: tls.h:465
#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 * malloc(size_t size)
Allocate memory.
Definition: malloc.c:599
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t exchange_len
Server Key Exchange record length.
Definition: tls.h:407
uint32_t len
Length.
Definition: ena.h:14

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

Referenced by tls_new_handshake().

◆ tls_new_certificate_request()

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

Receive new Certificate Request handshake record.

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

Definition at line 2457 of file tls.c.

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

References certstore, tls_client::chain, tls_connection::client, DBGC, ENOMEM, EPERM_CLIENT_CERT, tls_client::key, NULL, rc, x509_alloc_chain(), x509_append(), x509_auto_append(), x509_chain_put(), x509_find_key(), 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 2521 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_new_finished()

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

Receive new Finished handshake record.

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

Definition at line 2557 of file tls.c.

2558  {
2559  struct tls_session *session = tls->session;
2560  struct digest_algorithm *digest = tls->handshake_digest;
2561  const struct {
2562  uint8_t verify_data[ sizeof ( tls->verify.server ) ];
2563  char next[0];
2564  } __attribute__ (( packed )) *finished = data;
2565  uint8_t digest_out[ digest->digestsize ];
2566 
2567  /* Sanity check */
2568  if ( sizeof ( *finished ) != len ) {
2569  DBGC ( tls, "TLS %p received overlength Finished\n", tls );
2570  DBGC_HD ( tls, data, len );
2571  return -EINVAL_FINISHED;
2572  }
2573 
2574  /* Verify data */
2575  tls_verify_handshake ( tls, digest_out );
2576  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
2577  tls->verify.server, sizeof ( tls->verify.server ),
2578  "server finished", digest_out, sizeof ( digest_out ) );
2579  if ( memcmp ( tls->verify.server, finished->verify_data,
2580  sizeof ( tls->verify.server ) ) != 0 ) {
2581  DBGC ( tls, "TLS %p verification failed\n", tls );
2582  return -EPERM_VERIFY;
2583  }
2584 
2585  /* Mark server as finished */
2586  pending_put ( &tls->server.negotiation );
2587 
2588  /* If we are resuming a session (i.e. if the server Finished
2589  * arrives before the client Finished is sent), then schedule
2590  * transmission of Change Cipher and Finished.
2591  */
2592  if ( is_pending ( &tls->client.negotiation ) ) {
2594  tls_tx_resume ( tls );
2595  }
2596 
2597  /* Record session ID, ticket, and master secret, if applicable */
2598  if ( tls->session_id_len || tls->new_session_ticket_len ) {
2599  memcpy ( session->master_secret, tls->master_secret,
2600  sizeof ( session->master_secret ) );
2601  }
2602  if ( tls->session_id_len ) {
2603  session->id_len = tls->session_id_len;
2604  memcpy ( session->id, tls->session_id, sizeof ( session->id ) );
2605  }
2606  if ( tls->new_session_ticket_len ) {
2607  free ( session->ticket );
2608  session->ticket = tls->new_session_ticket;
2609  session->ticket_len = tls->new_session_ticket_len;
2610  tls->new_session_ticket = NULL;
2611  tls->new_session_ticket_len = 0;
2612  }
2613 
2614  /* Move to end of session's connection list and allow other
2615  * connections to start making progress.
2616  */
2617  list_del ( &tls->list );
2618  list_add_tail ( &tls->list, &session->conn );
2619  tls_tx_resume_all ( session );
2620 
2621  /* Send notification of a window change */
2622  xfer_window_changed ( &tls->plainstream );
2623 
2624  return 0;
2625 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:456
uint8_t id[32]
Session ID.
Definition: tls.h:344
#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:1091
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:1082
struct tls_session * session
Session.
Definition: tls.h:428
uint8_t master_secret[48]
Master secret.
Definition: tls.h:352
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:397
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:807
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:438
uint8_t session_id[32]
Session ID.
Definition: tls.h:432
struct tls_server server
Server state.
Definition: tls.h:465
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void * memcpy(void *dest, const void *src, size_t len) __nonnull
size_t id_len
Length of session ID.
Definition: tls.h:346
void * new_session_ticket
New session ticket.
Definition: tls.h:436
struct tls_client client
Client state.
Definition: tls.h:463
#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:82
struct list_head list
List of connections within the same session.
Definition: tls.h:430
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
#define EPERM_VERIFY
Definition: tls.c:170
size_t ticket_len
Length of session ticket.
Definition: tls.h:350
uint8_t master_secret[48]
Master secret.
Definition: tls.h:448
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:419
void * ticket
Session ticket.
Definition: tls.h:348
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
unsigned int pending
Pending transmissions.
Definition: tls.h:365
struct tls_tx tx
Transmit state.
Definition: tls.h:459
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:450
A TLS session.
Definition: tls.h:330
size_t digestsize
Digest size.
Definition: crypto.h:26
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t server[12]
Server verification data.
Definition: tls.h:156
struct list_head conn
List of connections.
Definition: tls.h:355
size_t session_id_len
Length of session ID.
Definition: tls.h:434
struct interface plainstream
Plaintext stream.
Definition: tls.h:441
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
uint32_t len
Length.
Definition: ena.h:14
#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:617

References __attribute__, tls_connection::client, tls_session::conn, data, DBGC, DBGC_HD, digest_algorithm::digestsize, EINVAL_FINISHED, EPERM_VERIFY, free, tls_connection::handshake_digest, tls_session::id, tls_session::id_len, is_pending(), len, tls_connection::list, list_add_tail, list_del, tls_session::master_secret, tls_connection::master_secret, memcmp(), memcpy(), tls_client::negotiation, tls_server::negotiation, tls_connection::new_session_ticket, tls_connection::new_session_ticket_len, next, NULL, tls_tx::pending, pending_put(), tls_connection::plainstream, tls_verify_data::server, tls_connection::server, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, tls_session::ticket, tls_session::ticket_len, tls_prf_label, TLS_TX_CHANGE_CIPHER, TLS_TX_FINISHED, tls_tx_resume(), tls_tx_resume_all(), tls_verify_handshake(), tls_connection::tx, tls_connection::verify, and xfer_window_changed().

Referenced by tls_new_handshake().

◆ tls_new_handshake()

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

Receive new Handshake record.

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

Definition at line 2634 of file tls.c.

2635  {
2636  size_t remaining;
2637  int rc;
2638 
2639  while ( ( remaining = iob_len ( iobuf ) ) ) {
2640  const struct {
2641  uint8_t type;
2642  tls24_t length;
2643  uint8_t payload[0];
2644  } __attribute__ (( packed )) *handshake = iobuf->data;
2645  const void *payload;
2646  size_t payload_len;
2647  size_t record_len;
2648 
2649  /* Parse header */
2650  if ( sizeof ( *handshake ) > remaining ) {
2651  /* Leave remaining fragment unconsumed */
2652  break;
2653  }
2654  payload_len = tls_uint24 ( &handshake->length );
2655  if ( payload_len > ( remaining - sizeof ( *handshake ) ) ) {
2656  /* Leave remaining fragment unconsumed */
2657  break;
2658  }
2659  payload = &handshake->payload;
2660  record_len = ( sizeof ( *handshake ) + payload_len );
2661 
2662  /* Handle payload */
2663  switch ( handshake->type ) {
2664  case TLS_HELLO_REQUEST:
2665  rc = tls_new_hello_request ( tls, payload,
2666  payload_len );
2667  break;
2668  case TLS_SERVER_HELLO:
2669  rc = tls_new_server_hello ( tls, payload, payload_len );
2670  break;
2672  rc = tls_new_session_ticket ( tls, payload,
2673  payload_len );
2674  break;
2675  case TLS_CERTIFICATE:
2676  rc = tls_new_certificate ( tls, payload, payload_len );
2677  break;
2679  rc = tls_new_server_key_exchange ( tls, payload,
2680  payload_len );
2681  break;
2683  rc = tls_new_certificate_request ( tls, payload,
2684  payload_len );
2685  break;
2686  case TLS_SERVER_HELLO_DONE:
2687  rc = tls_new_server_hello_done ( tls, payload,
2688  payload_len );
2689  break;
2690  case TLS_FINISHED:
2691  rc = tls_new_finished ( tls, payload, payload_len );
2692  break;
2693  default:
2694  DBGC ( tls, "TLS %p ignoring handshake type %d\n",
2695  tls, handshake->type );
2696  rc = 0;
2697  break;
2698  }
2699 
2700  /* Add to handshake digest (except for Hello Requests,
2701  * which are explicitly excluded).
2702  */
2703  if ( handshake->type != TLS_HELLO_REQUEST )
2704  tls_add_handshake ( tls, handshake, record_len );
2705 
2706  /* Abort on failure */
2707  if ( rc != 0 )
2708  return rc;
2709 
2710  /* Move to next handshake record */
2711  iob_pull ( iobuf, record_len );
2712  }
2713 
2714  return 0;
2715 }
#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:231
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:791
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:72
#define TLS_SERVER_HELLO_DONE
Definition: tls.h:75
#define TLS_CERTIFICATE_REQUEST
Definition: tls.h:74
static int tls_new_hello_request(struct tls_connection *tls, const void *data __unused, size_t len __unused)
Receive new Hello Request handshake record.
Definition: tls.c:2038
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:2254
#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:2557
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:2069
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:2457
#define TLS_NEW_SESSION_TICKET
Definition: tls.h:71
A TLS 24-bit integer.
Definition: tls.c:216
#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:2386
#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:2521
#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:2426

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

2725  {
2726 
2727  /* RFC4346 says that we should just ignore unknown record types */
2728  iob_pull ( iobuf, iob_len ( iobuf ) );
2729  return 0;
2730 }
#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 2739 of file tls.c.

2740  {
2741  struct io_buffer *iobuf;
2742  int rc;
2743 
2744  /* Fail unless we are ready to receive data */
2745  if ( ! tls_ready ( tls ) )
2746  return -ENOTCONN;
2747 
2748  /* Deliver each I/O buffer in turn */
2749  while ( ( iobuf = list_first_entry ( rx_data, struct io_buffer,
2750  list ) ) ) {
2751  list_del ( &iobuf->list );
2752  if ( ( rc = xfer_deliver_iob ( &tls->plainstream,
2753  iobuf ) ) != 0 ) {
2754  DBGC ( tls, "TLS %p could not deliver data: "
2755  "%s\n", tls, strerror ( rc ) );
2756  return rc;
2757  }
2758  }
2759 
2760  return 0;
2761 }
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:254
struct interface plainstream
Plaintext stream.
Definition: tls.h:441
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 2771 of file tls.c.

2772  {
2773  int ( * handler ) ( struct tls_connection *tls,
2774  struct io_buffer *iobuf );
2775  struct io_buffer *tmp = NULL;
2776  struct io_buffer **iobuf;
2777  int rc;
2778 
2779  /* Deliver data records as-is to the plainstream interface */
2780  if ( type == TLS_TYPE_DATA )
2781  return tls_new_data ( tls, rx_data );
2782 
2783  /* Determine handler and fragment buffer */
2784  iobuf = &tmp;
2785  switch ( type ) {
2787  handler = tls_new_change_cipher;
2788  break;
2789  case TLS_TYPE_ALERT:
2790  handler = tls_new_alert;
2791  break;
2792  case TLS_TYPE_HANDSHAKE:
2793  handler = tls_new_handshake;
2794  iobuf = &tls->rx.handshake;
2795  break;
2796  default:
2797  DBGC ( tls, "TLS %p unknown record type %d\n", tls, type );
2798  handler = tls_new_unknown;
2799  break;
2800  }
2801 
2802  /* Merge into a single I/O buffer */
2803  if ( *iobuf )
2804  list_add ( &(*iobuf)->list, rx_data );
2805  *iobuf = iob_concatenate ( rx_data );
2806  if ( ! *iobuf ) {
2807  DBGC ( tls, "TLS %p could not concatenate non-data record "
2808  "type %d\n", tls, type );
2809  rc = -ENOMEM_RX_CONCAT;
2810  goto err_concatenate;
2811  }
2812 
2813  /* Handle record */
2814  if ( ( rc = handler ( tls, *iobuf ) ) != 0 )
2815  goto err_handle;
2816 
2817  /* Discard I/O buffer if empty */
2818  if ( ! iob_len ( *iobuf ) ) {
2819  free_iob ( *iobuf );
2820  *iobuf = NULL;
2821  }
2822 
2823  /* Sanity check */
2824  assert ( tmp == NULL );
2825 
2826  return 0;
2827 
2828  err_handle:
2829  free_iob ( *iobuf );
2830  *iobuf = NULL;
2831  err_concatenate:
2832  return rc;
2833 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct io_buffer * handshake
Received handshake fragment.
Definition: tls.h:385
#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
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
#define ENOMEM_RX_CONCAT
Definition: tls.c:142
unsigned long tmp
Definition: linux_pci.h:63
#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:1996
static int tls_new_data(struct tls_connection *tls, struct list_head *rx_data)
Receive new data record.
Definition: tls.c:2739
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
struct tls_rx rx
Receive state.
Definition: tls.h:461
#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:2634
A TLS connection.
Definition: tls.h:423
#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:2724
A persistent I/O buffer.
Definition: iobuf.h:33

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

Referenced by tls_new_ciphertext().

◆ tls_hmac_init()

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

Initialise HMAC.

Parameters
cipherspecCipher specification
ctxContext
authhdrAuthentication header

Definition at line 2849 of file tls.c.

2850  {
2851  struct tls_cipher_suite *suite = cipherspec->suite;
2852  struct digest_algorithm *digest = suite->digest;
2853 
2854  hmac_init ( digest, ctx, cipherspec->mac_secret, suite->mac_len );
2855  hmac_update ( digest, ctx, authhdr, sizeof ( *authhdr ) );
2856 }
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition: hmac.c:57
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:197
A TLS cipher suite.
Definition: tls.h:189
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
uint8_t mac_len
MAC length.
Definition: tls.h:209
A message digest algorithm.
Definition: crypto.h:18
void * mac_secret
MAC secret.
Definition: tls.h:255

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

Referenced by tls_hmac(), and tls_hmac_list().

◆ tls_hmac_update()

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

Update HMAC.

Parameters
cipherspecCipher specification
ctxContext
dataData
lenLength of data

Definition at line 2866 of file tls.c.

2867  {
2868  struct digest_algorithm *digest = cipherspec->suite->digest;
2869 
2870  hmac_update ( digest, ctx, data, len );
2871 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:197
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint32_t len
Length.
Definition: ena.h:14

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

Referenced by tls_hmac(), and tls_hmac_list().

◆ tls_hmac_final()

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

Finalise HMAC.

Parameters
cipherspecCipher specification
ctxContext
macHMAC to fill in

Definition at line 2880 of file tls.c.

2881  {
2882  struct digest_algorithm *digest = cipherspec->suite->digest;
2883 
2884  hmac_final ( digest, ctx, hmac );
2885 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:197
A message digest algorithm.
Definition: crypto.h:18
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition: hmac.c:87

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

Referenced by tls_hmac(), and tls_hmac_list().

◆ tls_hmac()

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

Calculate HMAC.

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

Definition at line 2896 of file tls.c.

2898  {
2899  struct digest_algorithm *digest = cipherspec->suite->digest;
2900  uint8_t ctx[ hmac_ctxsize ( digest ) ];
2901 
2902  tls_hmac_init ( cipherspec, ctx, authhdr );
2903  tls_hmac_update ( cipherspec, ctx, data, len );
2904  tls_hmac_final ( cipherspec, ctx, hmac );
2905 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition: tls.c:2880
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2866
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:197
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition: tls.c:2849
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition: hmac.h:28
unsigned char uint8_t
Definition: stdint.h:10
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint32_t len
Length.
Definition: ena.h:14

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

Referenced by tls_send_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 2915 of file tls.c.

2917  {
2918  struct digest_algorithm *digest = cipherspec->suite->digest;
2919  uint8_t ctx[ hmac_ctxsize ( digest ) ];
2920  struct io_buffer *iobuf;
2921 
2922  tls_hmac_init ( cipherspec, ctx, authhdr );
2923  list_for_each_entry ( iobuf, list, list ) {
2924  tls_hmac_update ( cipherspec, ctx, iobuf->data,
2925  iob_len ( iobuf ) );
2926  }
2927  tls_hmac_final ( cipherspec, ctx, hmac );
2928 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition: tls.c:2880
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2866
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:197
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
Definition: tls.c:2849
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition: hmac.h:28
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
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:18
A persistent I/O buffer.
Definition: iobuf.h:33

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

Referenced by tls_new_ciphertext().

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

3076  {
3077  uint8_t *padding;
3078  unsigned int pad;
3079  unsigned int i;
3080  size_t len;
3081 
3082  /* Extract and verify padding */
3083  padding = ( iobuf->tail - 1 );
3084  pad = *padding;
3085  len = ( pad + 1 );
3086  if ( len > iob_len ( iobuf ) ) {
3087  DBGC ( tls, "TLS %p received underlength padding\n", tls );
3088  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3089  return -EINVAL_PADDING;
3090  }
3091  for ( i = 0 ; i < pad ; i++ ) {
3092  if ( *(--padding) != pad ) {
3093  DBGC ( tls, "TLS %p received bad padding\n", tls );
3094  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3095  return -EINVAL_PADDING;
3096  }
3097  }
3098 
3099  return len;
3100 }
#define EINVAL_PADDING
Definition: tls.c:94
#define DBGC(...)
Definition: compiler.h:505
u32 pad[9]
Padding.
Definition: ar9003_mac.h:90
void * tail
End of data.
Definition: iobuf.h: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
void * data
Start of data.
Definition: iobuf.h:48
uint32_t len
Length.
Definition: ena.h:14

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

3112  {
3113  struct tls_cipherspec *cipherspec = &tls->rx.cipherspec.active;
3114  struct tls_cipher_suite *suite = cipherspec->suite;
3115  struct cipher_algorithm *cipher = suite->cipher;
3116  struct digest_algorithm *digest = suite->digest;
3117  size_t len = ntohs ( tlshdr->length );
3118  struct {
3119  uint8_t fixed[suite->fixed_iv_len];
3120  uint8_t record[suite->record_iv_len];
3121  } __attribute__ (( packed )) iv;
3122  struct tls_auth_header authhdr;
3123  uint8_t verify_mac[digest->digestsize];
3124  uint8_t verify_auth[cipher->authsize];
3125  struct io_buffer *first;
3126  struct io_buffer *last;
3127  struct io_buffer *iobuf;
3128  void *mac;
3129  void *auth;
3130  size_t check_len;
3131  int pad_len;
3132  int rc;
3133 
3134  /* Locate first and last data buffers */
3135  assert ( ! list_empty ( rx_data ) );
3136  first = list_first_entry ( rx_data, struct io_buffer, list );
3137  last = list_last_entry ( rx_data, struct io_buffer, list );
3138 
3139  /* Extract initialisation vector */
3140  if ( iob_len ( first ) < sizeof ( iv.record ) ) {
3141  DBGC ( tls, "TLS %p received underlength IV\n", tls );
3142  DBGC_HD ( tls, first->data, iob_len ( first ) );
3143  return -EINVAL_IV;
3144  }
3145  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
3146  memcpy ( iv.record, first->data, sizeof ( iv.record ) );
3147  iob_pull ( first, sizeof ( iv.record ) );
3148  len -= sizeof ( iv.record );
3149 
3150  /* Extract unencrypted authentication tag */
3151  if ( iob_len ( last ) < cipher->authsize ) {
3152  DBGC ( tls, "TLS %p received underlength authentication tag\n",
3153  tls );
3154  DBGC_HD ( tls, last->data, iob_len ( last ) );
3155  return -EINVAL_MAC;
3156  }
3157  iob_unput ( last, cipher->authsize );
3158  len -= cipher->authsize;
3159  auth = last->tail;
3160 
3161  /* Construct authentication data */
3162  authhdr.seq = cpu_to_be64 ( tls->rx.seq );
3163  authhdr.header.type = tlshdr->type;
3164  authhdr.header.version = tlshdr->version;
3165  authhdr.header.length = htons ( len );
3166 
3167  /* Set initialisation vector */
3168  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv, sizeof ( iv ) );
3169 
3170  /* Process authentication data, if applicable */
3171  if ( is_auth_cipher ( cipher ) ) {
3172  cipher_decrypt ( cipher, cipherspec->cipher_ctx, &authhdr,
3173  NULL, sizeof ( authhdr ) );
3174  }
3175 
3176  /* Decrypt the received data */
3177  check_len = 0;
3178  list_for_each_entry ( iobuf, &tls->rx.data, list ) {
3179  cipher_decrypt ( cipher, cipherspec->cipher_ctx,
3180  iobuf->data, iobuf->data, iob_len ( iobuf ) );
3181  check_len += iob_len ( iobuf );
3182  }
3183  assert ( check_len == len );
3184 
3185  /* Strip block padding, if applicable */
3186  if ( is_block_cipher ( cipher ) ) {
3187  pad_len = tls_verify_padding ( tls, last );
3188  if ( pad_len < 0 ) {
3189  /* Assume zero padding length to avoid timing attacks */
3190  pad_len = 0;
3191  }
3192  iob_unput ( last, pad_len );
3193  len -= pad_len;
3194  }
3195 
3196  /* Extract decrypted MAC */
3197  if ( iob_len ( last ) < suite->mac_len ) {
3198  DBGC ( tls, "TLS %p received underlength MAC\n", tls );
3199  DBGC_HD ( tls, last->data, iob_len ( last ) );
3200  return -EINVAL_MAC;
3201  }
3202  iob_unput ( last, suite->mac_len );
3203  len -= suite->mac_len;
3204  mac = last->tail;
3205 
3206  /* Dump received data */
3207  DBGC2 ( tls, "Received plaintext data:\n" );
3208  check_len = 0;
3209  list_for_each_entry ( iobuf, rx_data, list ) {
3210  DBGC2_HD ( tls, iobuf->data, iob_len ( iobuf ) );
3211  check_len += iob_len ( iobuf );
3212  }
3213  assert ( check_len == len );
3214 
3215  /* Generate MAC */
3216  authhdr.header.length = htons ( len );
3217  if ( suite->mac_len )
3218  tls_hmac_list ( cipherspec, &authhdr, rx_data, verify_mac );
3219 
3220  /* Generate authentication tag */
3221  cipher_auth ( cipher, cipherspec->cipher_ctx, verify_auth );
3222 
3223  /* Verify MAC */
3224  if ( memcmp ( mac, verify_mac, suite->mac_len ) != 0 ) {
3225  DBGC ( tls, "TLS %p failed MAC verification\n", tls );
3226  return -EINVAL_MAC;
3227  }
3228 
3229  /* Verify authentication tag */
3230  if ( memcmp ( auth, verify_auth, cipher->authsize ) != 0 ) {
3231  DBGC ( tls, "TLS %p failed authentication tag verification\n",
3232  tls );
3233  return -EINVAL_MAC;
3234  }
3235 
3236  /* Process plaintext record */
3237  if ( ( rc = tls_new_record ( tls, tlshdr->type, rx_data ) ) != 0 )
3238  return rc;
3239 
3240  return 0;
3241 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#define __attribute__(x)
Definition: compiler.h:10
static int is_auth_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:266
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head data
List of received data buffers.
Definition: tls.h:383
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:207
uint32_t first
First block in range.
Definition: pccrr.h:14
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:373
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:144
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:247
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:346
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
static void tls_hmac_list(struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, struct list_head *list, void *hmac)
Calculate HMAC over list of I/O buffers.
Definition: tls.c:2915
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
size_t authsize
Authentication tag size.
Definition: crypto.h:74
#define EINVAL_MAC
Definition: tls.c:102
void * tail
End of data.
Definition: iobuf.h:50
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:253
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:249
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:197
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:205
A TLS cipher suite.
Definition: tls.h:189
#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
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition: crypto.h:225
uint8_t mac_len
MAC length.
Definition: tls.h:209
unsigned char uint8_t
Definition: stdint.h:10
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:245
struct tls_rx rx
Receive state.
Definition: tls.h:461
long pad_len
Definition: bigint.h:30
uint64_t seq
Sequence number.
Definition: tls.h:375
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
#define EINVAL_IV
Definition: tls.c:90
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:26
void * data
Start of data.
Definition: iobuf.h:48
uint16_t version
Protocol version.
Definition: tls.h:38
A message digest algorithm.
Definition: crypto.h:18
#define cpu_to_be64(value)
Definition: byteswap.h:111
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:263
A cipher algorithm.
Definition: crypto.h:50
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition: crypto.h:251
static int tls_new_record(struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
Receive new record.
Definition: tls.c:2771
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:195
static int tls_verify_padding(struct tls_connection *tls, struct io_buffer *iobuf)
Verify block padding.
Definition: tls.c:3075
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
uint32_t len
Length.
Definition: ena.h:14
#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:257
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:261
A persistent I/O buffer.
Definition: iobuf.h:33

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

Referenced by tls_newdata_process_data().

◆ tls_plainstream_window()

static size_t tls_plainstream_window ( struct tls_connection tls)
static

Check flow control window.

Parameters
tlsTLS connection
Return values
lenLength of window

Definition at line 3256 of file tls.c.

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

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

3275  {
3276  int rc;
3277 
3278  /* Refuse unless we are ready to accept data */
3279  if ( ! tls_ready ( tls ) ) {
3280  rc = -ENOTCONN;
3281  goto done;
3282  }
3283 
3284  if ( ( rc = tls_send_plaintext ( tls, TLS_TYPE_DATA, iobuf->data,
3285  iob_len ( iobuf ) ) ) != 0 )
3286  goto done;
3287 
3288  done:
3289  free_iob ( iobuf );
3290  return rc;
3291 }
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:2939
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:254
#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 3300 of file tls.c.

3301  {
3302 
3303  /* Return cipherstream or validator progress as applicable */
3304  if ( is_pending ( &tls->server.validation ) ) {
3305  return job_progress ( &tls->server.validator, progress );
3306  } else {
3307  return job_progress ( &tls->cipherstream, progress );
3308  }
3309 }
struct tls_server server
Server state.
Definition: tls.h:465
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:443
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:417
struct interface validator
Certificate validator.
Definition: tls.h:415
int job_progress(struct interface *intf, struct job_progress *progress)
Get job progress.
Definition: job.c:43

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

◆ tls_newdata_process_header()

static int tls_newdata_process_header ( struct tls_connection tls)
static

Handle received TLS header.

Parameters
tlsTLS connection
Return values
rcReturned status code

Definition at line 3339 of file tls.c.

3339  {
3340  struct tls_cipherspec *cipherspec = &tls->rx.cipherspec.active;
3341  struct cipher_algorithm *cipher = cipherspec->suite->cipher;
3342  size_t iv_len = cipherspec->suite->record_iv_len;
3343  size_t data_len = ntohs ( tls->rx.header.length );
3344  size_t remaining = data_len;
3345  size_t frag_len;
3346  size_t reserve;
3347  struct io_buffer *iobuf;
3348  struct io_buffer *tmp;
3349  int rc;
3350 
3351  /* Sanity check */
3352  assert ( ( TLS_RX_BUFSIZE % cipher->alignsize ) == 0 );
3353 
3354  /* Calculate alignment reservation at start of first data buffer */
3355  reserve = ( ( -iv_len ) & ( cipher->alignsize - 1 ) );
3356  remaining += reserve;
3357 
3358  /* Allocate data buffers now that we know the length */
3359  assert ( list_empty ( &tls->rx.data ) );
3360  while ( remaining ) {
3361 
3362  /* Calculate fragment length. Ensure that no block is
3363  * smaller than TLS_RX_MIN_BUFSIZE (by increasing the
3364  * allocation length if necessary).
3365  */
3366  frag_len = remaining;
3367  if ( frag_len > TLS_RX_BUFSIZE )
3368  frag_len = TLS_RX_BUFSIZE;
3369  remaining -= frag_len;
3370  if ( remaining < TLS_RX_MIN_BUFSIZE ) {
3371  frag_len += remaining;
3372  remaining = 0;
3373  }
3374 
3375  /* Allocate buffer */
3376  iobuf = alloc_iob_raw ( frag_len, TLS_RX_ALIGN, 0 );
3377  if ( ! iobuf ) {
3378  DBGC ( tls, "TLS %p could not allocate %zd of %zd "
3379  "bytes for receive buffer\n", tls,
3380  remaining, data_len );
3381  rc = -ENOMEM_RX_DATA;
3382  goto err;
3383  }
3384 
3385  /* Ensure tailroom is exactly what we asked for. This
3386  * will result in unaligned I/O buffers when the
3387  * fragment length is unaligned, which can happen only
3388  * before we switch to using a block cipher.
3389  */
3390  iob_reserve ( iobuf, ( iob_tailroom ( iobuf ) - frag_len ) );
3391 
3392  /* Ensure first buffer length will be aligned to a
3393  * multiple of the cipher alignment size after
3394  * stripping the record IV.
3395  */
3396  iob_reserve ( iobuf, reserve );
3397  reserve = 0;
3398 
3399  /* Add I/O buffer to list */
3400  list_add_tail ( &iobuf->list, &tls->rx.data );
3401  }
3402 
3403  /* Move to data state */
3404  tls->rx.state = TLS_RX_DATA;
3405 
3406  return 0;
3407 
3408  err:
3409  list_for_each_entry_safe ( iobuf, tmp, &tls->rx.data, list ) {
3410  list_del ( &iobuf->list );
3411  free_iob ( iobuf );
3412  }
3413  return rc;
3414 }
struct tls_header header
Current received record header.
Definition: tls.h:379
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head data
List of received data buffers.
Definition: tls.h:383
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:207
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:373
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:72
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:40
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
#define ntohs(value)
Definition: byteswap.h:136
A TLS cipher specification.
Definition: tls.h:247
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:63
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define ENOMEM_RX_DATA
Definition: tls.c:138
#define TLS_RX_ALIGN
RX I/O buffer alignment.
Definition: tls.h:487
#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:249
#define TLS_RX_BUFSIZE
RX I/O buffer size.
Definition: tls.h:476
#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
#define TLS_RX_MIN_BUFSIZE
Minimum RX I/O buffer size.
Definition: tls.h:484
struct tls_rx rx
Receive state.
Definition: tls.h:461
enum tls_rx_state state
State machine current state.
Definition: tls.h:377
#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
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:263
A cipher algorithm.
Definition: crypto.h:50
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:195
A persistent I/O buffer.
Definition: iobuf.h:33

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

Referenced by tls_cipherstream_deliver().

◆ tls_newdata_process_data()

static int tls_newdata_process_data ( struct tls_connection tls)
static

Handle received TLS data payload.

Parameters
tlsTLS connection
Return values
rcReturned status code

Definition at line 3422 of file tls.c.

3422  {
3423  struct io_buffer *iobuf;
3424  int rc;
3425 
3426  /* Move current buffer to end of list */
3427  iobuf = list_first_entry ( &tls->rx.data, struct io_buffer, list );
3428  list_del ( &iobuf->list );
3429  list_add_tail ( &iobuf->list, &tls->rx.data );
3430 
3431  /* Continue receiving data if any space remains */
3432  iobuf = list_first_entry ( &tls->rx.data, struct io_buffer, list );
3433  if ( iob_tailroom ( iobuf ) )
3434  return 0;
3435 
3436  /* Process record */
3437  if ( ( rc = tls_new_ciphertext ( tls, &tls->rx.header,
3438  &tls->rx.data ) ) != 0 )
3439  return rc;
3440 
3441  /* Increment RX sequence number */
3442  tls->rx.seq += 1;
3443 
3444  /* Return to header state */
3445  assert ( list_empty ( &tls->rx.data ) );
3446  tls->rx.state = TLS_RX_HEADER;
3447  iob_unput ( &tls->rx.iobuf, sizeof ( tls->rx.header ) );
3448 
3449  return 0;
3450 }
struct tls_header header
Current received record header.
Definition: tls.h:379
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:3110
struct list_head data
List of received data buffers.
Definition: tls.h:383
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define iob_unput(iobuf, len)
Definition: iobuf.h: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 tls_rx rx
Receive state.
Definition: tls.h:461
enum tls_rx_state state
State machine current state.
Definition: tls.h:377
uint64_t seq
Sequence number.
Definition: tls.h:375
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:381
A persistent I/O buffer.
Definition: iobuf.h:33

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

Referenced by tls_cipherstream_deliver().

◆ tls_cipherstream_window()

static size_t tls_cipherstream_window ( struct tls_connection tls)
static

Check flow control window.

Parameters
tlsTLS connection
Return values
lenLength of window

Definition at line 3458 of file tls.c.

3458  {
3459 
3460  /* Open window until we are ready to accept data */
3461  if ( ! tls_ready ( tls ) )
3462  return -1UL;
3463 
3464  return xfer_window ( &tls->plainstream );
3465 }
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:254
struct interface plainstream
Plaintext stream.
Definition: tls.h:441

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

3477  {
3478  size_t frag_len;
3479  int ( * process ) ( struct tls_connection *tls );
3480  struct io_buffer *dest;
3481  int rc;
3482 
3483  while ( iob_len ( iobuf ) ) {
3484 
3485  /* Select buffer according to current state */
3486  switch ( tls->rx.state ) {
3487  case TLS_RX_HEADER:
3488  dest = &tls->rx.iobuf;
3490  break;
3491  case TLS_RX_DATA:
3492  dest = list_first_entry ( &tls->rx.data,
3493  struct io_buffer, list );
3494  assert ( dest != NULL );
3496  break;
3497  default:
3498  assert ( 0 );
3499  rc = -EINVAL_RX_STATE;
3500  goto done;
3501  }
3502 
3503  /* Copy data portion to buffer */
3504  frag_len = iob_len ( iobuf );
3505  if ( frag_len > iob_tailroom ( dest ) )
3506  frag_len = iob_tailroom ( dest );
3507  memcpy ( iob_put ( dest, frag_len ), iobuf->data, frag_len );
3508  iob_pull ( iobuf, frag_len );
3509 
3510  /* Process data if buffer is now full */
3511  if ( iob_tailroom ( dest ) == 0 ) {
3512  if ( ( rc = process ( tls ) ) != 0 ) {
3513  tls_close ( tls, rc );
3514  goto done;
3515  }
3516  }
3517  }
3518  rc = 0;
3519 
3520  done:
3521  free_iob ( iobuf );
3522  return rc;
3523 }
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:3339
struct list_head data
List of received data buffers.
Definition: tls.h:383
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:416
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int tls_newdata_process_data(struct tls_connection *tls)
Handle received TLS data payload.
Definition: tls.c:3422
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define EINVAL_RX_STATE
Definition: tls.c:98
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h: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 tls_rx rx
Receive state.
Definition: tls.h:461
enum tls_rx_state state
State machine current state.
Definition: tls.h:377
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:381
void * data
Start of data.
Definition: iobuf.h:48
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
Definition: string.h:150
A TLS connection.
Definition: tls.h:423
#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, tls_rx::data, dest, done, EINVAL_RX_STATE, free_iob(), iob_len(), iob_pull, iob_put, iob_tailroom(), tls_rx::iobuf, io_buffer::list, list_first_entry, memcpy(), NULL, rc, tls_connection::rx, tls_rx::state, tls_close(), tls_newdata_process_data(), tls_newdata_process_header(), TLS_RX_DATA, and TLS_RX_HEADER.

◆ tls_validator_done()

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

Handle certificate validation completion.

Parameters
tlsTLS connection
rcReason for completion

Definition at line 3554 of file tls.c.

3554  {
3555  struct tls_session *session = tls->session;
3556  struct x509_certificate *cert;
3557 
3558  /* Mark validation as complete */
3559  pending_put ( &tls->server.validation );
3560 
3561  /* Close validator interface */
3562  intf_restart ( &tls->server.validator, rc );
3563 
3564  /* Check for validation failure */
3565  if ( rc != 0 ) {
3566  DBGC ( tls, "TLS %p certificate validation failed: %s\n",
3567  tls, strerror ( rc ) );
3568  goto err;
3569  }
3570  DBGC ( tls, "TLS %p certificate validation succeeded\n", tls );
3571 
3572  /* Extract first certificate */
3573  cert = x509_first ( tls->server.chain );
3574  assert ( cert != NULL );
3575 
3576  /* Verify server name */
3577  if ( ( rc = x509_check_name ( cert, session->name ) ) != 0 ) {
3578  DBGC ( tls, "TLS %p server certificate does not match %s: %s\n",
3579  tls, session->name, strerror ( rc ) );
3580  goto err;
3581  }
3582 
3583  /* Extract the now trusted server public key */
3584  memcpy ( &tls->server.key, &cert->subject.public_key.raw,
3585  sizeof ( tls->server.key ) );
3586 
3587  /* Schedule Client Key Exchange, Change Cipher, and Finished */
3590  TLS_TX_FINISHED );
3591  if ( tls->client.chain ) {
3592  tls->tx.pending |= ( TLS_TX_CERTIFICATE |
3594  }
3595  tls_tx_resume ( tls );
3596 
3597  return;
3598 
3599  err:
3600  tls_close ( tls, rc );
3601  return;
3602 }
struct asn1_cursor raw
Raw public key information.
Definition: x509.h:51
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
struct asn1_cursor key
Public key (within server certificate)
Definition: tls.h:413
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1082
struct tls_session * session
Session.
Definition: tls.h:428
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition: x509.c:1561
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
#define DBGC(...)
Definition: compiler.h:505
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:416
struct tls_server server
Server state.
Definition: tls.h:465
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:463
struct x509_public_key public_key
Public key information.
Definition: x509.h:65
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:215
struct x509_subject subject
Subject.
Definition: x509.h:244
struct x509_chain * chain
Certificate chain.
Definition: tls.h:411
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:417
unsigned int pending
Pending transmissions.
Definition: tls.h:365
struct tls_tx tx
Transmit state.
Definition: tls.h:459
A TLS session.
Definition: tls.h:330
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:310
struct interface validator
Certificate validator.
Definition: tls.h:415
struct x509_chain * chain
Certificate chain (if used)
Definition: tls.h:395
const char * name
Server name.
Definition: tls.h:337
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References assert(), tls_client::chain, tls_server::chain, tls_connection::client, DBGC, intf_restart(), tls_server::key, memcpy(), tls_session::name, NULL, tls_tx::pending, pending_put(), x509_subject::public_key, x509_public_key::raw, rc, tls_connection::server, tls_connection::session, strerror(), x509_certificate::subject, tls_close(), TLS_TX_CERTIFICATE, TLS_TX_CERTIFICATE_VERIFY, TLS_TX_CHANGE_CIPHER, TLS_TX_CLIENT_KEY_EXCHANGE, TLS_TX_FINISHED, tls_tx_resume(), tls_connection::tx, tls_server::validation, tls_server::validator, x509_check_name(), and x509_first().

◆ tls_tx_step()

static void tls_tx_step ( struct tls_connection tls)
static

TLS TX state machine.

Parameters
tlsTLS connection

Definition at line 3626 of file tls.c.

3626  {
3627  struct tls_session *session = tls->session;
3628  struct tls_connection *conn;
3629  int rc;
3630 
3631  /* Wait for cipherstream to become ready */
3632  if ( ! xfer_window ( &tls->cipherstream ) )
3633  return;
3634 
3635  /* Send first pending transmission */
3636  if ( tls->tx.pending & TLS_TX_CLIENT_HELLO ) {
3637  /* Serialise server negotiations within a session, to
3638  * provide a consistent view of session IDs and
3639  * session tickets.
3640  */
3641  list_for_each_entry ( conn, &session->conn, list ) {
3642  if ( conn == tls )
3643  break;
3644  if ( is_pending ( &conn->server.negotiation ) )
3645  return;
3646  }
3647  /* Record or generate session ID and associated master secret */
3648  if ( session->id_len ) {
3649  /* Attempt to resume an existing session */
3650  memcpy ( tls->session_id, session->id,
3651  sizeof ( tls->session_id ) );
3652  tls->session_id_len = session->id_len;
3654  sizeof ( tls->master_secret ) );
3655  } else {
3656  /* No existing session: use a random session ID */
3657  assert ( sizeof ( tls->session_id ) ==
3658  sizeof ( tls->client.random ) );
3659  memcpy ( tls->session_id, &tls->client.random,
3660  sizeof ( tls->session_id ) );
3661  tls->session_id_len = sizeof ( tls->session_id );
3662  }
3663  /* Send Client Hello */
3664  if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
3665  DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
3666  tls, strerror ( rc ) );
3667  goto err;
3668  }
3669  tls->tx.pending &= ~TLS_TX_CLIENT_HELLO;
3670  } else if ( tls->tx.pending & TLS_TX_CERTIFICATE ) {
3671  /* Send Certificate */
3672  if ( ( rc = tls_send_certificate ( tls ) ) != 0 ) {
3673  DBGC ( tls, "TLS %p cold not send Certificate: %s\n",
3674  tls, strerror ( rc ) );
3675  goto err;
3676  }
3677  tls->tx.pending &= ~TLS_TX_CERTIFICATE;
3678  } else if ( tls->tx.pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
3679  /* Send Client Key Exchange */
3680  if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
3681  DBGC ( tls, "TLS %p could not send Client Key "
3682  "Exchange: %s\n", tls, strerror ( rc ) );
3683  goto err;
3684  }
3686  } else if ( tls->tx.pending & TLS_TX_CERTIFICATE_VERIFY ) {
3687  /* Send Certificate Verify */
3688  if ( ( rc = tls_send_certificate_verify ( tls ) ) != 0 ) {
3689  DBGC ( tls, "TLS %p could not send Certificate "
3690  "Verify: %s\n", tls, strerror ( rc ) );
3691  goto err;
3692  }
3694  } else if ( tls->tx.pending & TLS_TX_CHANGE_CIPHER ) {
3695  /* Send Change Cipher, and then change the cipher in use */
3696  if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
3697  DBGC ( tls, "TLS %p could not send Change Cipher: "
3698  "%s\n", tls, strerror ( rc ) );
3699  goto err;
3700  }
3701  if ( ( rc = tls_change_cipher ( tls,
3702  &tls->tx.cipherspec ) ) != 0 ){
3703  DBGC ( tls, "TLS %p could not activate TX cipher: "
3704  "%s\n", tls, strerror ( rc ) );
3705  goto err;
3706  }
3707  tls->tx.seq = 0;
3708  tls->tx.pending &= ~TLS_TX_CHANGE_CIPHER;
3709  } else if ( tls->tx.pending & TLS_TX_FINISHED ) {
3710  /* Send Finished */
3711  if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
3712  DBGC ( tls, "TLS %p could not send Finished: %s\n",
3713  tls, strerror ( rc ) );
3714  goto err;
3715  }
3716  tls->tx.pending &= ~TLS_TX_FINISHED;
3717  }
3718 
3719  /* Reschedule process if pending transmissions remain,
3720  * otherwise send notification of a window change.
3721  */
3722  if ( tls->tx.pending ) {
3723  tls_tx_resume ( tls );
3724  } else {
3725  xfer_window_changed ( &tls->plainstream );
3726  }
3727 
3728  return;
3729 
3730  err:
3731  tls_close ( tls, rc );
3732 }
static int tls_send_certificate(struct tls_connection *tls)
Transmit Certificate record.
Definition: tls.c:1324
uint8_t id[32]
Session ID.
Definition: tls.h:344
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec_pair *pair)
Activate next cipher suite.
Definition: tls.c:955
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1082
struct tls_session * session
Session.
Definition: tls.h:428
uint8_t master_secret[48]
Master secret.
Definition: tls.h:352
#define DBGC(...)
Definition: compiler.h:505
uint8_t session_id[32]
Session ID.
Definition: tls.h:432
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:416
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
struct tls_server server
Server state.
Definition: tls.h:465
void * memcpy(void *dest, const void *src, size_t len) __nonnull
size_t id_len
Length of session ID.
Definition: tls.h:346
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_client client
Client state.
Definition: tls.h:463
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:430
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:448
static int tls_send_client_key_exchange(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition: tls.c:1795
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint64_t seq
Sequence number.
Definition: tls.h:363
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:443
struct pending_operation negotiation
Security negotiation pending operation.
Definition: tls.h:419
unsigned int pending
Pending transmissions.
Definition: tls.h:365
struct tls_tx tx
Transmit state.
Definition: tls.h:459
static int tls_send_certificate_verify(struct tls_connection *tls)
Transmit Certificate Verify record.
Definition: tls.c:1823
A TLS session.
Definition: tls.h:330
A TLS connection.
Definition: tls.h:423
struct tls_client_random random
Random bytes.
Definition: tls.h:391
struct list_head conn
List of connections.
Definition: tls.h:355
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:1313
size_t session_id_len
Length of session ID.
Definition: tls.h:434
struct interface plainstream
Plaintext stream.
Definition: tls.h:441

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

◆ tls_session()

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

Find or create session for TLS connection.

Parameters
tlsTLS connection
nameServer name
Return values
rcReturn status code

Definition at line 3752 of file tls.c.

3752  {
3753  struct tls_session *session;
3754  char *name_copy;
3755  int rc;
3756 
3757  /* Find existing matching session, if any */
3758  list_for_each_entry ( session, &tls_sessions, list ) {
3759  if ( ( strcmp ( name, session->name ) == 0 ) &&
3760  ( tls->server.root == session->root ) &&
3761  ( tls->client.key == session->key ) ) {
3762  ref_get ( &session->refcnt );
3763  tls->session = session;
3764  DBGC ( tls, "TLS %p joining session %s\n", tls, name );
3765  return 0;
3766  }
3767  }
3768 
3769  /* Create new session */
3770  session = zalloc ( sizeof ( *session ) + strlen ( name )
3771  + 1 /* NUL */ );
3772  if ( ! session ) {
3773  rc = -ENOMEM;
3774  goto err_alloc;
3775  }
3776  ref_init ( &session->refcnt, free_tls_session );
3777  name_copy = ( ( ( void * ) session ) + sizeof ( *session ) );
3778  strcpy ( name_copy, name );
3779  session->name = name_copy;
3780  session->root = x509_root_get ( tls->server.root );
3781  session->key = privkey_get ( tls->client.key );
3782  INIT_LIST_HEAD ( &session->conn );
3783  list_add ( &session->list, &tls_sessions );
3784 
3785  /* Record session */
3786  tls->session = session;
3787 
3788  DBGC ( tls, "TLS %p created session %s\n", tls, name );
3789  return 0;
3790 
3791  ref_put ( &session->refcnt );
3792  err_alloc:
3793  return rc;
3794 }
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:428
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
#define DBGC(...)
Definition: compiler.h:505
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
Definition: privkey.h:30
static void free_tls_session(struct refcnt *refcnt)
Free TLS session.
Definition: tls.c:353
struct private_key * key
Private key (if used)
Definition: tls.h:393
struct tls_server server
Server state.
Definition: tls.h:465
struct refcnt refcnt
Reference counter.
Definition: tls.h:332
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct tls_client client
Client state.
Definition: tls.h:463
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:346
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:392
struct list_head list
List of sessions.
Definition: tls.h:334
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:640
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
A TLS session.
Definition: tls.h:330
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
struct x509_root * root
Root of trust.
Definition: tls.h:339
struct private_key * key
Private key.
Definition: tls.h:341
struct list_head conn
List of connections.
Definition: tls.h:355
const char * name
Server name.
Definition: tls.h:337
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
struct x509_root * root
Root of trust.
Definition: tls.h:409

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

◆ add_tls()

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

Add TLS on an interface.

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

Definition at line 3812 of file tls.c.

3813  {
3814  struct tls_connection *tls;
3815  int rc;
3816 
3817  /* Allocate and initialise TLS structure */
3818  tls = malloc ( sizeof ( *tls ) );
3819  if ( ! tls ) {
3820  rc = -ENOMEM;
3821  goto err_alloc;
3822  }
3823  memset ( tls, 0, sizeof ( *tls ) );
3824  ref_init ( &tls->refcnt, free_tls );
3825  INIT_LIST_HEAD ( &tls->list );
3826  intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt );
3828  intf_init ( &tls->server.validator, &tls_validator_desc, &tls->refcnt );
3830  &tls->refcnt );
3831  tls->client.key = privkey_get ( key ? key : &private_key );
3833  tls->version = TLS_VERSION_MAX;
3834  tls_clear_cipher ( tls, &tls->tx.cipherspec.active );
3835  tls_clear_cipher ( tls, &tls->tx.cipherspec.pending );
3836  tls_clear_cipher ( tls, &tls->rx.cipherspec.active );
3837  tls_clear_cipher ( tls, &tls->rx.cipherspec.pending );
3838  tls_clear_handshake ( tls );
3839  tls->client.random.gmt_unix_time = time ( NULL );
3840  iob_populate ( &tls->rx.iobuf, &tls->rx.header, 0,
3841  sizeof ( tls->rx.header ) );
3842  INIT_LIST_HEAD ( &tls->rx.data );
3843  if ( ( rc = tls_generate_random ( tls, &tls->client.random.random,
3844  ( sizeof ( tls->client.random.random ) ) ) ) != 0 ) {
3845  goto err_random;
3846  }
3847  if ( ( rc = tls_session ( tls, name ) ) != 0 )
3848  goto err_session;
3849  list_add_tail ( &tls->list, &tls->session->conn );
3850 
3851  /* Start negotiation */
3852  tls_restart ( tls );
3853 
3854  /* Attach to parent interface, mortalise self, and return */
3855  intf_insert ( xfer, &tls->plainstream, &tls->cipherstream );
3856  ref_put ( &tls->refcnt );
3857  return 0;
3858 
3859  err_session:
3860  err_random:
3861  ref_put ( &tls->refcnt );
3862  err_alloc:
3863  return rc;
3864 }
static void free_tls(struct refcnt *refcnt)
Free TLS connection.
Definition: tls.c:377
struct tls_header header
Current received record header.
Definition: tls.h:379
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
struct process process
Transmit process.
Definition: tls.h:367
struct tls_session * session
Session.
Definition: tls.h:428
struct list_head data
List of received data buffers.
Definition: tls.h:383
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition: tls.c:1103
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:425
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:373
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
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:3537
static struct interface_descriptor tls_validator_desc
TLS certificate validator interface descriptor.
Definition: tls.c:3610
struct private_key * key
Private key (if used)
Definition: tls.h:393
struct tls_server server
Server state.
Definition: tls.h:465
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct tls_client client
Client state.
Definition: tls.h:463
#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:430
uint32_t gmt_unix_time
GMT Unix time.
Definition: tls.h:302
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:392
struct tls_cipherspec_pair cipherspec
Cipher specifications.
Definition: tls.h:361
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:443
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
struct tls_cipherspec pending
Next cipher specification.
Definition: tls.h:265
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:599
struct tls_rx rx
Receive state.
Definition: tls.h:461
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
struct tls_tx tx
Transmit state.
Definition: tls.h:459
static struct interface_descriptor tls_plainstream_desc
TLS plaintext stream interface descriptor.
Definition: tls.c:3322
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:304
A TLS session.
Definition: tls.h:330
static struct process_descriptor tls_process_desc
TLS TX process descriptor.
Definition: tls.c:3735
struct io_buffer iobuf
Current received record header (static I/O buffer)
Definition: tls.h:381
struct interface validator
Certificate validator.
Definition: tls.h:415
uint16_t version
Protocol version.
Definition: tls.h:446
static void tls_clear_handshake(struct tls_connection *tls)
Clear handshake digest algorithm.
Definition: tls.c:750
struct tls_cipherspec active
Current cipher specification.
Definition: tls.h:263
A private key.
Definition: privkey.h:16
A TLS connection.
Definition: tls.h:423
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct tls_client_random random
Random bytes.
Definition: tls.h:391
struct list_head conn
List of connections.
Definition: tls.h:355
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:454
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:441
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @383 key
Sense key.
Definition: scsi.h:18
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
void * memset(void *dest, int character, size_t len) __nonnull
struct x509_root * root
Root of trust.
Definition: tls.h:409

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

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

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( add_tls  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_crypto  )

Variable Documentation

◆ md5_sha1_algorithm

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

Hybrid MD5+SHA1 digest algorithm.

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

RSA digestInfo prefix for MD5+SHA1 algorithm.

Definition at line 335 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:128
struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm
Public key exchange algorithm.
Definition: tls.c:1439
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 823 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:1386

Public key exchange algorithm.

Definition at line 1439 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:1540

Ephemeral Diffie-Hellman key exchange algorithm.

Definition at line 1654 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:1665

Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm.

Definition at line 1784 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:416
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:3300
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:3273
A TLS connection.
Definition: tls.h:423
static size_t tls_plainstream_window(struct tls_connection *tls)
Check flow control window.
Definition: tls.c:3256

TLS plaintext stream interface operations.

Definition at line 3312 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:3312
A TLS connection.
Definition: tls.h:423
#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 3322 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:1082
static int tls_cipherstream_deliver(struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *xfer __unused)
Receive new ciphertext.
Definition: tls.c:3475
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
Definition: tls.c:416
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:423
static size_t tls_cipherstream_window(struct tls_connection *tls)
Check flow control window.
Definition: tls.c:3458

TLS ciphertext stream interface operations.

Definition at line 3526 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:3526
A TLS connection.
Definition: tls.h:423
#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 3537 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:3554
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
A TLS connection.
Definition: tls.h:423

TLS certificate validator interface operations.

Definition at line 3605 of file tls.c.

◆ tls_validator_desc

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

TLS certificate validator interface descriptor.

Definition at line 3610 of file tls.c.

Referenced by add_tls().

◆ tls_process_desc

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

TLS TX process descriptor.

Definition at line 3735 of file tls.c.

Referenced by add_tls().