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

Transport Layer Security Protocol. More...

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

Go to the source code of this file.

Data Structures

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

Macros

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )
 
#define EINFO_EINVAL_CHANGE_CIPHER
 
#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )
 
#define EINFO_EINVAL_ALERT
 
#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )
 
#define EINFO_EINVAL_HELLO
 
#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )
 
#define EINFO_EINVAL_CERTIFICATE
 
#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )
 
#define EINFO_EINVAL_CERTIFICATES
 
#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )
 
#define EINFO_EINVAL_HELLO_DONE
 
#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )
 
#define EINFO_EINVAL_FINISHED
 
#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )
 
#define EINFO_EINVAL_HANDSHAKE
 
#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )
 
#define EINFO_EINVAL_IV
 
#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )
 
#define EINFO_EINVAL_PADDING
 
#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )
 
#define EINFO_EINVAL_RX_STATE
 
#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )
 
#define EINFO_EINVAL_MAC
 
#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )
 
#define EINFO_EINVAL_TICKET
 
#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )
 
#define EINFO_EINVAL_KEY_EXCHANGE
 
#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )
 
#define EINFO_EIO_ALERT
 
#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )
 
#define EINFO_ENOMEM_CONTEXT
 
#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )
 
#define EINFO_ENOMEM_CERTIFICATE
 
#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )
 
#define EINFO_ENOMEM_CHAIN
 
#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )
 
#define EINFO_ENOMEM_TX_PLAINTEXT
 
#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )
 
#define EINFO_ENOMEM_TX_CIPHERTEXT
 
#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )
 
#define EINFO_ENOMEM_RX_DATA
 
#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )
 
#define EINFO_ENOMEM_RX_CONCAT
 
#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )
 
#define EINFO_ENOTSUP_CIPHER
 
#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )
 
#define EINFO_ENOTSUP_NULL
 
#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )
 
#define EINFO_ENOTSUP_SIG_HASH
 
#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )
 
#define EINFO_ENOTSUP_VERSION
 
#define 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...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
static LIST_HEAD (tls_sessions)
 List of TLS session. More...
 
static void tls_tx_resume_all (struct tls_session *session)
 Resume TX state machine for all connections within a session. More...
 
static int tls_send_plaintext (struct tls_connection *tls, unsigned int type, const void *data, size_t len)
 Send plaintext record. More...
 
static void tls_clear_cipher (struct tls_connection *tls, struct tls_cipherspec *cipherspec)
 
static unsigned long tls_uint24 (const tls24_t *field24)
 Extract 24-bit field value. More...
 
static void tls_set_uint24 (tls24_t *field24, unsigned long value)
 Set 24-bit field value. More...
 
static int tls_ready (struct tls_connection *tls)
 Determine if TLS connection is ready for application data. More...
 
static int tls_version (struct tls_connection *tls, unsigned int version)
 Check for TLS version. More...
 
static void md5_sha1_init (void *ctx)
 Initialise MD5+SHA1 algorithm. More...
 
static void md5_sha1_update (void *ctx, const void *data, size_t len)
 Accumulate data with MD5+SHA1 algorithm. More...
 
static void md5_sha1_final (void *ctx, void *out)
 Generate MD5+SHA1 digest. More...
 
static void free_tls_session (struct refcnt *refcnt)
 Free TLS session. More...
 
static void free_tls (struct refcnt *refcnt)
 Free TLS connection. More...
 
static void tls_close (struct tls_connection *tls, int rc)
 Finish with TLS connection. More...
 
static int tls_generate_random (struct tls_connection *tls, void *data, size_t len)
 Generate random data. More...
 
static void tls_hmac_update_va (struct digest_algorithm *digest, void *ctx, va_list args)
 Update HMAC with a list of ( data, len ) pairs. More...
 
static void tls_p_hash_va (struct tls_connection *tls, struct digest_algorithm *digest, const void *secret, size_t secret_len, void *out, size_t out_len, va_list seeds)
 Generate secure pseudo-random data using a single hash function. More...
 
static void tls_prf (struct tls_connection *tls, const void *secret, size_t secret_len, void *out, size_t out_len,...)
 Generate secure pseudo-random data. More...
 
static void tls_generate_master_secret (struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
 Generate master secret. More...
 
static int tls_generate_keys (struct tls_connection *tls)
 Generate key material. More...
 
static void tls_clear_handshake (struct tls_connection *tls)
 Clear handshake digest algorithm. More...
 
static int tls_select_handshake (struct tls_connection *tls, struct digest_algorithm *digest)
 Select handshake digest algorithm. More...
 
static int tls_add_handshake (struct tls_connection *tls, const void *data, size_t len)
 Add handshake record to verification hash. More...
 
static void tls_verify_handshake (struct tls_connection *tls, void *out)
 Calculate handshake verification hash. More...
 
static struct tls_cipher_suitetls_find_cipher_suite (unsigned int cipher_suite)
 Identify cipher suite. More...
 
static void tls_clear_cipher (struct tls_connection *tls __unused, struct tls_cipherspec *cipherspec)
 Clear cipher suite. More...
 
static int tls_set_cipher (struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
 Set cipher suite. More...
 
static int tls_select_cipher (struct tls_connection *tls, unsigned int cipher_suite)
 Select next cipher suite. More...
 
static int tls_change_cipher (struct tls_connection *tls, struct tls_cipherspec *pending, struct tls_cipherspec *active)
 Activate next cipher suite. More...
 
static struct tls_signature_hash_algorithmtls_signature_hash_algorithm (struct pubkey_algorithm *pubkey, struct digest_algorithm *digest)
 Find TLS signature and hash algorithm. More...
 
static struct pubkey_algorithmtls_signature_hash_pubkey (struct tls_signature_hash_id code)
 Find TLS signature algorithm. More...
 
static struct digest_algorithmtls_signature_hash_digest (struct tls_signature_hash_id code)
 Find TLS hash algorithm. More...
 
static 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_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 (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, const void *data, size_t len)
 Receive new Change Cipher record. More...
 
static int tls_new_alert (struct tls_connection *tls, const void *data, size_t len)
 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, const void *data, size_t len)
 Receive new Handshake 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...
 
static struct interface_operation tls_plainstream_ops []
 TLS plaintext stream interface operations. More...
 
static struct interface_descriptor tls_plainstream_desc
 TLS plaintext stream interface descriptor. More...
 
static struct interface_operation tls_cipherstream_ops []
 TLS ciphertext stream interface operations. More...
 
static struct interface_descriptor tls_cipherstream_desc
 TLS ciphertext stream interface descriptor. More...
 
static struct interface_operation tls_validator_ops []
 TLS certificate validator interface operations. More...
 
static struct interface_descriptor tls_validator_desc
 TLS certificate validator interface descriptor. More...
 
static struct process_descriptor tls_process_desc
 TLS TX process descriptor. More...
 

Detailed Description

Transport Layer Security Protocol.

Definition in file tls.c.

Macro Definition Documentation

◆ EINVAL_CHANGE_CIPHER

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )

Definition at line 57 of file tls.c.

◆ EINFO_EINVAL_CHANGE_CIPHER

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

Definition at line 58 of file tls.c.

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

Definition at line 61 of file tls.c.

◆ EINFO_EINVAL_ALERT

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

Definition at line 62 of file tls.c.

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

Definition at line 65 of file tls.c.

◆ EINFO_EINVAL_HELLO

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

Definition at line 66 of file tls.c.

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

Definition at line 69 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATE

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

Definition at line 70 of file tls.c.

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

Definition at line 73 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATES

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

Definition at line 74 of file tls.c.

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

Definition at line 77 of file tls.c.

◆ EINFO_EINVAL_HELLO_DONE

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

Definition at line 78 of file tls.c.

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

Definition at line 81 of file tls.c.

◆ EINFO_EINVAL_FINISHED

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

Definition at line 82 of file tls.c.

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

Definition at line 85 of file tls.c.

◆ EINFO_EINVAL_HANDSHAKE

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

Definition at line 86 of file tls.c.

◆ EINVAL_IV

#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )

Definition at line 89 of file tls.c.

◆ EINFO_EINVAL_IV

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

Definition at line 90 of file tls.c.

◆ EINVAL_PADDING

#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )

Definition at line 93 of file tls.c.

◆ EINFO_EINVAL_PADDING

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

Definition at line 94 of file tls.c.

◆ EINVAL_RX_STATE

#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )

Definition at line 97 of file tls.c.

◆ EINFO_EINVAL_RX_STATE

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

Definition at line 98 of file tls.c.

◆ EINVAL_MAC

#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )

Definition at line 101 of file tls.c.

◆ EINFO_EINVAL_MAC

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

Definition at line 102 of file tls.c.

◆ EINVAL_TICKET

#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )

Definition at line 105 of file tls.c.

◆ EINFO_EINVAL_TICKET

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

Definition at line 106 of file tls.c.

◆ EINVAL_KEY_EXCHANGE

#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )

Definition at line 109 of file tls.c.

◆ EINFO_EINVAL_KEY_EXCHANGE

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

Definition at line 110 of file tls.c.

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

Definition at line 113 of file tls.c.

◆ EINFO_EIO_ALERT

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

Definition at line 114 of file tls.c.

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

Definition at line 117 of file tls.c.

◆ EINFO_ENOMEM_CONTEXT

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

Definition at line 118 of file tls.c.

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

Definition at line 121 of file tls.c.

◆ EINFO_ENOMEM_CERTIFICATE

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

Definition at line 122 of file tls.c.

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

Definition at line 125 of file tls.c.

◆ EINFO_ENOMEM_CHAIN

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

Definition at line 126 of file tls.c.

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

Definition at line 129 of file tls.c.

◆ EINFO_ENOMEM_TX_PLAINTEXT

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

Definition at line 130 of file tls.c.

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

Definition at line 133 of file tls.c.

◆ EINFO_ENOMEM_TX_CIPHERTEXT

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

Definition at line 134 of file tls.c.

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

Definition at line 137 of file tls.c.

◆ EINFO_ENOMEM_RX_DATA

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

Definition at line 138 of file tls.c.

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

Definition at line 141 of file tls.c.

◆ EINFO_ENOMEM_RX_CONCAT

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

Definition at line 142 of file tls.c.

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

Definition at line 145 of file tls.c.

◆ EINFO_ENOTSUP_CIPHER

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

Definition at line 146 of file tls.c.

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

Definition at line 149 of file tls.c.

◆ EINFO_ENOTSUP_NULL

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

Definition at line 150 of file tls.c.

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

Definition at line 153 of file tls.c.

◆ EINFO_ENOTSUP_SIG_HASH

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

Definition at line 154 of file tls.c.

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

Definition at line 157 of file tls.c.

◆ EINFO_ENOTSUP_VERSION

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

Definition at line 158 of file tls.c.

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

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

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

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

◆ EPERM_CLIENT_CERT

#define EPERM_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )

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

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

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

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

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

◆ EPERM_KEY_EXCHANGE

#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )

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

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

Definition at line 185 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 186 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 )
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:555
__be32 out[4]
Definition: CIB_PRM.h:36
#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 611 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 825 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 980 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 1065 of file tls.c.

1065  {
1066  struct tls_connection *tls;
1067 
1068  list_for_each_entry ( tls, &session->conn, list )
1069  tls_tx_resume ( tls );
1070 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1056
struct ntlm_data session
Session key.
Definition: ntlm.h:24
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct list_head list
List of connections within the same session.
Definition: tls.h:319
A TLS connection.
Definition: tls.h:312

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

Referenced by tls_close(), and tls_new_finished().

◆ tls_send_plaintext()

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

Send plaintext record.

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

Definition at line 2661 of file tls.c.

2662  {
2663  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec;
2664  struct tls_cipher_suite *suite = cipherspec->suite;
2665  struct cipher_algorithm *cipher = suite->cipher;
2666  struct digest_algorithm *digest = suite->digest;
2667  struct {
2668  uint8_t fixed[suite->fixed_iv_len];
2669  uint8_t record[suite->record_iv_len];
2670  } __attribute__ (( packed )) iv;
2671  struct tls_auth_header authhdr;
2672  struct tls_header *tlshdr;
2673  void *plaintext = NULL;
2674  size_t plaintext_len = len;
2675  struct io_buffer *ciphertext = NULL;
2676  size_t ciphertext_len;
2677  size_t padding_len;
2678  uint8_t mac[digest->digestsize];
2679  void *tmp;
2680  int rc;
2681 
2682  /* Construct initialisation vector */
2683  memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
2684  tls_generate_random ( tls, iv.record, sizeof ( iv.record ) );
2685 
2686  /* Construct authentication data */
2687  authhdr.seq = cpu_to_be64 ( tls->tx_seq );
2688  authhdr.header.type = type;
2689  authhdr.header.version = htons ( tls->version );
2690  authhdr.header.length = htons ( len );
2691 
2692  /* Calculate padding length */
2693  plaintext_len += suite->mac_len;
2694  if ( is_block_cipher ( cipher ) ) {
2695  padding_len = ( ( ( cipher->blocksize - 1 ) &
2696  -( plaintext_len + 1 ) ) + 1 );
2697  } else {
2698  padding_len = 0;
2699  }
2700  plaintext_len += padding_len;
2701 
2702  /* Allocate plaintext */
2703  plaintext = malloc ( plaintext_len );
2704  if ( ! plaintext ) {
2705  DBGC ( tls, "TLS %p could not allocate %zd bytes for "
2706  "plaintext\n", tls, plaintext_len );
2708  goto done;
2709  }
2710 
2711  /* Assemble plaintext */
2712  tmp = plaintext;
2713  memcpy ( tmp, data, len );
2714  tmp += len;
2715  if ( suite->mac_len )
2716  tls_hmac ( cipherspec, &authhdr, data, len, mac );
2717  memcpy ( tmp, mac, suite->mac_len );
2718  tmp += suite->mac_len;
2719  memset ( tmp, ( padding_len - 1 ), padding_len );
2720  tmp += padding_len;
2721  assert ( tmp == ( plaintext + plaintext_len ) );
2722  DBGC2 ( tls, "Sending plaintext data:\n" );
2723  DBGC2_HD ( tls, plaintext, plaintext_len );
2724 
2725  /* Set initialisation vector */
2726  cipher_setiv ( cipher, cipherspec->cipher_ctx, &iv, sizeof ( iv ) );
2727 
2728  /* Process authentication data, if applicable */
2729  if ( is_auth_cipher ( cipher ) ) {
2730  cipher_encrypt ( cipher, cipherspec->cipher_ctx, &authhdr,
2731  NULL, sizeof ( authhdr ) );
2732  }
2733 
2734  /* Allocate ciphertext */
2735  ciphertext_len = ( sizeof ( *tlshdr ) + sizeof ( iv.record ) +
2736  plaintext_len + cipher->authsize );
2737  ciphertext = xfer_alloc_iob ( &tls->cipherstream, ciphertext_len );
2738  if ( ! ciphertext ) {
2739  DBGC ( tls, "TLS %p could not allocate %zd bytes for "
2740  "ciphertext\n", tls, ciphertext_len );
2742  goto done;
2743  }
2744 
2745  /* Assemble ciphertext */
2746  tlshdr = iob_put ( ciphertext, sizeof ( *tlshdr ) );
2747  tlshdr->type = type;
2748  tlshdr->version = htons ( tls->version );
2749  tlshdr->length = htons ( ciphertext_len - sizeof ( *tlshdr ) );
2750  memcpy ( iob_put ( ciphertext, sizeof ( iv.record ) ), iv.record,
2751  sizeof ( iv.record ) );
2752  cipher_encrypt ( cipher, cipherspec->cipher_ctx, plaintext,
2753  iob_put ( ciphertext, plaintext_len ), plaintext_len );
2754  cipher_auth ( cipher, cipherspec->cipher_ctx,
2755  iob_put ( ciphertext, cipher->authsize ) );
2756  assert ( iob_len ( ciphertext ) == ciphertext_len );
2757 
2758  /* Free plaintext as soon as possible to conserve memory */
2759  free ( plaintext );
2760  plaintext = NULL;
2761 
2762  /* Send ciphertext */
2763  if ( ( rc = xfer_deliver_iob ( &tls->cipherstream,
2764  iob_disown ( ciphertext ) ) ) != 0 ) {
2765  DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
2766  tls, strerror ( rc ) );
2767  goto done;
2768  }
2769 
2770  /* Update TX state machine to next record */
2771  tls->tx_seq += 1;
2772 
2773  done:
2774  free ( plaintext );
2775  free_iob ( ciphertext );
2776  return rc;
2777 }
#define __attribute__(x)
Definition: compiler.h:10
static int is_auth_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:256
size_t blocksize
Block size.
Definition: crypto.h:59
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:120
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:254
uint8_t record_iv_len
Record initialisation vector length.
Definition: tls.h:192
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:157
struct eltorito_descriptor_fixed fixed
Fixed portion.
Definition: eltorito.h:13
TLS authentication header.
Definition: tls.h:129
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:206
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
unsigned long tmp
Definition: linux_pci.h:53
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:228
size_t authsize
Authentication tag size.
Definition: crypto.h:73
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:337
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:214
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:208
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:182
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:190
A TLS cipher suite.
Definition: tls.h:174
#define ENOMEM_TX_CIPHERTEXT
Definition: tls.c:133
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:332
#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:218
uint8_t mac_len
MAC length.
Definition: tls.h:194
unsigned char uint8_t
Definition: stdint.h:10
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
A TLS header.
Definition: tls.h:28
#define ENOMEM_TX_PLAINTEXT
Definition: tls.c:129
static void tls_hmac(struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, const void *data, size_t len, void *hmac)
Calculate HMAC.
Definition: tls.c:2618
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
uint8_t iv[12]
Initialisation vector.
Definition: gcm.h:12
uint16_t version
Protocol version.
Definition: tls.h:38
A message digest algorithm.
Definition: crypto.h:17
uint16_t version
Protocol version.
Definition: tls.h:335
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define cpu_to_be64(value)
Definition: byteswap.h:111
A cipher algorithm.
Definition: crypto.h:49
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition: crypto.h:243
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:180
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:448
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
struct bofm_section_header done
Definition: bofm_test.c:46
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:218
uint64_t tx_seq
TX sequence number.
Definition: tls.h:382
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:252
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33

References __attribute__, assert(), cipher_algorithm::authsize, cipher_algorithm::blocksize, tls_cipher_suite::cipher, cipher_auth(), tls_cipherspec::cipher_ctx, cipher_encrypt, cipher_setiv(), tls_connection::cipherstream, cpu_to_be64, data, DBGC, DBGC2, DBGC2_HD, digest, tls_cipher_suite::digest, done, 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, strerror(), tls_cipherspec::suite, tls_generate_random(), tls_hmac(), tmp, tls_connection::tx_cipherspec, tls_connection::tx_seq, type, tls_header::type, tls_header::version, tls_connection::version, xfer_alloc_iob(), and xfer_deliver_iob().

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

◆ tls_clear_cipher() [1/2]

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

◆ tls_uint24()

static unsigned long tls_uint24 ( const tls24_t field24)
inlinestatic

Extract 24-bit field value.

Parameters
field2424-bit field
Return values
valueField value

Definition at line 226 of file tls.c.

226  {
227 
228  return ( ( field24->high << 16 ) | be16_to_cpu ( field24->low ) );
229 }
#define be16_to_cpu(value)
Definition: byteswap.h:115
uint16_t low
Low word.
Definition: tls.c:215
uint8_t high
High byte.
Definition: tls.c:213

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

237  {
238 
239  field24->high = ( value >> 16 );
240  field24->low = cpu_to_be16 ( value );
241 }
#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:215
uint8_t high
High byte.
Definition: tls.c:213

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

249  {
250  return ( ( ! is_pending ( &tls->client_negotiation ) ) &&
251  ( ! is_pending ( &tls->server_negotiation ) ) );
252 }
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:375
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:377

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

Referenced by tls_cipherstream_window(), tls_new_hello_request(), tls_new_record(), 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 266 of file tls.c.

266  {
267  return ( ( TLS_VERSION_MIN >= version ) ||
268  ( tls->version >= version ) );
269 }
u32 version
Driver version.
Definition: ath9k_hw.c:1983
uint16_t version
Protocol version.
Definition: tls.h:335
#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_send_client_key_exchange_dhe().

◆ md5_sha1_init()

static void md5_sha1_init ( void *  ctx)
static

Initialise MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context

Definition at line 283 of file tls.c.

283  {
284  struct md5_sha1_context *context = ctx;
285 
286  digest_init ( &md5_algorithm, context->md5 );
287  digest_init ( &sha1_algorithm, context->sha1 );
288 }
An MD5+SHA1 context.
Definition: tls.h:261
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:198
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:265
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:263
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 297 of file tls.c.

297  {
298  struct md5_sha1_context *context = ctx;
299 
300  digest_update ( &md5_algorithm, context->md5, data, len );
301  digest_update ( &sha1_algorithm, context->sha1, data, len );
302 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:203
An MD5+SHA1 context.
Definition: tls.h:261
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint32_t len
Length.
Definition: ena.h:14
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:265
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:263
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 310 of file tls.c.

310  {
311  struct md5_sha1_context *context = ctx;
312  struct md5_sha1_digest *digest = out;
313 
314  digest_final ( &md5_algorithm, context->md5, digest->md5 );
315  digest_final ( &sha1_algorithm, context->sha1, digest->sha1 );
316 }
An MD5+SHA1 context.
Definition: tls.h:261
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:208
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
__be32 out[4]
Definition: CIB_PRM.h:36
An MD5+SHA1 digest.
Definition: tls.h:272
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:265
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:263
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, digest_final(), md5_sha1_context::md5, md5_algorithm, out, md5_sha1_context::sha1, and sha1_algorithm.

◆ free_tls_session()

static void free_tls_session ( struct refcnt refcnt)
static

Free TLS session.

Parameters
refcntReference counter

Definition at line 348 of file tls.c.

348  {
349  struct tls_session *session =
350  container_of ( refcnt, struct tls_session, refcnt );
351 
352  /* Sanity check */
353  assert ( list_empty ( &session->conn ) );
354 
355  /* Remove from list of sessions */
356  list_del ( &session->list );
357 
358  /* Free dynamically-allocated resources */
359  x509_root_put ( session->root );
360  privkey_put ( session->key );
361  free ( session->ticket );
362 
363  /* Free session */
364  free ( session );
365 }
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:373
A reference counter.
Definition: refcnt.h:26
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct ntlm_data session
Session key.
Definition: ntlm.h:24
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
A TLS session.
Definition: tls.h:283

References assert(), container_of, free, list_del, list_empty, privkey_put(), session, and x509_root_put().

Referenced by tls_session().

◆ free_tls()

static void free_tls ( struct refcnt refcnt)
static

Free TLS connection.

Parameters
refcntReference counter

Definition at line 372 of file tls.c.

372  {
373  struct tls_connection *tls =
375  struct tls_session *session = tls->session;
376  struct io_buffer *iobuf;
377  struct io_buffer *tmp;
378 
379  /* Free dynamically-allocated resources */
380  free ( tls->new_session_ticket );
381  tls_clear_cipher ( tls, &tls->tx_cipherspec );
383  tls_clear_cipher ( tls, &tls->rx_cipherspec );
385  free ( tls->server_key );
386  free ( tls->handshake_ctx );
387  list_for_each_entry_safe ( iobuf, tmp, &tls->rx_data, list ) {
388  list_del ( &iobuf->list );
389  free_iob ( iobuf );
390  }
391  x509_chain_put ( tls->certs );
392  x509_chain_put ( tls->chain );
393  x509_root_put ( tls->root );
394  privkey_put ( tls->key );
395 
396  /* Drop reference to session */
397  assert ( list_empty ( &tls->list ) );
398  ref_put ( &session->refcnt );
399 
400  /* Free TLS structure itself */
401  free ( tls );
402 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:370
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:317
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition: x509.h:373
struct x509_root * root
Root of trust.
Definition: tls.h:368
A reference counter.
Definition: refcnt.h:26
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:53
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:357
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:337
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct ntlm_data session
Session key.
Definition: ntlm.h:24
void * new_session_ticket
New session ticket.
Definition: tls.h:325
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:361
struct list_head list
List of connections within the same session.
Definition: tls.h:319
#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:447
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * server_key
Server Key Exchange record (if any)
Definition: tls.h:351
struct private_key * key
Private key.
Definition: tls.h:359
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:341
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:339
struct list_head rx_data
List of received data buffers.
Definition: tls.h:397
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
A TLS session.
Definition: tls.h:283
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:343
A TLS connection.
Definition: tls.h:312
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
A persistent I/O buffer.
Definition: iobuf.h:33

References assert(), tls_connection::certs, tls_connection::chain, container_of, free, free_iob(), tls_connection::handshake_ctx, tls_connection::key, io_buffer::list, tls_connection::list, list_del, list_empty, list_for_each_entry_safe, tls_connection::new_session_ticket, privkey_put(), ref_put, tls_connection::root, tls_connection::rx_cipherspec, tls_connection::rx_cipherspec_pending, tls_connection::rx_data, tls_connection::server_key, session, tls_connection::session, tls_clear_cipher(), tmp, tls_connection::tx_cipherspec, tls_connection::tx_cipherspec_pending, x509_chain_put(), and x509_root_put().

Referenced by add_tls().

◆ tls_close()

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

Finish with TLS connection.

Parameters
tlsTLS connection
rcStatus code

Definition at line 410 of file tls.c.

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

References tls_connection::cipherstream, tls_connection::client_negotiation, INIT_LIST_HEAD, intf_shutdown(), tls_connection::list, list_del, pending_put(), tls_connection::plainstream, tls_connection::process, process_del(), rc, tls_connection::server_negotiation, tls_connection::session, tls_tx_resume_all(), tls_connection::validation, and tls_connection::validator.

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

◆ tls_generate_random()

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

Generate random data.

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

Definition at line 448 of file tls.c.

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

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

Referenced by add_tls(), tls_send_client_key_exchange_dhe(), tls_send_client_key_exchange_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 471 of file tls.c.

472  {
473  void *data;
474  size_t len;
475 
476  while ( ( data = va_arg ( args, void * ) ) ) {
477  len = va_arg ( args, size_t );
478  hmac_update ( digest, ctx, data, len );
479  }
480 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#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
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

Referenced by tls_p_hash_va().

◆ tls_p_hash_va()

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

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

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

Definition at line 493 of file tls.c.

497  {
498  uint8_t ctx[ hmac_ctxsize ( digest ) ];
499  uint8_t ctx_partial[ sizeof ( ctx ) ];
500  uint8_t a[digest->digestsize];
501  uint8_t out_tmp[digest->digestsize];
502  size_t frag_len = digest->digestsize;
503  va_list tmp;
504 
505  DBGC2 ( tls, "TLS %p %s secret:\n", tls, digest->name );
506  DBGC2_HD ( tls, secret, secret_len );
507 
508  /* Calculate A(1) */
509  hmac_init ( digest, ctx, secret, secret_len );
510  va_copy ( tmp, seeds );
512  va_end ( tmp );
513  hmac_final ( digest, ctx, a );
514  DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name );
515  DBGC2_HD ( tls, &a, sizeof ( a ) );
516 
517  /* Generate as much data as required */
518  while ( out_len ) {
519  /* Calculate output portion */
520  hmac_init ( digest, ctx, secret, secret_len );
521  hmac_update ( digest, ctx, a, sizeof ( a ) );
522  memcpy ( ctx_partial, ctx, sizeof ( ctx_partial ) );
523  va_copy ( tmp, seeds );
525  va_end ( tmp );
526  hmac_final ( digest, ctx, out_tmp );
527 
528  /* Copy output */
529  if ( frag_len > out_len )
530  frag_len = out_len;
531  memcpy ( out, out_tmp, frag_len );
532  DBGC2 ( tls, "TLS %p %s output:\n", tls, digest->name );
533  DBGC2_HD ( tls, out, frag_len );
534 
535  /* Calculate A(i) */
536  hmac_final ( digest, ctx_partial, a );
537  DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name );
538  DBGC2_HD ( tls, &a, sizeof ( a ) );
539 
540  out += frag_len;
541  out_len -= frag_len;
542  }
543 }
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
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
uint32_t a
Definition: md4.c:28
unsigned long tmp
Definition: linux_pci.h:53
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void tls_hmac_update_va(struct digest_algorithm *digest, void *ctx, va_list args)
Update HMAC with a list of ( data, len ) pairs.
Definition: tls.c:471
__be32 out[4]
Definition: CIB_PRM.h:36
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:42
#define DBGC2_HD(...)
Definition: compiler.h:524
unsigned char uint8_t
Definition: stdint.h:10
#define DBGC2(...)
Definition: compiler.h:522
__builtin_va_list va_list
Definition: stdarg.h:6
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition: hmac.c:87

References a, ctx, DBGC2, DBGC2_HD, digest, hmac_final(), hmac_init(), hmac_update(), memcpy(), 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 555 of file tls.c.

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

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

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

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

659  {
660  struct tls_cipherspec *tx_cipherspec = &tls->tx_cipherspec_pending;
661  struct tls_cipherspec *rx_cipherspec = &tls->rx_cipherspec_pending;
662  size_t hash_size = tx_cipherspec->suite->mac_len;
663  size_t key_size = tx_cipherspec->suite->key_len;
664  size_t iv_size = tx_cipherspec->suite->fixed_iv_len;
665  size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
666  uint8_t key_block[total];
667  uint8_t *key;
668  int rc;
669 
670  /* Generate key block */
671  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
672  key_block, sizeof ( key_block ), "key expansion",
673  &tls->server_random, sizeof ( tls->server_random ),
674  &tls->client_random, sizeof ( tls->client_random ) );
675 
676  /* Split key block into portions */
677  key = key_block;
678 
679  /* TX MAC secret */
680  memcpy ( tx_cipherspec->mac_secret, key, hash_size );
681  DBGC ( tls, "TLS %p TX MAC secret:\n", tls );
682  DBGC_HD ( tls, key, hash_size );
683  key += hash_size;
684 
685  /* RX MAC secret */
686  memcpy ( rx_cipherspec->mac_secret, key, hash_size );
687  DBGC ( tls, "TLS %p RX MAC secret:\n", tls );
688  DBGC_HD ( tls, key, hash_size );
689  key += hash_size;
690 
691  /* TX key */
692  if ( ( rc = cipher_setkey ( tx_cipherspec->suite->cipher,
693  tx_cipherspec->cipher_ctx,
694  key, key_size ) ) != 0 ) {
695  DBGC ( tls, "TLS %p could not set TX key: %s\n",
696  tls, strerror ( rc ) );
697  return rc;
698  }
699  DBGC ( tls, "TLS %p TX key:\n", tls );
700  DBGC_HD ( tls, key, key_size );
701  key += key_size;
702 
703  /* RX key */
704  if ( ( rc = cipher_setkey ( rx_cipherspec->suite->cipher,
705  rx_cipherspec->cipher_ctx,
706  key, key_size ) ) != 0 ) {
707  DBGC ( tls, "TLS %p could not set TX key: %s\n",
708  tls, strerror ( rc ) );
709  return rc;
710  }
711  DBGC ( tls, "TLS %p RX key:\n", tls );
712  DBGC_HD ( tls, key, key_size );
713  key += key_size;
714 
715  /* TX initialisation vector */
716  memcpy ( tx_cipherspec->fixed_iv, key, iv_size );
717  DBGC ( tls, "TLS %p TX IV:\n", tls );
718  DBGC_HD ( tls, key, iv_size );
719  key += iv_size;
720 
721  /* RX initialisation vector */
722  memcpy ( rx_cipherspec->fixed_iv, key, iv_size );
723  DBGC ( tls, "TLS %p RX IV:\n", tls );
724  DBGC_HD ( tls, key, iv_size );
725  key += iv_size;
726 
727  assert ( ( key_block + total ) == key );
728 
729  return 0;
730 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:347
A TLS cipher specification.
Definition: tls.h:206
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:214
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:208
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:190
uint8_t master_secret[48]
Master secret.
Definition: tls.h:345
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:349
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:194
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:339
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:343
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:180
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:611
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:218
union @382 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:213
void * mac_secret
MAC secret.
Definition: tls.h:216
uint8_t key_len
Key length.
Definition: tls.h:188

References assert(), tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_setkey(), tls_connection::client_random, DBGC, DBGC_HD, tls_cipherspec::fixed_iv, tls_cipher_suite::fixed_iv_len, key, tls_cipher_suite::key_len, tls_cipher_suite::mac_len, tls_cipherspec::mac_secret, tls_connection::master_secret, memcpy(), rc, tls_connection::rx_cipherspec_pending, tls_connection::server_random, strerror(), tls_cipherspec::suite, tls_prf_label, and tls_connection::tx_cipherspec_pending.

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

◆ tls_clear_handshake()

static void tls_clear_handshake ( struct tls_connection tls)
static

Clear handshake digest algorithm.

Parameters
tlsTLS connection

Definition at line 744 of file tls.c.

744  {
745 
746  /* Select null digest algorithm */
748 
749  /* Free any existing context */
750  free ( tls->handshake_ctx );
751  tls->handshake_ctx = NULL;
752 }
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:357
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:355
#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 761 of file tls.c.

762  {
763 
764  /* Clear existing handshake digest */
765  tls_clear_handshake ( tls );
766 
767  /* Allocate and initialise context */
768  tls->handshake_ctx = malloc ( digest->ctxsize );
769  if ( ! tls->handshake_ctx )
770  return -ENOMEM;
771  tls->handshake_digest = digest;
772  digest_init ( digest, tls->handshake_ctx );
773 
774  return 0;
775 }
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define ENOMEM
Not enough space.
Definition: errno.h:534
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:357
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:198
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:355
static void tls_clear_handshake(struct tls_connection *tls)
Clear handshake digest algorithm.
Definition: tls.c:744

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

786  {
788 
790  return 0;
791 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:203
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:357
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:355
uint32_t len
Length.
Definition: ena.h:14
A message digest algorithm.
Definition: crypto.h:17
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

801  {
803  uint8_t ctx[ digest->ctxsize ];
804 
805  memcpy ( ctx, tls->handshake_ctx, sizeof ( ctx ) );
806  digest_final ( digest, ctx, out );
807 }
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:208
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:357
void * memcpy(void *dest, const void *src, size_t len) __nonnull
__be32 out[4]
Definition: CIB_PRM.h:36
unsigned char uint8_t
Definition: stdint.h:10
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:355
A message digest algorithm.
Definition: crypto.h:17

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

834  {
835  struct tls_cipher_suite *suite;
836 
837  /* Identify cipher suite */
839  if ( suite->code == cipher_suite )
840  return suite;
841  }
842 
843  return NULL;
844 }
A TLS cipher suite.
Definition: tls.h:174
#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:198
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:186

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

852  {
853 
854  if ( cipherspec->suite ) {
855  pubkey_final ( cipherspec->suite->pubkey,
856  cipherspec->pubkey_ctx );
857  }
858  free ( cipherspec->dynamic );
859  memset ( cipherspec, 0, sizeof ( *cipherspec ) );
860  cipherspec->suite = &tls_cipher_suite_null;
861 }
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:817
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:178
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:208
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:212
static void pubkey_final(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:293
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:210
void * memset(void *dest, int character, size_t len) __nonnull

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

873  {
874  struct pubkey_algorithm *pubkey = suite->pubkey;
875  struct cipher_algorithm *cipher = suite->cipher;
876  size_t total;
877  void *dynamic;
878 
879  /* Clear out old cipher contents, if any */
880  tls_clear_cipher ( tls, cipherspec );
881 
882  /* Allocate dynamic storage */
883  total = ( pubkey->ctxsize + cipher->ctxsize + suite->mac_len +
884  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->pubkey_ctx = dynamic; dynamic += pubkey->ctxsize;
895  cipherspec->cipher_ctx = dynamic; dynamic += cipher->ctxsize;
896  cipherspec->mac_secret = dynamic; dynamic += suite->mac_len;
897  cipherspec->fixed_iv = dynamic; dynamic += suite->fixed_iv_len;
898  assert ( ( cipherspec->dynamic + total ) == dynamic );
899 
900  /* Store parameters */
901  cipherspec->suite = suite;
902 
903  return 0;
904 }
#define DBGC(...)
Definition: compiler.h:505
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:178
size_t ctxsize
Context size.
Definition: crypto.h:124
#define ENOMEM_CONTEXT
Definition: tls.c:117
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:214
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:208
uint8_t fixed_iv_len
Fixed initialisation vector length.
Definition: tls.h:190
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
uint8_t mac_len
MAC length.
Definition: tls.h:194
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:212
size_t ctxsize
Context size.
Definition: crypto.h:53
A cipher algorithm.
Definition: crypto.h:49
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:180
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:210
A public key algorithm.
Definition: crypto.h:120
void * fixed_iv
Fixed initialisation vector.
Definition: tls.h:218
void * mac_secret
MAC secret.
Definition: tls.h:216

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

Referenced by tls_select_cipher().

◆ tls_select_cipher()

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

Select next cipher suite.

Parameters
tlsTLS connection
cipher_suiteCipher suite specification
Return values
rcReturn status code

Definition at line 913 of file tls.c.

914  {
915  struct tls_cipher_suite *suite;
916  struct digest_algorithm *digest;
917  int rc;
918 
919  /* Identify cipher suite */
920  suite = tls_find_cipher_suite ( cipher_suite );
921  if ( ! suite ) {
922  DBGC ( tls, "TLS %p does not support cipher %04x\n",
923  tls, ntohs ( cipher_suite ) );
924  return -ENOTSUP_CIPHER;
925  }
926 
927  /* Set handshake digest algorithm */
928  digest = ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ?
929  suite->handshake : &md5_sha1_algorithm );
930  if ( ( rc = tls_select_handshake ( tls, digest ) ) != 0 )
931  return rc;
932 
933  /* Set ciphers */
934  if ( ( rc = tls_set_cipher ( tls, &tls->tx_cipherspec_pending,
935  suite ) ) != 0 )
936  return rc;
937  if ( ( rc = tls_set_cipher ( tls, &tls->rx_cipherspec_pending,
938  suite ) ) != 0 )
939  return rc;
940 
941  DBGC ( tls, "TLS %p selected %s-%s-%s-%d-%s\n", tls,
942  suite->exchange->name, suite->pubkey->name,
943  suite->cipher->name, ( suite->key_len * 8 ),
944  suite->digest->name );
945 
946  return 0;
947 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:176
static struct tls_cipher_suite * tls_find_cipher_suite(unsigned int cipher_suite)
Identify cipher suite.
Definition: tls.c:834
#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:163
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:178
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define ENOTSUP_CIPHER
Definition: tls.c:145
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:182
A TLS cipher suite.
Definition: tls.h:174
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:319
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:339
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:266
const char * name
Algorithm name.
Definition: crypto.h:19
struct digest_algorithm * handshake
Handshake digest algorithm (for TLSv1.2 and above)
Definition: tls.h:184
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:343
A message digest algorithm.
Definition: crypto.h:17
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:180
const char * name
Algorithm name.
Definition: crypto.h:51
static int tls_set_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
Set cipher suite.
Definition: tls.c:871
static int tls_select_handshake(struct tls_connection *tls, struct digest_algorithm *digest)
Select handshake digest algorithm.
Definition: tls.c:761
const char * name
Algorithm name.
Definition: crypto.h:122
uint8_t key_len
Key length.
Definition: tls.h:188

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

Referenced by tls_new_server_hello().

◆ tls_change_cipher()

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

Activate next cipher suite.

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

Definition at line 957 of file tls.c.

959  {
960 
961  /* Sanity check */
962  if ( pending->suite == &tls_cipher_suite_null ) {
963  DBGC ( tls, "TLS %p refusing to use null cipher\n", tls );
964  return -ENOTSUP_NULL;
965  }
966 
967  tls_clear_cipher ( tls, active );
968  memswap ( active, pending, sizeof ( *active ) );
969  return 0;
970 }
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:817
#define DBGC(...)
Definition: compiler.h:505
uint32_t pending
Pending events.
Definition: hyperv.h:12
#define ENOTSUP_NULL
Definition: tls.c:149
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)

References DBGC, ENOTSUP_NULL, memswap(), pending, tls_cipher_suite_null, and tls_clear_cipher().

Referenced by tls_new_change_cipher(), and tls_tx_step().

◆ tls_signature_hash_algorithm()

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

Find TLS signature and hash algorithm.

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

Definition at line 991 of file tls.c.

992  {
993  struct tls_signature_hash_algorithm *sig_hash;
994 
995  /* Identify signature and hash algorithm */
997  if ( ( sig_hash->pubkey == pubkey ) &&
998  ( sig_hash->digest == digest ) ) {
999  return sig_hash;
1000  }
1001  }
1002 
1003  return NULL;
1004 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:232
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
A TLS signature algorithm.
Definition: tls.h:230
#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:244
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:234
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

1013  {
1014  struct tls_signature_hash_algorithm *sig_hash;
1015 
1016  /* Identify signature and hash algorithm */
1018  if ( sig_hash->code.signature == code.signature )
1019  return sig_hash->pubkey;
1020  }
1021 
1022  return NULL;
1023 }
A TLS signature algorithm.
Definition: tls.h:230
#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:226
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:244
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:236
uint8_t code
Response code.
Definition: scsi.h:16
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:234
#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_send_client_key_exchange_dhe().

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

1032  {
1033  struct tls_signature_hash_algorithm *sig_hash;
1034 
1035  /* Identify signature and hash algorithm */
1037  if ( sig_hash->code.hash == code.hash )
1038  return sig_hash->digest;
1039  }
1040 
1041  return NULL;
1042 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:232
A TLS signature algorithm.
Definition: tls.h:230
uint8_t hash
Hash algorithm.
Definition: tls.h:224
#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:244
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:236
uint8_t code
Response code.
Definition: scsi.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_send_client_key_exchange_dhe().

◆ tls_tx_resume()

static void tls_tx_resume ( struct tls_connection tls)
static

Resume TX state machine.

Parameters
tlsTLS connection

Definition at line 1056 of file tls.c.

1056  {
1057  process_add ( &tls->process );
1058 }
struct process process
TX process.
Definition: tls.h:386
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59

References tls_connection::process, and process_add().

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

◆ tls_restart()

static void tls_restart ( struct tls_connection tls)
static

Restart negotiation.

Parameters
tlsTLS connection

Definition at line 1077 of file tls.c.

1077  {
1078 
1079  /* Sanity check */
1080  assert ( ! tls->tx_pending );
1081  assert ( ! is_pending ( &tls->client_negotiation ) );
1082  assert ( ! is_pending ( &tls->server_negotiation ) );
1083  assert ( ! is_pending ( &tls->validation ) );
1084 
1085  /* (Re)start negotiation */
1087  tls_tx_resume ( tls );
1088  pending_get ( &tls->client_negotiation );
1089  pending_get ( &tls->server_negotiation );
1090 }
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:375
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1056
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:379
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:377
unsigned int tx_pending
TX pending transmissions.
Definition: tls.h:384
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45

References assert(), tls_connection::client_negotiation, is_pending(), pending_get(), tls_connection::server_negotiation, TLS_TX_CLIENT_HELLO, tls_tx_resume(), tls_connection::tx_pending, and tls_connection::validation.

Referenced by add_tls(), and tls_new_hello_request().

◆ tls_send_handshake()

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

Transmit Handshake record.

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

Definition at line 1100 of file tls.c.

1101  {
1102 
1103  /* Add to handshake digest */
1104  tls_add_handshake ( tls, data, len );
1105 
1106  /* Send record */
1107  return tls_send_plaintext ( tls, TLS_TYPE_HANDSHAKE, data, len );
1108 }
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:785
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:2661
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:59
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

Referenced by tls_send_certificate(), tls_send_certificate_verify(), tls_send_client_hello(), tls_send_client_key_exchange_dhe(), tls_send_client_key_exchange_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 1117 of file tls.c.

1120  {
1121  struct tls_session *session = tls->session;
1122  size_t name_len = strlen ( session->name );
1123  struct {
1124  uint32_t type_length;
1125  uint16_t version;
1126  uint8_t random[32];
1127  uint8_t session_id_len;
1128  uint8_t session_id[tls->session_id_len];
1129  uint16_t cipher_suite_len;
1130  uint16_t cipher_suites[TLS_NUM_CIPHER_SUITES];
1131  uint8_t compression_methods_len;
1132  uint8_t compression_methods[1];
1133  uint16_t extensions_len;
1134  struct {
1135  uint16_t server_name_type;
1136  uint16_t server_name_len;
1137  struct {
1138  uint16_t len;
1139  struct {
1140  uint8_t type;
1141  uint16_t len;
1142  uint8_t name[name_len];
1143  } __attribute__ (( packed )) list[1];
1144  } __attribute__ (( packed )) server_name;
1145  uint16_t max_fragment_length_type;
1146  uint16_t max_fragment_length_len;
1147  struct {
1148  uint8_t max;
1149  } __attribute__ (( packed )) max_fragment_length;
1150  uint16_t signature_algorithms_type;
1151  uint16_t signature_algorithms_len;
1152  struct {
1153  uint16_t len;
1154  struct tls_signature_hash_id
1156  } __attribute__ (( packed )) signature_algorithms;
1157  uint16_t renegotiation_info_type;
1158  uint16_t renegotiation_info_len;
1159  struct {
1160  uint8_t len;
1162  sizeof ( tls->verify.client ) :0];
1163  } __attribute__ (( packed )) renegotiation_info;
1164  uint16_t session_ticket_type;
1165  uint16_t session_ticket_len;
1166  struct {
1167  uint8_t data[session->ticket_len];
1168  } __attribute__ (( packed )) session_ticket;
1169  } __attribute__ (( packed )) extensions;
1170  } __attribute__ (( packed )) hello;
1171  struct tls_cipher_suite *suite;
1172  struct tls_signature_hash_algorithm *sighash;
1173  unsigned int i;
1174 
1175  /* Construct record */
1176  memset ( &hello, 0, sizeof ( hello ) );
1177  hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) |
1178  htonl ( sizeof ( hello ) -
1179  sizeof ( hello.type_length ) ) );
1180  hello.version = htons ( TLS_VERSION_MAX );
1181  memcpy ( &hello.random, &tls->client_random, sizeof ( hello.random ) );
1182  hello.session_id_len = tls->session_id_len;
1183  memcpy ( hello.session_id, tls->session_id,
1184  sizeof ( hello.session_id ) );
1185  hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) );
1186  i = 0 ; for_each_table_entry ( suite, TLS_CIPHER_SUITES )
1187  hello.cipher_suites[i++] = suite->code;
1188  hello.compression_methods_len = sizeof ( hello.compression_methods );
1189  hello.extensions_len = htons ( sizeof ( hello.extensions ) );
1190  hello.extensions.server_name_type = htons ( TLS_SERVER_NAME );
1191  hello.extensions.server_name_len
1192  = htons ( sizeof ( hello.extensions.server_name ) );
1193  hello.extensions.server_name.len
1194  = htons ( sizeof ( hello.extensions.server_name.list ) );
1195  hello.extensions.server_name.list[0].type = TLS_SERVER_NAME_HOST_NAME;
1196  hello.extensions.server_name.list[0].len
1197  = htons ( sizeof ( hello.extensions.server_name.list[0].name ));
1198  memcpy ( hello.extensions.server_name.list[0].name, session->name,
1199  sizeof ( hello.extensions.server_name.list[0].name ) );
1200  hello.extensions.max_fragment_length_type
1202  hello.extensions.max_fragment_length_len
1203  = htons ( sizeof ( hello.extensions.max_fragment_length ) );
1204  hello.extensions.max_fragment_length.max
1206  hello.extensions.signature_algorithms_type
1208  hello.extensions.signature_algorithms_len
1209  = htons ( sizeof ( hello.extensions.signature_algorithms ) );
1210  hello.extensions.signature_algorithms.len
1211  = htons ( sizeof ( hello.extensions.signature_algorithms.code));
1212  i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
1213  hello.extensions.signature_algorithms.code[i++] = sighash->code;
1214  hello.extensions.renegotiation_info_type
1216  hello.extensions.renegotiation_info_len
1217  = htons ( sizeof ( hello.extensions.renegotiation_info ) );
1218  hello.extensions.renegotiation_info.len
1219  = sizeof ( hello.extensions.renegotiation_info.data );
1220  memcpy ( hello.extensions.renegotiation_info.data, tls->verify.client,
1221  sizeof ( hello.extensions.renegotiation_info.data ) );
1222  hello.extensions.session_ticket_type = htons ( TLS_SESSION_TICKET );
1223  hello.extensions.session_ticket_len
1224  = htons ( sizeof ( hello.extensions.session_ticket ) );
1225  memcpy ( hello.extensions.session_ticket.data, session->ticket,
1226  sizeof ( hello.extensions.session_ticket.data ) );
1227 
1228  return action ( tls, &hello, sizeof ( hello ) );
1229 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:365
#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:825
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:126
#define max(x, y)
Definition: ath.h:39
struct tls_session * session
Session.
Definition: tls.h:317
uint32_t type
Operating system type.
Definition: ena.h:12
#define TLS_CLIENT_HELLO
Definition: tls.h:66
uint8_t session_id[32]
Session ID.
Definition: tls.h:321
#define htonl(value)
Definition: byteswap.h:133
#define TLS_MAX_FRAGMENT_LENGTH
Definition: tls.h:113
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Driver version.
Definition: ath9k_hw.c:1983
struct ntlm_data session
Session key.
Definition: ntlm.h:24
#define TLS_SESSION_TICKET
Definition: tls.h:123
A TLS cipher suite.
Definition: tls.h:174
#define TLS_SERVER_NAME
Definition: tls.h:109
A TLS signature algorithm.
Definition: tls.h:230
struct list_head list
List of sessions.
Definition: tls.h:287
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define TLS_NUM_SIG_HASH_ALGORITHMS
Number of supported signature and hash algorithms.
Definition: tls.c:980
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:349
#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:30
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:244
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:236
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
#define TLS_SERVER_NAME_HOST_NAME
Definition: tls.h:110
uint8_t client[12]
Client verification data.
Definition: tls.h:139
uint8_t code
Response code.
Definition: scsi.h:16
uint32_t len
Length.
Definition: ena.h:14
A TLS session.
Definition: tls.h:283
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:363
#define TLS_MAX_FRAGMENT_LENGTH_4096
Definition: tls.h:117
const char * name
Server name.
Definition: tls.h:290
A TLS signature and hash algorithm identifier.
Definition: tls.h:222
size_t session_id_len
Length of session ID.
Definition: tls.h:323
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:198
#define htons(value)
Definition: byteswap.h:135
#define TLS_SIGNATURE_ALGORITHMS
Definition: tls.h:120
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:186
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, tls_verify_data::client, tls_connection::client_random, code, tls_cipher_suite::code, tls_signature_hash_algorithm::code, cpu_to_le32, data, for_each_table_entry, hello, htonl, htons, len, tls_session::list, max, memcpy(), memset(), tls_session::name, random(), tls_connection::secure_renegotiation, session, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, strlen(), TLS_CIPHER_SUITES, TLS_CLIENT_HELLO, TLS_MAX_FRAGMENT_LENGTH, TLS_MAX_FRAGMENT_LENGTH_4096, TLS_NUM_CIPHER_SUITES, 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, 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 1237 of file tls.c.

1237  {
1238 
1239  return tls_client_hello ( tls, tls_send_handshake );
1240 }
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1100
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:1117

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

1248  {
1249  struct {
1250  tls24_t length;
1251  uint8_t data[0];
1252  } __attribute__ (( packed )) *certificate;
1253  struct {
1254  uint32_t type_length;
1255  tls24_t length;
1256  typeof ( *certificate ) certificates[0];
1257  } __attribute__ (( packed )) *certificates;
1258  struct x509_link *link;
1259  struct x509_certificate *cert;
1260  size_t len;
1261  int rc;
1262 
1263  /* Calculate length of client certificates */
1264  len = 0;
1265  list_for_each_entry ( link, &tls->certs->links, list ) {
1266  cert = link->cert;
1267  len += ( sizeof ( *certificate ) + cert->raw.len );
1268  DBGC ( tls, "TLS %p sending client certificate %s\n",
1269  tls, x509_name ( cert ) );
1270  }
1271 
1272  /* Allocate storage for Certificate record (which may be too
1273  * large for the stack).
1274  */
1275  certificates = zalloc ( sizeof ( *certificates ) + len );
1276  if ( ! certificates )
1277  return -ENOMEM_CERTIFICATE;
1278 
1279  /* Populate record */
1280  certificates->type_length =
1282  htonl ( sizeof ( *certificates ) + len -
1283  sizeof ( certificates->type_length ) ) );
1284  tls_set_uint24 ( &certificates->length, len );
1285  certificate = &certificates->certificates[0];
1286  list_for_each_entry ( link, &tls->certs->links, list ) {
1287  cert = link->cert;
1288  tls_set_uint24 ( &certificate->length, cert->raw.len );
1289  memcpy ( certificate->data, cert->raw.data, cert->raw.len );
1290  certificate = ( ( ( void * ) certificate->data ) +
1291  cert->raw.len );
1292  }
1293 
1294  /* Transmit record */
1295  rc = tls_send_handshake ( tls, certificates,
1296  ( sizeof ( *certificates ) + len ) );
1297 
1298  /* Free record */
1299  free ( certificates );
1300 
1301  return rc;
1302 }
#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:181
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:69
#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:1100
size_t len
Length of data.
Definition: asn1.h:24
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:361
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:185
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
A TLS 24-bit integer.
Definition: tls.c:211
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:145
uint32_t len
Length.
Definition: ena.h:14
#define ENOMEM_CERTIFICATE
Definition: tls.c:121
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static void tls_set_uint24(tls24_t *field24, unsigned long value)
Set 24-bit field value.
Definition: tls.c:237
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
struct asn1_cursor raw
Raw certificate.
Definition: x509.h:200

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

Referenced by tls_tx_step().

◆ tls_send_client_key_exchange_pubkey()

static int tls_send_client_key_exchange_pubkey ( struct tls_connection tls)
static

Transmit Client Key Exchange record using public key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1310 of file tls.c.

1310  {
1311  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
1312  struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1313  size_t max_len = pubkey_max_len ( pubkey, cipherspec->pubkey_ctx );
1314  struct {
1315  uint16_t version;
1316  uint8_t random[46];
1317  } __attribute__ (( packed )) pre_master_secret;
1318  struct {
1319  uint32_t type_length;
1320  uint16_t encrypted_pre_master_secret_len;
1321  uint8_t encrypted_pre_master_secret[max_len];
1322  } __attribute__ (( packed )) key_xchg;
1323  size_t unused;
1324  int len;
1325  int rc;
1326 
1327  /* Generate pre-master secret */
1328  pre_master_secret.version = htons ( TLS_VERSION_MAX );
1329  if ( ( rc = tls_generate_random ( tls, &pre_master_secret.random,
1330  ( sizeof ( pre_master_secret.random ) ) ) ) != 0 ) {
1331  return rc;
1332  }
1333 
1334  /* Generate master secret */
1335  tls_generate_master_secret ( tls, &pre_master_secret,
1336  sizeof ( pre_master_secret ) );
1337 
1338  /* Generate keys */
1339  if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
1340  DBGC ( tls, "TLS %p could not generate keys: %s\n",
1341  tls, strerror ( rc ) );
1342  return rc;
1343  }
1344 
1345  /* Encrypt pre-master secret using server's public key */
1346  memset ( &key_xchg, 0, sizeof ( key_xchg ) );
1347  len = pubkey_encrypt ( pubkey, cipherspec->pubkey_ctx,
1348  &pre_master_secret, sizeof ( pre_master_secret ),
1349  key_xchg.encrypted_pre_master_secret );
1350  if ( len < 0 ) {
1351  rc = len;
1352  DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
1353  tls, strerror ( rc ) );
1354  return rc;
1355  }
1356  unused = ( max_len - len );
1357  key_xchg.type_length =
1359  htonl ( sizeof ( key_xchg ) -
1360  sizeof ( key_xchg.type_length ) - unused ) );
1361  key_xchg.encrypted_pre_master_secret_len =
1362  htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) -
1363  unused );
1364 
1365  return tls_send_handshake ( tls, &key_xchg,
1366  ( sizeof ( key_xchg ) - unused ) );
1367 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
static void tls_generate_master_secret(struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
Generate master secret.
Definition: tls.c:631
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:206
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:178
#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:1100
static size_t pubkey_max_len(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:265
u32 version
Driver version.
Definition: ath9k_hw.c:1983
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:208
#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:30
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:212
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:339
#define TLS_VERSION_MAX
Maximum supported TLS version.
Definition: tls.h:50
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:659
uint32_t len
Length.
Definition: ena.h:14
uint8_t unused[32]
Unused.
Definition: eltorito.h:15
static int pubkey_encrypt(struct pubkey_algorithm *pubkey, void *ctx, const void *data, size_t len, void *out)
Definition: crypto.h:270
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:448
A public key algorithm.
Definition: crypto.h:120
#define htons(value)
Definition: byteswap.h:135
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:74
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, cpu_to_le32, DBGC, htonl, htons, len, max_len, memset(), tls_cipher_suite::pubkey, tls_cipherspec::pubkey_ctx, pubkey_encrypt(), pubkey_max_len(), random(), rc, strerror(), tls_cipherspec::suite, TLS_CLIENT_KEY_EXCHANGE, tls_generate_keys(), tls_generate_master_secret(), tls_generate_random(), tls_send_handshake(), TLS_VERSION_MAX, tls_connection::tx_cipherspec_pending, unused, and version.

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

1381  {
1382  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
1383  struct pubkey_algorithm *pubkey;
1384  struct digest_algorithm *digest;
1385  int use_sig_hash = tls_version ( tls, TLS_VERSION_TLS_1_2 );
1386  uint8_t private[ sizeof ( tls->client_random.random ) ];
1387  const struct {
1388  uint16_t len;
1389  uint8_t data[0];
1390  } __attribute__ (( packed )) *dh_val[3];
1391  const struct {
1392  struct tls_signature_hash_id sig_hash[use_sig_hash];
1393  uint16_t signature_len;
1394  uint8_t signature[0];
1395  } __attribute__ (( packed )) *sig;
1396  const void *data;
1397  size_t remaining;
1398  size_t frag_len;
1399  unsigned int i;
1400  int rc;
1401 
1402  /* Parse ServerKeyExchange */
1403  data = tls->server_key;
1404  remaining = tls->server_key_len;
1405  for ( i = 0 ; i < ( sizeof ( dh_val ) / sizeof ( dh_val[0] ) ) ; i++ ){
1406  dh_val[i] = data;
1407  if ( ( sizeof ( *dh_val[i] ) > remaining ) ||
1408  ( ntohs ( dh_val[i]->len ) > ( remaining -
1409  sizeof ( *dh_val[i] ) ) )){
1410  DBGC ( tls, "TLS %p received underlength "
1411  "ServerKeyExchange\n", tls );
1412  DBGC_HDA ( tls, 0, tls->server_key,
1413  tls->server_key_len );
1415  goto err_header;
1416  }
1417  frag_len = ( sizeof ( *dh_val[i] ) + ntohs ( dh_val[i]->len ));
1418  data += frag_len;
1419  remaining -= frag_len;
1420  }
1421  sig = data;
1422  if ( ( sizeof ( *sig ) > remaining ) ||
1423  ( ntohs ( sig->signature_len ) > ( remaining -
1424  sizeof ( *sig ) ) ) ) {
1425  DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
1426  tls );
1427  DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
1429  goto err_header;
1430  }
1431 
1432  /* Identify signature and hash algorithm */
1433  if ( use_sig_hash ) {
1434  pubkey = tls_signature_hash_pubkey ( sig->sig_hash[0] );
1435  digest = tls_signature_hash_digest ( sig->sig_hash[0] );
1436  if ( ( ! pubkey ) || ( ! digest ) ) {
1437  DBGC ( tls, "TLS %p ServerKeyExchange unsupported "
1438  "signature and hash algorithm\n", tls );
1439  rc = -ENOTSUP_SIG_HASH;
1440  goto err_sig_hash;
1441  }
1442  if ( pubkey != cipherspec->suite->pubkey ) {
1443  DBGC ( tls, "TLS %p ServerKeyExchange incorrect "
1444  "signature algorithm %s (expected %s)\n", tls,
1445  pubkey->name, cipherspec->suite->pubkey->name );
1447  goto err_sig_hash;
1448  }
1449  } else {
1450  pubkey = cipherspec->suite->pubkey;
1452  }
1453 
1454  /* Verify signature */
1455  {
1456  const void *signature = sig->signature;
1457  size_t signature_len = ntohs ( sig->signature_len );
1458  uint8_t ctx[digest->ctxsize];
1459  uint8_t hash[digest->digestsize];
1460 
1461  /* Calculate digest */
1462  digest_init ( digest, ctx );
1464  sizeof ( tls->client_random ) );
1466  sizeof ( tls->server_random ) );
1468  ( tls->server_key_len - remaining ) );
1469  digest_final ( digest, ctx, hash );
1470 
1471  /* Verify signature */
1472  if ( ( rc = pubkey_verify ( pubkey, cipherspec->pubkey_ctx,
1473  digest, hash, signature,
1474  signature_len ) ) != 0 ) {
1475  DBGC ( tls, "TLS %p ServerKeyExchange failed "
1476  "verification\n", tls );
1477  DBGC_HDA ( tls, 0, tls->server_key,
1478  tls->server_key_len );
1480  goto err_verify;
1481  }
1482  }
1483 
1484  /* Generate Diffie-Hellman private key */
1485  if ( ( rc = tls_generate_random ( tls, private,
1486  sizeof ( private ) ) ) != 0 ) {
1487  goto err_random;
1488  }
1489 
1490  /* Construct pre-master secret and ClientKeyExchange record */
1491  {
1492  typeof ( dh_val[0] ) dh_p = dh_val[0];
1493  typeof ( dh_val[1] ) dh_g = dh_val[1];
1494  typeof ( dh_val[2] ) dh_ys = dh_val[2];
1495  size_t len = ntohs ( dh_p->len );
1496  struct {
1497  uint32_t type_length;
1498  uint16_t dh_xs_len;
1499  uint8_t dh_xs[len];
1500  } __attribute__ (( packed )) *key_xchg;
1501  struct {
1502  uint8_t pre_master_secret[len];
1503  typeof ( *key_xchg ) key_xchg;
1504  } *dynamic;
1505  uint8_t *pre_master_secret;
1506 
1507  /* Allocate space */
1508  dynamic = malloc ( sizeof ( *dynamic ) );
1509  if ( ! dynamic ) {
1510  rc = -ENOMEM;
1511  goto err_alloc;
1512  }
1513  pre_master_secret = dynamic->pre_master_secret;
1514  key_xchg = &dynamic->key_xchg;
1515  key_xchg->type_length =
1517  htonl ( sizeof ( *key_xchg ) -
1518  sizeof ( key_xchg->type_length ) ) );
1519  key_xchg->dh_xs_len = htons ( len );
1520 
1521  /* Calculate pre-master secret and client public value */
1522  if ( ( rc = dhe_key ( dh_p->data, len,
1523  dh_g->data, ntohs ( dh_g->len ),
1524  dh_ys->data, ntohs ( dh_ys->len ),
1525  private, sizeof ( private ),
1526  key_xchg->dh_xs,
1527  pre_master_secret ) ) != 0 ) {
1528  DBGC ( tls, "TLS %p could not calculate DHE key: %s\n",
1529  tls, strerror ( rc ) );
1530  goto err_dhe_key;
1531  }
1532 
1533  /* Strip leading zeroes from pre-master secret */
1534  while ( len && ( ! *pre_master_secret ) ) {
1535  pre_master_secret++;
1536  len--;
1537  }
1538 
1539  /* Generate master secret */
1540  tls_generate_master_secret ( tls, pre_master_secret, len );
1541 
1542  /* Generate keys */
1543  if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
1544  DBGC ( tls, "TLS %p could not generate keys: %s\n",
1545  tls, strerror ( rc ) );
1546  goto err_generate_keys;
1547  }
1548 
1549  /* Transmit Client Key Exchange record */
1550  if ( ( rc = tls_send_handshake ( tls, key_xchg,
1551  sizeof ( *key_xchg ) ) ) !=0){
1552  goto err_send_handshake;
1553  }
1554 
1555  err_send_handshake:
1556  err_generate_keys:
1557  err_dhe_key:
1558  free ( dynamic );
1559  }
1560  err_alloc:
1561  err_random:
1562  err_verify:
1563  err_sig_hash:
1564  err_header:
1565  return rc;
1566 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:203
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 struct pubkey_algorithm * tls_signature_hash_pubkey(struct tls_signature_hash_id code)
Find TLS signature algorithm.
Definition: tls.c:1013
u8 sig
Definition: CIB_PRM.h:43
#define EPERM_KEY_EXCHANGE
Definition: tls.c:181
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:208
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:631
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:347
static struct digest_algorithm * tls_signature_hash_digest(struct tls_signature_hash_id code)
Find TLS hash algorithm.
Definition: tls.c:1032
#define ntohs(value)
Definition: byteswap.h:136
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
A TLS cipher specification.
Definition: tls.h:206
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:178
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#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:1100
#define ENOMEM
Not enough space.
Definition: errno.h:534
static int pubkey_verify(struct pubkey_algorithm *pubkey, void *ctx, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
Definition: crypto.h:286
#define DBGC_HDA(...)
Definition: compiler.h:506
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:208
#define cpu_to_le32(value)
Definition: byteswap.h:107
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:319
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:198
pseudo_bit_t hash[0x00010]
Hash algorithm.
Definition: arbel.h:13
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:349
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * server_key
Server Key Exchange record (if any)
Definition: tls.h:351
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:212
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:339
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:659
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:266
uint8_t random[28]
Random data.
Definition: tls.h:257
uint32_t len
Length.
Definition: ena.h:14
A message digest algorithm.
Definition: crypto.h:17
uint8_t data[48]
Additional event data.
Definition: ena.h:22
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
#define EINVAL_KEY_EXCHANGE
Definition: tls.c:109
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:448
A TLS signature and hash algorithm identifier.
Definition: tls.h:222
#define ENOTSUP_SIG_HASH
Definition: tls.c:153
u8 signature
Signature.
Definition: CIB_PRM.h:35
A public key algorithm.
Definition: crypto.h:120
#define htons(value)
Definition: byteswap.h:135
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:74
const char * name
Algorithm name.
Definition: crypto.h:122
size_t server_key_len
Server Key Exchange record length.
Definition: tls.h:353

References __attribute__, tls_connection::client_random, cpu_to_le32, ctx, data, DBGC, DBGC_HDA, dhe_key(), digest, digest_final(), digest_init(), digest_update(), EINVAL_KEY_EXCHANGE, ENOMEM, ENOTSUP_SIG_HASH, EPERM_KEY_EXCHANGE, free, hash, htonl, htons, len, malloc(), md5_sha1_algorithm, pubkey_algorithm::name, ntohs, tls_cipher_suite::pubkey, tls_cipherspec::pubkey_ctx, pubkey_verify(), tls_client_random::random, rc, tls_connection::server_key, tls_connection::server_key_len, tls_connection::server_random, sig, signature, strerror(), tls_cipherspec::suite, TLS_CLIENT_KEY_EXCHANGE, tls_generate_keys(), tls_generate_master_secret(), tls_generate_random(), tls_send_handshake(), tls_signature_hash_digest(), tls_signature_hash_pubkey(), tls_version(), TLS_VERSION_TLS_1_2, tls_connection::tx_cipherspec_pending, and typeof().

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

1580  {
1581  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
1582  struct tls_cipher_suite *suite = cipherspec->suite;
1583 
1584  /* Transmit Client Key Exchange record via key exchange algorithm */
1585  return suite->exchange->exchange ( tls );
1586 }
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
Definition: tls.h:176
A TLS cipher specification.
Definition: tls.h:206
int(* exchange)(struct tls_connection *tls)
Transmit Client Key Exchange record.
Definition: tls.h:170
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:208
A TLS cipher suite.
Definition: tls.h:174
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:339

References tls_key_exchange_algorithm::exchange, tls_cipher_suite::exchange, tls_cipherspec::suite, and tls_connection::tx_cipherspec_pending.

Referenced by tls_tx_step().

◆ tls_send_certificate_verify()

static int tls_send_certificate_verify ( struct tls_connection tls)
static

Transmit Certificate Verify record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1594 of file tls.c.

1594  {
1595  struct digest_algorithm *digest = tls->handshake_digest;
1596  struct x509_certificate *cert = x509_first ( tls->certs );
1597  struct pubkey_algorithm *pubkey = cert->signature_algorithm->pubkey;
1598  struct asn1_cursor *key = privkey_cursor ( tls->key );
1599  uint8_t digest_out[ digest->digestsize ];
1600  uint8_t ctx[ pubkey->ctxsize ];
1601  struct tls_signature_hash_algorithm *sig_hash = NULL;
1602  int rc;
1603 
1604  /* Generate digest to be signed */
1605  tls_verify_handshake ( tls, digest_out );
1606 
1607  /* Initialise public-key algorithm */
1608  if ( ( rc = pubkey_init ( pubkey, ctx, key->data, key->len ) ) != 0 ) {
1609  DBGC ( tls, "TLS %p could not initialise %s client private "
1610  "key: %s\n", tls, pubkey->name, strerror ( rc ) );
1611  goto err_pubkey_init;
1612  }
1613 
1614  /* TLSv1.2 and later use explicit algorithm identifiers */
1615  if ( tls_version ( tls, TLS_VERSION_TLS_1_2 ) ) {
1616  sig_hash = tls_signature_hash_algorithm ( pubkey, digest );
1617  if ( ! sig_hash ) {
1618  DBGC ( tls, "TLS %p could not identify (%s,%s) "
1619  "signature and hash algorithm\n", tls,
1620  pubkey->name, digest->name );
1621  rc = -ENOTSUP_SIG_HASH;
1622  goto err_sig_hash;
1623  }
1624  }
1625 
1626  /* Generate and transmit record */
1627  {
1628  size_t max_len = pubkey_max_len ( pubkey, ctx );
1629  int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
1630  struct {
1631  uint32_t type_length;
1632  struct tls_signature_hash_id sig_hash[use_sig_hash];
1633  uint16_t signature_len;
1635  } __attribute__ (( packed )) certificate_verify;
1636  size_t unused;
1637  int len;
1638 
1639  /* Sign digest */
1640  len = pubkey_sign ( pubkey, ctx, digest, digest_out,
1641  certificate_verify.signature );
1642  if ( len < 0 ) {
1643  rc = len;
1644  DBGC ( tls, "TLS %p could not sign %s digest using %s "
1645  "client private key: %s\n", tls, digest->name,
1646  pubkey->name, strerror ( rc ) );
1647  goto err_pubkey_sign;
1648  }
1649  unused = ( max_len - len );
1650 
1651  /* Construct Certificate Verify record */
1652  certificate_verify.type_length =
1654  htonl ( sizeof ( certificate_verify ) -
1655  sizeof ( certificate_verify.type_length ) -
1656  unused ) );
1657  if ( use_sig_hash ) {
1658  memcpy ( &certificate_verify.sig_hash[0],
1659  &sig_hash->code,
1660  sizeof ( certificate_verify.sig_hash[0] ) );
1661  }
1662  certificate_verify.signature_len =
1663  htons ( sizeof ( certificate_verify.signature ) -
1664  unused );
1665 
1666  /* Transmit record */
1667  rc = tls_send_handshake ( tls, &certificate_verify,
1668  ( sizeof ( certificate_verify ) - unused ) );
1669  }
1670 
1671  err_pubkey_sign:
1672  err_sig_hash:
1673  pubkey_final ( pubkey, ctx );
1674  err_pubkey_init:
1675  return rc;
1676 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:801
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
struct asn1_algorithm * signature_algorithm
Signature algorithm.
Definition: x509.h:208
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:47
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define htonl(value)
Definition: byteswap.h:133
size_t ctxsize
Context size.
Definition: crypto.h:124
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1100
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition: privkey.h:52
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:312
static size_t pubkey_max_len(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:265
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:991
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:361
A TLS signature algorithm.
Definition: tls.h:230
#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:185
unsigned char uint8_t
Definition: stdint.h:10
struct private_key * key
Private key.
Definition: tls.h:359
unsigned int uint32_t
Definition: stdint.h:12
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:236
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
Definition: tls.c:266
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:355
uint32_t len
Length.
Definition: ena.h:14
uint8_t unused[32]
Unused.
Definition: eltorito.h:15
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:280
static int pubkey_sign(struct pubkey_algorithm *pubkey, void *ctx, struct digest_algorithm *digest, const void *value, void *signature)
Definition: crypto.h:280
A message digest algorithm.
Definition: crypto.h:17
static void pubkey_final(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:293
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:234
A TLS signature and hash algorithm identifier.
Definition: tls.h:222
#define TLS_CERTIFICATE_VERIFY
Definition: tls.h:73
#define ENOTSUP_SIG_HASH
Definition: tls.c:153
u8 signature
Signature.
Definition: CIB_PRM.h:35
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
An ASN.1 object cursor.
Definition: asn1.h:20
A public key algorithm.
Definition: crypto.h:120
#define htons(value)
Definition: byteswap.h:135
union @382 key
Sense key.
Definition: scsi.h:18
const char * name
Algorithm name.
Definition: crypto.h:122
static int pubkey_init(struct pubkey_algorithm *pubkey, void *ctx, const void *key, size_t key_len)
Definition: crypto.h:260

References __attribute__, tls_connection::certs, tls_signature_hash_algorithm::code, cpu_to_le32, ctx, pubkey_algorithm::ctxsize, DBGC, digest, ENOTSUP_SIG_HASH, tls_connection::handshake_digest, htonl, htons, key, tls_connection::key, len, max_len, memcpy(), pubkey_algorithm::name, NULL, privkey_cursor(), tls_signature_hash_algorithm::pubkey, asn1_algorithm::pubkey, pubkey_final(), pubkey_init(), 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 1684 of file tls.c.

1684  {
1685  static const uint8_t change_cipher[1] = { 1 };
1687  change_cipher, sizeof ( change_cipher ) );
1688 }
#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:2661
unsigned char uint8_t
Definition: stdint.h:10

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

1696  {
1697  struct digest_algorithm *digest = tls->handshake_digest;
1698  struct {
1699  uint32_t type_length;
1700  uint8_t verify_data[ sizeof ( tls->verify.client ) ];
1701  } __attribute__ (( packed )) finished;
1702  uint8_t digest_out[ digest->digestsize ];
1703  int rc;
1704 
1705  /* Construct client verification data */
1706  tls_verify_handshake ( tls, digest_out );
1707  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
1708  tls->verify.client, sizeof ( tls->verify.client ),
1709  "client finished", digest_out, sizeof ( digest_out ) );
1710 
1711  /* Construct record */
1712  memset ( &finished, 0, sizeof ( finished ) );
1713  finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
1714  htonl ( sizeof ( finished ) -
1715  sizeof ( finished.type_length ) ) );
1716  memcpy ( finished.verify_data, tls->verify.client,
1717  sizeof ( finished.verify_data ) );
1718 
1719  /* Transmit record */
1720  if ( ( rc = tls_send_handshake ( tls, &finished,
1721  sizeof ( finished ) ) ) != 0 )
1722  return rc;
1723 
1724  /* Mark client as finished */
1725  pending_put ( &tls->client_negotiation );
1726 
1727  return 0;
1728 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:365
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:375
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:801
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#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:1100
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint8_t master_secret[48]
Master secret.
Definition: tls.h:345
#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:139
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:355
A message digest algorithm.
Definition: crypto.h:17
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:611
#define TLS_FINISHED
Definition: tls.h:75
void * memset(void *dest, int character, size_t len) __nonnull

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

Referenced by tls_tx_step().

◆ tls_new_change_cipher()

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

Receive new Change Cipher record.

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

Definition at line 1738 of file tls.c.

1739  {
1740  int rc;
1741 
1742  if ( ( len != 1 ) || ( *( ( uint8_t * ) data ) != 1 ) ) {
1743  DBGC ( tls, "TLS %p received invalid Change Cipher\n", tls );
1744  DBGC_HD ( tls, data, len );
1745  return -EINVAL_CHANGE_CIPHER;
1746  }
1747 
1748  if ( ( rc = tls_change_cipher ( tls, &tls->rx_cipherspec_pending,
1749  &tls->rx_cipherspec ) ) != 0 ) {
1750  DBGC ( tls, "TLS %p could not activate RX cipher: %s\n",
1751  tls, strerror ( rc ) );
1752  return rc;
1753  }
1754  tls->rx_seq = ~( ( uint64_t ) 0 );
1755 
1756  return 0;
1757 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint64_t rx_seq
RX sequence number.
Definition: tls.h:389
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
#define EINVAL_CHANGE_CIPHER
Definition: tls.c:57
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec *pending, struct tls_cipherspec *active)
Activate next cipher suite.
Definition: tls.c:957
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:341
uint32_t len
Length.
Definition: ena.h:14
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:343
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References data, DBGC, DBGC_HD, EINVAL_CHANGE_CIPHER, len, rc, tls_connection::rx_cipherspec, tls_connection::rx_cipherspec_pending, tls_connection::rx_seq, strerror(), and tls_change_cipher().

Referenced by tls_new_record().

◆ tls_new_alert()

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

Receive new Alert record.

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

Definition at line 1767 of file tls.c.

1768  {
1769  const struct {
1770  uint8_t level;
1771  uint8_t description;
1772  char next[0];
1773  } __attribute__ (( packed )) *alert = data;
1774 
1775  /* Sanity check */
1776  if ( sizeof ( *alert ) != len ) {
1777  DBGC ( tls, "TLS %p received overlength Alert\n", tls );
1778  DBGC_HD ( tls, data, len );
1779  return -EINVAL_ALERT;
1780  }
1781 
1782  switch ( alert->level ) {
1783  case TLS_ALERT_WARNING:
1784  DBGC ( tls, "TLS %p received warning alert %d\n",
1785  tls, alert->description );
1786  return 0;
1787  case TLS_ALERT_FATAL:
1788  DBGC ( tls, "TLS %p received fatal alert %d\n",
1789  tls, alert->description );
1790  return -EPERM_ALERT;
1791  default:
1792  DBGC ( tls, "TLS %p received unknown alert level %d"
1793  "(alert %d)\n", tls, alert->level, alert->description );
1794  return -EIO_ALERT;
1795  }
1796 }
#define __attribute__(x)
Definition: compiler.h:10
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
#define EIO_ALERT
Definition: tls.c:113
#define TLS_ALERT_WARNING
Definition: tls.h:78
#define EINVAL_ALERT
Definition: tls.c:61
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_ALERT_FATAL
Definition: tls.h:79
uint32_t len
Length.
Definition: ena.h:14
static void alert(const char *fmt,...)
Print alert message.
Definition: settings_ui.c:324
#define EPERM_ALERT
Definition: tls.c:161
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References __attribute__, alert(), data, DBGC, DBGC_HD, EINVAL_ALERT, EIO_ALERT, EPERM_ALERT, 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 1806 of file tls.c.

1808  {
1809 
1810  /* Ignore if a handshake is in progress */
1811  if ( ! tls_ready ( tls ) ) {
1812  DBGC ( tls, "TLS %p ignoring Hello Request\n", tls );
1813  return 0;
1814  }
1815 
1816  /* Fail unless server supports secure renegotiation */
1817  if ( ! tls->secure_renegotiation ) {
1818  DBGC ( tls, "TLS %p refusing to renegotiate insecurely\n",
1819  tls );
1820  return -EPERM_RENEG_INSECURE;
1821  }
1822 
1823  /* Restart negotiation */
1824  tls_restart ( tls );
1825 
1826  return 0;
1827 }
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition: tls.c:1077
#define DBGC(...)
Definition: compiler.h:505
#define EPERM_RENEG_INSECURE
Definition: tls.c:173
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:363
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:249

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

1838  {
1839  const struct {
1840  uint16_t version;
1841  uint8_t random[32];
1842  uint8_t session_id_len;
1843  uint8_t session_id[0];
1844  } __attribute__ (( packed )) *hello_a = data;
1845  const uint8_t *session_id;
1846  const struct {
1847  uint16_t cipher_suite;
1848  uint8_t compression_method;
1849  char next[0];
1850  } __attribute__ (( packed )) *hello_b;
1851  const struct {
1852  uint16_t len;
1853  uint8_t data[0];
1854  } __attribute__ (( packed )) *exts;
1855  const struct {
1856  uint16_t type;
1857  uint16_t len;
1858  uint8_t data[0];
1859  } __attribute__ (( packed )) *ext;
1860  const struct {
1861  uint8_t len;
1862  uint8_t data[0];
1863  } __attribute__ (( packed )) *reneg = NULL;
1864  uint16_t version;
1865  size_t exts_len;
1866  size_t ext_len;
1867  size_t remaining;
1868  int rc;
1869 
1870  /* Parse header */
1871  if ( ( sizeof ( *hello_a ) > len ) ||
1872  ( hello_a->session_id_len > ( len - sizeof ( *hello_a ) ) ) ||
1873  ( sizeof ( *hello_b ) > ( len - sizeof ( *hello_a ) -
1874  hello_a->session_id_len ) ) ) {
1875  DBGC ( tls, "TLS %p received underlength Server Hello\n", tls );
1876  DBGC_HD ( tls, data, len );
1877  return -EINVAL_HELLO;
1878  }
1879  session_id = hello_a->session_id;
1880  hello_b = ( ( void * ) ( session_id + hello_a->session_id_len ) );
1881 
1882  /* Parse extensions, if present */
1883  remaining = ( len - sizeof ( *hello_a ) - hello_a->session_id_len -
1884  sizeof ( *hello_b ) );
1885  if ( remaining ) {
1886 
1887  /* Parse extensions length */
1888  exts = ( ( void * ) hello_b->next );
1889  if ( ( sizeof ( *exts ) > remaining ) ||
1890  ( ( exts_len = ntohs ( exts->len ) ) >
1891  ( remaining - sizeof ( *exts ) ) ) ) {
1892  DBGC ( tls, "TLS %p received underlength extensions\n",
1893  tls );
1894  DBGC_HD ( tls, data, len );
1895  return -EINVAL_HELLO;
1896  }
1897 
1898  /* Parse extensions */
1899  for ( ext = ( ( void * ) exts->data ), remaining = exts_len ;
1900  remaining ;
1901  ext = ( ( ( void * ) ext ) + sizeof ( *ext ) + ext_len ),
1902  remaining -= ( sizeof ( *ext ) + ext_len ) ) {
1903 
1904  /* Parse extension length */
1905  if ( ( sizeof ( *ext ) > remaining ) ||
1906  ( ( ext_len = ntohs ( ext->len ) ) >
1907  ( remaining - sizeof ( *ext ) ) ) ) {
1908  DBGC ( tls, "TLS %p received underlength "
1909  "extension\n", tls );
1910  DBGC_HD ( tls, data, len );
1911  return -EINVAL_HELLO;
1912  }
1913 
1914  /* Record known extensions */
1915  switch ( ext->type ) {
1916  case htons ( TLS_RENEGOTIATION_INFO ) :
1917  reneg = ( ( void * ) ext->data );
1918  if ( ( sizeof ( *reneg ) > ext_len ) ||
1919  ( reneg->len >
1920  ( ext_len - sizeof ( *reneg ) ) ) ) {
1921  DBGC ( tls, "TLS %p received "
1922  "underlength renegotiation "
1923  "info\n", tls );
1924  DBGC_HD ( tls, data, len );
1925  return -EINVAL_HELLO;
1926  }
1927  break;
1928  }
1929  }
1930  }
1931 
1932  /* Check and store protocol version */
1933  version = ntohs ( hello_a->version );
1934  if ( version < TLS_VERSION_MIN ) {
1935  DBGC ( tls, "TLS %p does not support protocol version %d.%d\n",
1936  tls, ( version >> 8 ), ( version & 0xff ) );
1937  return -ENOTSUP_VERSION;
1938  }
1939  if ( version > tls->version ) {
1940  DBGC ( tls, "TLS %p server attempted to illegally upgrade to "
1941  "protocol version %d.%d\n",
1942  tls, ( version >> 8 ), ( version & 0xff ) );
1943  return -EPROTO_VERSION;
1944  }
1945  tls->version = version;
1946  DBGC ( tls, "TLS %p using protocol version %d.%d\n",
1947  tls, ( version >> 8 ), ( version & 0xff ) );
1948 
1949  /* Select cipher suite */
1950  if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 )
1951  return rc;
1952 
1953  /* Add preceding Client Hello to handshake digest */
1954  if ( ( rc = tls_client_hello ( tls, tls_add_handshake ) ) != 0 )
1955  return rc;
1956 
1957  /* Copy out server random bytes */
1958  memcpy ( &tls->server_random, &hello_a->random,
1959  sizeof ( tls->server_random ) );
1960 
1961  /* Check session ID */
1962  if ( hello_a->session_id_len &&
1963  ( hello_a->session_id_len == tls->session_id_len ) &&
1964  ( memcmp ( session_id, tls->session_id,
1965  tls->session_id_len ) == 0 ) ) {
1966 
1967  /* Session ID match: reuse master secret */
1968  DBGC ( tls, "TLS %p resuming session ID:\n", tls );
1969  DBGC_HDA ( tls, 0, tls->session_id, tls->session_id_len );
1970  if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
1971  return rc;
1972 
1973  } else {
1974 
1975  /* Record new session ID, if present */
1976  if ( hello_a->session_id_len &&
1977  ( hello_a->session_id_len <= sizeof ( tls->session_id ))){
1978  tls->session_id_len = hello_a->session_id_len;
1979  memcpy ( tls->session_id, session_id,
1980  tls->session_id_len );
1981  DBGC ( tls, "TLS %p new session ID:\n", tls );
1982  DBGC_HDA ( tls, 0, tls->session_id,
1983  tls->session_id_len );
1984  }
1985  }
1986 
1987  /* Handle secure renegotiation */
1988  if ( tls->secure_renegotiation ) {
1989 
1990  /* Secure renegotiation is expected; verify data */
1991  if ( ( reneg == NULL ) ||
1992  ( reneg->len != sizeof ( tls->verify ) ) ||
1993  ( memcmp ( reneg->data, &tls->verify,
1994  sizeof ( tls->verify ) ) != 0 ) ) {
1995  DBGC ( tls, "TLS %p server failed secure "
1996  "renegotiation\n", tls );
1997  return -EPERM_RENEG_VERIFY;
1998  }
1999 
2000  } else if ( reneg != NULL ) {
2001 
2002  /* Secure renegotiation is being enabled */
2003  if ( reneg->len != 0 ) {
2004  DBGC ( tls, "TLS %p server provided non-empty initial "
2005  "renegotiation\n", tls );
2006  return -EPERM_RENEG_VERIFY;
2007  }
2008  tls->secure_renegotiation = 1;
2009  }
2010 
2011  return 0;
2012 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:365
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static int tls_select_cipher(struct tls_connection *tls, unsigned int cipher_suite)
Select next cipher suite.
Definition: tls.c:913
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:126
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define EINVAL_HELLO
Definition: tls.c:65
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:785
uint32_t type
Operating system type.
Definition: ena.h:12
#define ENOTSUP_VERSION
Definition: tls.c:157
#define DBGC(...)
Definition: compiler.h:505
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:347
uint8_t session_id[32]
Session ID.
Definition: tls.h:321
#define EPROTO_VERSION
Definition: tls.c:185
#define ntohs(value)
Definition: byteswap.h:136
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:30
unsigned char uint8_t
Definition: stdint.h:10
#define EPERM_RENEG_VERIFY
Definition: tls.c:177
uint16_t ext
Extended status.
Definition: ena.h:20
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:659
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:1117
uint32_t len
Length.
Definition: ena.h:14
uint16_t version
Protocol version.
Definition: tls.h:335
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:363
size_t session_id_len
Length of session ID.
Definition: tls.h:323
#define TLS_VERSION_MIN
Minimum TLS version.
Definition: crypto.h:13
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135

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

Referenced by tls_new_handshake().

◆ tls_new_session_ticket()

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

Receive New Session Ticket handshake record.

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

Definition at line 2022 of file tls.c.

2023  {
2024  const struct {
2026  uint16_t len;
2027  uint8_t ticket[0];
2028  } __attribute__ (( packed )) *new_session_ticket = data;
2029  size_t ticket_len;
2030 
2031  /* Parse header */
2032  if ( sizeof ( *new_session_ticket ) > len ) {
2033  DBGC ( tls, "TLS %p received underlength New Session Ticket\n",
2034  tls );
2035  DBGC_HD ( tls, data, len );
2036  return -EINVAL_TICKET;
2037  }
2038  ticket_len = ntohs ( new_session_ticket->len );
2039  if ( ticket_len > ( len - sizeof ( *new_session_ticket ) ) ) {
2040  DBGC ( tls, "TLS %p received overlength New Session Ticket\n",
2041  tls );
2042  DBGC_HD ( tls, data, len );
2043  return -EINVAL_TICKET;
2044  }
2045 
2046  /* Free any unapplied new session ticket */
2047  free ( tls->new_session_ticket );
2048  tls->new_session_ticket = NULL;
2049  tls->new_session_ticket_len = 0;
2050 
2051  /* Record ticket */
2052  tls->new_session_ticket = malloc ( ticket_len );
2053  if ( ! tls->new_session_ticket )
2054  return -ENOMEM;
2055  memcpy ( tls->new_session_ticket, new_session_ticket->ticket,
2056  ticket_len );
2057  tls->new_session_ticket_len = ticket_len;
2058  DBGC ( tls, "TLS %p new session ticket:\n", tls );
2059  DBGC_HDA ( tls, 0, tls->new_session_ticket,
2060  tls->new_session_ticket_len );
2061 
2062  return 0;
2063 }
#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:327
#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:325
#define DBGC_HDA(...)
Definition: compiler.h:506
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
Definition: wpa.h:54
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_TICKET
Definition: tls.c:105
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_new_handshake().

◆ tls_parse_chain()

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

Parse certificate chain.

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

Definition at line 2073 of file tls.c.

2074  {
2075  size_t remaining = len;
2076  int rc;
2077 
2078  /* Free any existing certificate chain */
2079  x509_chain_put ( tls->chain );
2080  tls->chain = NULL;
2081 
2082  /* Create certificate chain */
2083  tls->chain = x509_alloc_chain();
2084  if ( ! tls->chain ) {
2085  rc = -ENOMEM_CHAIN;
2086  goto err_alloc_chain;
2087  }
2088 
2089  /* Add certificates to chain */
2090  while ( remaining ) {
2091  const struct {
2092  tls24_t length;
2093  uint8_t data[0];
2094  } __attribute__ (( packed )) *certificate = data;
2095  size_t certificate_len;
2096  size_t record_len;
2097  struct x509_certificate *cert;
2098 
2099  /* Parse header */
2100  if ( sizeof ( *certificate ) > remaining ) {
2101  DBGC ( tls, "TLS %p underlength certificate:\n", tls );
2102  DBGC_HDA ( tls, 0, data, remaining );
2104  goto err_underlength;
2105  }
2106  certificate_len = tls_uint24 ( &certificate->length );
2107  if ( certificate_len > ( remaining - sizeof ( *certificate ) )){
2108  DBGC ( tls, "TLS %p overlength certificate:\n", tls );
2109  DBGC_HDA ( tls, 0, data, remaining );
2111  goto err_overlength;
2112  }
2113  record_len = ( sizeof ( *certificate ) + certificate_len );
2114 
2115  /* Add certificate to chain */
2116  if ( ( rc = x509_append_raw ( tls->chain, certificate->data,
2117  certificate_len ) ) != 0 ) {
2118  DBGC ( tls, "TLS %p could not append certificate: %s\n",
2119  tls, strerror ( rc ) );
2120  DBGC_HDA ( tls, 0, data, remaining );
2121  goto err_parse;
2122  }
2123  cert = x509_last ( tls->chain );
2124  DBGC ( tls, "TLS %p found certificate %s\n",
2125  tls, x509_name ( cert ) );
2126 
2127  /* Move to next certificate in list */
2128  data += record_len;
2129  remaining -= record_len;
2130  }
2131 
2132  return 0;
2133 
2134  err_parse:
2135  err_overlength:
2136  err_underlength:
2137  x509_chain_put ( tls->chain );
2138  tls->chain = NULL;
2139  err_alloc_chain:
2140  return rc;
2141 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
#define __attribute__(x)
Definition: compiler.h:10
u16 length
Definition: sky2.h:9
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:370
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:226
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:1675
#define DBGC(...)
Definition: compiler.h:505
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1627
#define ENOMEM_CHAIN
Definition: tls.c:125
#define EINVAL_CERTIFICATE
Definition: tls.c:69
#define DBGC_HDA(...)
Definition: compiler.h:506
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition: x509.h:294
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:185
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:211
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:145
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_new_certificate().

◆ tls_new_certificate()

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

Receive new Certificate handshake record.

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

Definition at line 2151 of file tls.c.

2152  {
2153  const struct {
2154  tls24_t length;
2155  uint8_t certificates[0];
2156  } __attribute__ (( packed )) *certificate = data;
2157  size_t certificates_len;
2158  int rc;
2159 
2160  /* Parse header */
2161  if ( sizeof ( *certificate ) > len ) {
2162  DBGC ( tls, "TLS %p received underlength Server Certificate\n",
2163  tls );
2164  DBGC_HD ( tls, data, len );
2165  return -EINVAL_CERTIFICATES;
2166  }
2167  certificates_len = tls_uint24 ( &certificate->length );
2168  if ( certificates_len > ( len - sizeof ( *certificate ) ) ) {
2169  DBGC ( tls, "TLS %p received overlength Server Certificate\n",
2170  tls );
2171  DBGC_HD ( tls, data, len );
2172  return -EINVAL_CERTIFICATES;
2173  }
2174 
2175  /* Parse certificate chain */
2176  if ( ( rc = tls_parse_chain ( tls, certificate->certificates,
2177  certificates_len ) ) != 0 )
2178  return rc;
2179 
2180  return 0;
2181 }
#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:226
#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:211
uint32_t len
Length.
Definition: ena.h:14
static int tls_parse_chain(struct tls_connection *tls, const void *data, size_t len)
Parse certificate chain.
Definition: tls.c:2073
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EINVAL_CERTIFICATES
Definition: tls.c:73

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

Referenced by tls_new_handshake().

◆ tls_new_server_key_exchange()

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

Receive new Server Key Exchange handshake record.

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

Definition at line 2191 of file tls.c.

2192  {
2193 
2194  /* Free any existing server key exchange record */
2195  free ( tls->server_key );
2196  tls->server_key_len = 0;
2197 
2198  /* Allocate copy of server key exchange record */
2199  tls->server_key = malloc ( len );
2200  if ( ! tls->server_key )
2201  return -ENOMEM;
2202 
2203  /* Store copy of server key exchange record for later
2204  * processing. We cannot verify the signature at this point
2205  * since the certificate validation will not yet have
2206  * completed.
2207  */
2208  memcpy ( tls->server_key, data, len );
2209  tls->server_key_len = len;
2210 
2211  return 0;
2212 }
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * server_key
Server Key Exchange record (if any)
Definition: tls.h:351
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t server_key_len
Server Key Exchange record length.
Definition: tls.h:353

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

Referenced by tls_new_handshake().

◆ tls_new_certificate_request()

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

Receive new Certificate Request handshake record.

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

Definition at line 2222 of file tls.c.

2224  {
2225  struct x509_certificate *cert;
2226  int rc;
2227 
2228  /* We can only send a single certificate, so there is no point
2229  * in parsing the Certificate Request.
2230  */
2231 
2232  /* Free any existing client certificate chain */
2233  x509_chain_put ( tls->certs );
2234  tls->certs = NULL;
2235 
2236  /* Determine client certificate to be sent */
2237  cert = certstore_find_key ( tls->key );
2238  if ( ! cert ) {
2239  DBGC ( tls, "TLS %p could not find certificate corresponding "
2240  "to private key\n", tls );
2241  rc = -EPERM_CLIENT_CERT;
2242  goto err_find;
2243  }
2244  x509_get ( cert );
2245  DBGC ( tls, "TLS %p selected client certificate %s\n",
2246  tls, x509_name ( cert ) );
2247 
2248  /* Create client certificate chain */
2249  tls->certs = x509_alloc_chain();
2250  if ( ! tls->certs ) {
2251  rc = -ENOMEM;
2252  goto err_alloc;
2253  }
2254 
2255  /* Append client certificate to chain */
2256  if ( ( rc = x509_append ( tls->certs, cert ) ) != 0 )
2257  goto err_append;
2258 
2259  /* Append any relevant issuer certificates */
2260  if ( ( rc = x509_auto_append ( tls->certs, &certstore ) ) != 0 )
2261  goto err_auto_append;
2262 
2263  /* Drop local reference to client certificate */
2264  x509_put ( cert );
2265 
2266  return 0;
2267 
2268  err_auto_append:
2269  err_append:
2270  x509_chain_put ( tls->certs );
2271  tls->certs = NULL;
2272  err_alloc:
2273  x509_put ( cert );
2274  err_find:
2275  return rc;
2276 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
#define EPERM_CLIENT_CERT
Definition: tls.c:169
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_certificate * certstore_find_key(struct private_key *key)
Find certificate in store corresponding to a private key.
Definition: certstore.c:119
struct x509_chain certstore
Certificate store.
Definition: certstore.c:73
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition: x509.h:236
#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:1650
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1627
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct x509_chain * certs
Client certificate chain (if used)
Definition: tls.h:361
An X.509 certificate.
Definition: x509.h:185
struct private_key * key
Private key.
Definition: tls.h:359
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:145
int x509_auto_append(struct x509_chain *chain, struct x509_chain *certs)
Append X.509 certificates to X.509 certificate chain.
Definition: x509.c:1734
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:247
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_new_handshake().

◆ tls_new_server_hello_done()

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

Receive new Server Hello Done handshake record.

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

Definition at line 2286 of file tls.c.

2287  {
2288  const struct {
2289  char next[0];
2290  } __attribute__ (( packed )) *hello_done = data;
2291  int rc;
2292 
2293  /* Sanity check */
2294  if ( sizeof ( *hello_done ) != len ) {
2295  DBGC ( tls, "TLS %p received overlength Server Hello Done\n",
2296  tls );
2297  DBGC_HD ( tls, data, len );
2298  return -EINVAL_HELLO_DONE;
2299  }
2300 
2301  /* Begin certificate validation */
2302  if ( ( rc = create_validator ( &tls->validator, tls->chain,
2303  tls->root ) ) != 0 ) {
2304  DBGC ( tls, "TLS %p could not start certificate validation: "
2305  "%s\n", tls, strerror ( rc ) );
2306  return rc;
2307  }
2308  pending_get ( &tls->validation );
2309 
2310  return 0;
2311 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:370
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
#define EINVAL_HELLO_DONE
Definition: tls.c:77
struct x509_root * root
Root of trust.
Definition: tls.h:368
int create_validator(struct interface *job, struct x509_chain *chain, struct x509_root *root)
Instantiate a certificate validator.
Definition: validator.c:630
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:379
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC_HD(...)
Definition: compiler.h:507
uint32_t len
Length.
Definition: ena.h:14
struct interface validator
Certificate validator.
Definition: tls.h:372
uint8_t data[48]
Additional event data.
Definition: ena.h:22
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45

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

Referenced by tls_new_handshake().

◆ tls_new_finished()

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

Receive new Finished handshake record.

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

Definition at line 2321 of file tls.c.

2322  {
2323  struct tls_session *session = tls->session;
2324  struct digest_algorithm *digest = tls->handshake_digest;
2325  const struct {
2326  uint8_t verify_data[ sizeof ( tls->verify.server ) ];
2327  char next[0];
2328  } __attribute__ (( packed )) *finished = data;
2329  uint8_t digest_out[ digest->digestsize ];
2330 
2331  /* Sanity check */
2332  if ( sizeof ( *finished ) != len ) {
2333  DBGC ( tls, "TLS %p received overlength Finished\n", tls );
2334  DBGC_HD ( tls, data, len );
2335  return -EINVAL_FINISHED;
2336  }
2337 
2338  /* Verify data */
2339  tls_verify_handshake ( tls, digest_out );
2340  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
2341  tls->verify.server, sizeof ( tls->verify.server ),
2342  "server finished", digest_out, sizeof ( digest_out ) );
2343  if ( memcmp ( tls->verify.server, finished->verify_data,
2344  sizeof ( tls->verify.server ) ) != 0 ) {
2345  DBGC ( tls, "TLS %p verification failed\n", tls );
2346  return -EPERM_VERIFY;
2347  }
2348 
2349  /* Mark server as finished */
2350  pending_put ( &tls->server_negotiation );
2351 
2352  /* If we are resuming a session (i.e. if the server Finished
2353  * arrives before the client Finished is sent), then schedule
2354  * transmission of Change Cipher and Finished.
2355  */
2356  if ( is_pending ( &tls->client_negotiation ) ) {
2358  tls_tx_resume ( tls );
2359  }
2360 
2361  /* Record session ID, ticket, and master secret, if applicable */
2362  if ( tls->session_id_len || tls->new_session_ticket_len ) {
2363  memcpy ( session->master_secret, tls->master_secret,
2364  sizeof ( session->master_secret ) );
2365  }
2366  if ( tls->session_id_len ) {
2367  session->id_len = tls->session_id_len;
2368  memcpy ( session->id, tls->session_id, sizeof ( session->id ) );
2369  }
2370  if ( tls->new_session_ticket_len ) {
2371  free ( session->ticket );
2372  session->ticket = tls->new_session_ticket;
2373  session->ticket_len = tls->new_session_ticket_len;
2374  tls->new_session_ticket = NULL;
2375  tls->new_session_ticket_len = 0;
2376  }
2377 
2378  /* Move to end of session's connection list and allow other
2379  * connections to start making progress.
2380  */
2381  list_del ( &tls->list );
2382  list_add_tail ( &tls->list, &session->conn );
2384 
2385  /* Send notification of a window change */
2386  xfer_window_changed ( &tls->plainstream );
2387 
2388  return 0;
2389 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:365
#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:1065
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:145
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:375
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1056
struct tls_session * session
Session.
Definition: tls.h:317
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:801
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:327
uint8_t session_id[32]
Session ID.
Definition: tls.h:321
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct ntlm_data session
Session key.
Definition: ntlm.h:24
void * new_session_ticket
New session ticket.
Definition: tls.h:325
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define EINVAL_FINISHED
Definition: tls.c:81
struct list_head list
List of connections within the same session.
Definition: tls.h:319
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
#define EPERM_VERIFY
Definition: tls.c:165
uint8_t master_secret[48]
Master secret.
Definition: tls.h:345
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:377
unsigned int tx_pending
TX pending transmissions.
Definition: tls.h:384
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:355
uint32_t len
Length.
Definition: ena.h:14
A TLS session.
Definition: tls.h:283
A message digest algorithm.
Definition: crypto.h:17
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t server[12]
Server verification data.
Definition: tls.h:141
size_t session_id_len
Length of session ID.
Definition: tls.h:323
struct interface plainstream
Plaintext stream.
Definition: tls.h:330
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:611

References __attribute__, tls_connection::client_negotiation, data, DBGC, DBGC_HD, digest, EINVAL_FINISHED, EPERM_VERIFY, free, tls_connection::handshake_digest, is_pending(), len, tls_connection::list, list_add_tail, list_del, tls_connection::master_secret, memcmp(), memcpy(), tls_connection::new_session_ticket, tls_connection::new_session_ticket_len, next, NULL, pending_put(), tls_connection::plainstream, tls_verify_data::server, tls_connection::server_negotiation, session, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, tls_prf_label, TLS_TX_CHANGE_CIPHER, TLS_TX_FINISHED, tls_tx_resume(), tls_tx_resume_all(), tls_verify_handshake(), tls_connection::tx_pending, tls_connection::verify, and xfer_window_changed().

Referenced by tls_new_handshake().

◆ tls_new_handshake()

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

Receive new Handshake record.

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

Definition at line 2399 of file tls.c.

2400  {
2401  size_t remaining = len;
2402  int rc;
2403 
2404  while ( remaining ) {
2405  const struct {
2406  uint8_t type;
2407  tls24_t length;
2408  uint8_t payload[0];
2409  } __attribute__ (( packed )) *handshake = data;
2410  const void *payload;
2411  size_t payload_len;
2412  size_t record_len;
2413 
2414  /* Parse header */
2415  if ( sizeof ( *handshake ) > remaining ) {
2416  DBGC ( tls, "TLS %p received underlength Handshake\n",
2417  tls );
2418  DBGC_HD ( tls, data, remaining );
2419  return -EINVAL_HANDSHAKE;
2420  }
2421  payload_len = tls_uint24 ( &handshake->length );
2422  if ( payload_len > ( remaining - sizeof ( *handshake ) ) ) {
2423  DBGC ( tls, "TLS %p received overlength Handshake\n",
2424  tls );
2425  DBGC_HD ( tls, data, len );
2426  return -EINVAL_HANDSHAKE;
2427  }
2428  payload = &handshake->payload;
2429  record_len = ( sizeof ( *handshake ) + payload_len );
2430 
2431  /* Handle payload */
2432  switch ( handshake->type ) {
2433  case TLS_HELLO_REQUEST:
2434  rc = tls_new_hello_request ( tls, payload,
2435  payload_len );
2436  break;
2437  case TLS_SERVER_HELLO:
2438  rc = tls_new_server_hello ( tls, payload, payload_len );
2439  break;
2441  rc = tls_new_session_ticket ( tls, payload,
2442  payload_len );
2443  break;
2444  case TLS_CERTIFICATE:
2445  rc = tls_new_certificate ( tls, payload, payload_len );
2446  break;
2448  rc = tls_new_server_key_exchange ( tls, payload,
2449  payload_len );
2450  break;
2452  rc = tls_new_certificate_request ( tls, payload,
2453  payload_len );
2454  break;
2455  case TLS_SERVER_HELLO_DONE:
2456  rc = tls_new_server_hello_done ( tls, payload,
2457  payload_len );
2458  break;
2459  case TLS_FINISHED:
2460  rc = tls_new_finished ( tls, payload, payload_len );
2461  break;
2462  default:
2463  DBGC ( tls, "TLS %p ignoring handshake type %d\n",
2464  tls, handshake->type );
2465