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

Transport Layer Security Protocol. More...

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

Go to the source code of this file.

Data Structures

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

Macros

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )
 
#define EINFO_EINVAL_CHANGE_CIPHER
 
#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )
 
#define EINFO_EINVAL_ALERT
 
#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )
 
#define EINFO_EINVAL_HELLO
 
#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )
 
#define EINFO_EINVAL_CERTIFICATE
 
#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )
 
#define EINFO_EINVAL_CERTIFICATES
 
#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )
 
#define EINFO_EINVAL_HELLO_DONE
 
#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )
 
#define EINFO_EINVAL_FINISHED
 
#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )
 
#define EINFO_EINVAL_HANDSHAKE
 
#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )
 
#define EINFO_EINVAL_IV
 
#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )
 
#define EINFO_EINVAL_PADDING
 
#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )
 
#define EINFO_EINVAL_RX_STATE
 
#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )
 
#define EINFO_EINVAL_MAC
 
#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )
 
#define EINFO_EINVAL_TICKET
 
#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )
 
#define EINFO_EINVAL_KEY_EXCHANGE
 
#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )
 
#define EINFO_EIO_ALERT
 
#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )
 
#define EINFO_ENOMEM_CONTEXT
 
#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )
 
#define EINFO_ENOMEM_CERTIFICATE
 
#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )
 
#define EINFO_ENOMEM_CHAIN
 
#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )
 
#define EINFO_ENOMEM_TX_PLAINTEXT
 
#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )
 
#define EINFO_ENOMEM_TX_CIPHERTEXT
 
#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )
 
#define EINFO_ENOMEM_RX_DATA
 
#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )
 
#define EINFO_ENOMEM_RX_CONCAT
 
#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )
 
#define EINFO_ENOTSUP_CIPHER
 
#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )
 
#define EINFO_ENOTSUP_NULL
 
#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )
 
#define EINFO_ENOTSUP_SIG_HASH
 
#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )
 
#define EINFO_ENOTSUP_VERSION
 
#define ENOTSUP_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )
 
#define EINFO_ENOTSUP_CURVE
 
#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )
 
#define EINFO_EPERM_ALERT
 
#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )
 
#define EINFO_EPERM_VERIFY
 
#define EPERM_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )
 
#define EINFO_EPERM_CLIENT_CERT
 
#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )
 
#define EINFO_EPERM_RENEG_INSECURE
 
#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )
 
#define EINFO_EPERM_RENEG_VERIFY
 
#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )
 
#define EINFO_EPERM_KEY_EXCHANGE
 
#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )
 
#define EINFO_EPROTO_VERSION
 
#define tls_prf_label(tls, secret, secret_len, out, out_len, label, ...)
 Generate secure pseudo-random data. More...
 
#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )
 Number of supported cipher suites. More...
 
#define TLS_NUM_SIG_HASH_ALGORITHMS   table_num_entries ( TLS_SIG_HASH_ALGORITHMS )
 Number of supported signature and hash algorithms. More...
 
#define TLS_NUM_NAMED_CURVES   table_num_entries ( TLS_NAMED_CURVES )
 Number of supported named curves. More...
 

Functions

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

Variables

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

Detailed Description

Transport Layer Security Protocol.

Definition in file tls.c.

Macro Definition Documentation

◆ EINVAL_CHANGE_CIPHER

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )

Definition at line 57 of file tls.c.

◆ EINFO_EINVAL_CHANGE_CIPHER

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

Definition at line 58 of file tls.c.

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

Definition at line 61 of file tls.c.

◆ EINFO_EINVAL_ALERT

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

Definition at line 62 of file tls.c.

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

Definition at line 65 of file tls.c.

◆ EINFO_EINVAL_HELLO

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

Definition at line 66 of file tls.c.

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

Definition at line 69 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATE

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

Definition at line 70 of file tls.c.

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

Definition at line 73 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATES

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

Definition at line 74 of file tls.c.

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

Definition at line 77 of file tls.c.

◆ EINFO_EINVAL_HELLO_DONE

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

Definition at line 78 of file tls.c.

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

Definition at line 81 of file tls.c.

◆ EINFO_EINVAL_FINISHED

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

Definition at line 82 of file tls.c.

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

Definition at line 85 of file tls.c.

◆ EINFO_EINVAL_HANDSHAKE

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

Definition at line 86 of file tls.c.

◆ EINVAL_IV

#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )

Definition at line 89 of file tls.c.

◆ EINFO_EINVAL_IV

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

Definition at line 90 of file tls.c.

◆ EINVAL_PADDING

#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )

Definition at line 93 of file tls.c.

◆ EINFO_EINVAL_PADDING

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

Definition at line 94 of file tls.c.

◆ EINVAL_RX_STATE

#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )

Definition at line 97 of file tls.c.

◆ EINFO_EINVAL_RX_STATE

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

Definition at line 98 of file tls.c.

◆ EINVAL_MAC

#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )

Definition at line 101 of file tls.c.

◆ EINFO_EINVAL_MAC

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

Definition at line 102 of file tls.c.

◆ EINVAL_TICKET

#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )

Definition at line 105 of file tls.c.

◆ EINFO_EINVAL_TICKET

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

Definition at line 106 of file tls.c.

◆ EINVAL_KEY_EXCHANGE

#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )

Definition at line 109 of file tls.c.

◆ EINFO_EINVAL_KEY_EXCHANGE

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

Definition at line 110 of file tls.c.

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

Definition at line 113 of file tls.c.

◆ EINFO_EIO_ALERT

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

Definition at line 114 of file tls.c.

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

Definition at line 117 of file tls.c.

◆ EINFO_ENOMEM_CONTEXT

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

Definition at line 118 of file tls.c.

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

Definition at line 121 of file tls.c.

◆ EINFO_ENOMEM_CERTIFICATE

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

Definition at line 122 of file tls.c.

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

Definition at line 125 of file tls.c.

◆ EINFO_ENOMEM_CHAIN

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

Definition at line 126 of file tls.c.

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

Definition at line 129 of file tls.c.

◆ EINFO_ENOMEM_TX_PLAINTEXT

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

Definition at line 130 of file tls.c.

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

Definition at line 133 of file tls.c.

◆ EINFO_ENOMEM_TX_CIPHERTEXT

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

Definition at line 134 of file tls.c.

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

Definition at line 137 of file tls.c.

◆ EINFO_ENOMEM_RX_DATA

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

Definition at line 138 of file tls.c.

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

Definition at line 141 of file tls.c.

◆ EINFO_ENOMEM_RX_CONCAT

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

Definition at line 142 of file tls.c.

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

Definition at line 145 of file tls.c.

◆ EINFO_ENOTSUP_CIPHER

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

Definition at line 146 of file tls.c.

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

Definition at line 149 of file tls.c.

◆ EINFO_ENOTSUP_NULL

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

Definition at line 150 of file tls.c.

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

Definition at line 153 of file tls.c.

◆ EINFO_ENOTSUP_SIG_HASH

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

Definition at line 154 of file tls.c.

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

Definition at line 157 of file tls.c.

◆ EINFO_ENOTSUP_VERSION

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

Definition at line 158 of file tls.c.

◆ ENOTSUP_CURVE

#define ENOTSUP_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )

Definition at line 161 of file tls.c.

◆ EINFO_ENOTSUP_CURVE

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

Definition at line 162 of file tls.c.

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

Definition at line 165 of file tls.c.

◆ EINFO_EPERM_ALERT

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

Definition at line 166 of file tls.c.

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

Definition at line 169 of file tls.c.

◆ EINFO_EPERM_VERIFY

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

Definition at line 170 of file tls.c.

◆ EPERM_CLIENT_CERT

#define EPERM_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )

Definition at line 173 of file tls.c.

◆ EINFO_EPERM_CLIENT_CERT

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

Definition at line 174 of file tls.c.

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

Definition at line 177 of file tls.c.

◆ EINFO_EPERM_RENEG_INSECURE

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

Definition at line 178 of file tls.c.

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

Definition at line 181 of file tls.c.

◆ EINFO_EPERM_RENEG_VERIFY

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

Definition at line 182 of file tls.c.

◆ EPERM_KEY_EXCHANGE

#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )

Definition at line 185 of file tls.c.

◆ EINFO_EPERM_KEY_EXCHANGE

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

Definition at line 186 of file tls.c.

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

Definition at line 189 of file tls.c.

◆ EINFO_EPROTO_VERSION

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

Definition at line 190 of file tls.c.

◆ tls_prf_label

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

Generate secure pseudo-random data.

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

Definition at line 616 of file tls.c.

◆ TLS_NUM_CIPHER_SUITES

#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )

Number of supported cipher suites.

Definition at line 830 of file tls.c.

◆ TLS_NUM_SIG_HASH_ALGORITHMS

#define TLS_NUM_SIG_HASH_ALGORITHMS   table_num_entries ( TLS_SIG_HASH_ALGORITHMS )

Number of supported signature and hash algorithms.

Definition at line 985 of file tls.c.

◆ TLS_NUM_NAMED_CURVES

#define TLS_NUM_NAMED_CURVES   table_num_entries ( TLS_NAMED_CURVES )

Number of supported named curves.

Definition at line 1057 of file tls.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ LIST_HEAD()

static LIST_HEAD ( tls_sessions  )
static

List of TLS session.

◆ tls_tx_resume_all()

static void tls_tx_resume_all ( struct tls_session session)
static

Resume TX state machine for all connections within a session.

Parameters
sessionTLS session

Definition at line 1099 of file tls.c.

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

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

Referenced by tls_close(), and tls_new_finished().

◆ tls_send_plaintext()

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

Send plaintext record.

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

Definition at line 2936 of file tls.c.

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

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

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

◆ tls_clear_cipher() [1/2]

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

◆ tls_uint24()

static unsigned long tls_uint24 ( const tls24_t field24)
inlinestatic

Extract 24-bit field value.

Parameters
field2424-bit field
Return values
valueField value

Definition at line 230 of file tls.c.

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

References be16_to_cpu, tls24_t::high, and tls24_t::low.

Referenced by tls_new_certificate(), tls_new_handshake(), and tls_parse_chain().

◆ tls_set_uint24()

static void tls_set_uint24 ( tls24_t field24,
unsigned long  value 
)
static

Set 24-bit field value.

Parameters
field2424-bit field
valueField value

Definition at line 241 of file tls.c.

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

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

Referenced by tls_send_certificate().

◆ tls_ready()

static int tls_ready ( struct tls_connection tls)
static

Determine if TLS connection is ready for application data.

Parameters
tlsTLS connection
Return values
is_readyTLS connection is ready

Definition at line 253 of file tls.c.

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

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

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

◆ tls_version()

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

Check for TLS version.

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

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

Definition at line 270 of file tls.c.

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

References TLS_VERSION_MIN, tls_connection::version, and version.

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

◆ md5_sha1_init()

static void md5_sha1_init ( void *  ctx)
static

Initialise MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context

Definition at line 287 of file tls.c.

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

References ctx, md5_sha1_context::md5, md5_algorithm, md5_sha1_context::sha1, and sha1_algorithm.

◆ md5_sha1_update()

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

Accumulate data with MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context
dataData
lenLength of data

Definition at line 301 of file tls.c.

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

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

◆ md5_sha1_final()

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

Generate MD5+SHA1 digest.

Parameters
ctxMD5+SHA1 context
outOutput buffer

Definition at line 314 of file tls.c.

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

References ctx, digest, md5_sha1_context::md5, md5_algorithm, out, md5_sha1_context::sha1, and sha1_algorithm.

◆ free_tls_session()

static void free_tls_session ( struct refcnt refcnt)
static

Free TLS session.

Parameters
refcntReference counter

Definition at line 352 of file tls.c.

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

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

Referenced by tls_session().

◆ free_tls()

static void free_tls ( struct refcnt refcnt)
static

Free TLS connection.

Parameters
refcntReference counter

Definition at line 376 of file tls.c.

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

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

Referenced by add_tls().

◆ tls_close()

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

Finish with TLS connection.

Parameters
tlsTLS connection
rcStatus code

Definition at line 415 of file tls.c.

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

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

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

◆ tls_generate_random()

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

Generate random data.

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

Definition at line 453 of file tls.c.

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

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

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

◆ tls_hmac_update_va()

static void tls_hmac_update_va ( struct digest_algorithm digest,
void *  ctx,
va_list  args 
)
static

Update HMAC with a list of ( data, len ) pairs.

Parameters
digestHash function to use
ctxHMAC context
args( data, len ) pairs of data, terminated by NULL

Definition at line 476 of file tls.c.

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

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

Referenced by tls_p_hash_va().

◆ tls_p_hash_va()

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

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

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

Definition at line 498 of file tls.c.

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

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

Referenced by tls_prf().

◆ tls_prf()

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

Generate secure pseudo-random data.

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

Definition at line 560 of file tls.c.

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

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

◆ tls_generate_master_secret()

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

Generate master secret.

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

The client and server random values must already be known.

Definition at line 636 of file tls.c.

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

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

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

◆ tls_generate_keys()

static int tls_generate_keys ( struct tls_connection tls)
static

Generate key material.

Parameters
tlsTLS connection

The master secret must already be known.

Definition at line 664 of file tls.c.

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

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

Referenced by tls_new_server_hello(), and tls_send_client_key_exchange().

◆ tls_clear_handshake()

static void tls_clear_handshake ( struct tls_connection tls)
static

Clear handshake digest algorithm.

Parameters
tlsTLS connection

Definition at line 749 of file tls.c.

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

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

Referenced by add_tls(), and tls_select_handshake().

◆ tls_select_handshake()

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

Select handshake digest algorithm.

Parameters
tlsTLS connection
digestHandshake digest algorithm
Return values
rcReturn status code

Definition at line 766 of file tls.c.

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

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

Referenced by tls_select_cipher().

◆ tls_add_handshake()

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

Add handshake record to verification hash.

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

Definition at line 790 of file tls.c.

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

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

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

◆ tls_verify_handshake()

static void tls_verify_handshake ( struct tls_connection tls,
void *  out 
)
static

Calculate handshake verification hash.

Parameters
tlsTLS connection
outOutput buffer

Calculates the digest over all handshake messages seen so far.

Definition at line 806 of file tls.c.

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

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

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

◆ tls_find_cipher_suite()

static struct tls_cipher_suite* tls_find_cipher_suite ( unsigned int  cipher_suite)
static

Identify cipher suite.

Parameters
cipher_suiteCipher suite specification
Return values
suiteCipher suite, or NULL

Definition at line 839 of file tls.c.

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

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

Referenced by tls_select_cipher().

◆ tls_clear_cipher() [2/2]

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

Clear cipher suite.

Parameters
cipherspecTLS cipher specification

Definition at line 856 of file tls.c.

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

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

◆ tls_set_cipher()

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

Set cipher suite.

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

Definition at line 876 of file tls.c.

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

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

Referenced by tls_select_cipher().

◆ tls_select_cipher()

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

Select next cipher suite.

Parameters
tlsTLS connection
cipher_suiteCipher suite specification
Return values
rcReturn status code

Definition at line 918 of file tls.c.

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

References tls_cipher_suite::cipher, DBGC, tls_cipher_suite::digest, digest, ENOTSUP_CIPHER, tls_cipher_suite::exchange, tls_cipher_suite::handshake, tls_cipher_suite::key_len, md5_sha1_algorithm, digest_algorithm::name, cipher_algorithm::name, pubkey_algorithm::name, tls_key_exchange_algorithm::name, ntohs, tls_cipher_suite::pubkey, rc, tls_connection::rx_cipherspec_pending, tls_find_cipher_suite(), tls_select_handshake(), tls_set_cipher(), tls_version(), TLS_VERSION_TLS_1_2, and tls_connection::tx_cipherspec_pending.

Referenced by tls_new_server_hello().

◆ tls_change_cipher()

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

Activate next cipher suite.

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

Definition at line 962 of file tls.c.

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

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

Referenced by tls_new_change_cipher(), and tls_tx_step().

◆ tls_signature_hash_algorithm()

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

Find TLS signature and hash algorithm.

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

Definition at line 996 of file tls.c.

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

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

Referenced by tls_send_certificate_verify().

◆ tls_signature_hash_pubkey()

static struct pubkey_algorithm* tls_signature_hash_pubkey ( struct tls_signature_hash_id  code)
static

Find TLS signature algorithm.

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

Definition at line 1018 of file tls.c.

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

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

Referenced by tls_verify_dh_params().

◆ tls_signature_hash_digest()

static struct digest_algorithm* tls_signature_hash_digest ( struct tls_signature_hash_id  code)
static

Find TLS hash algorithm.

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

Definition at line 1037 of file tls.c.

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

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

Referenced by tls_verify_dh_params().

◆ tls_find_named_curve()

static struct tls_named_curve* tls_find_named_curve ( unsigned int  named_curve)
static

Identify named curve.

Parameters
named_curveNamed curve specification
Return values
curveNamed curve, or NULL

Definition at line 1066 of file tls.c.

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

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

Referenced by tls_send_client_key_exchange_ecdhe().

◆ tls_tx_resume()

static void tls_tx_resume ( struct tls_connection tls)
static

Resume TX state machine.

Parameters
tlsTLS connection

Definition at line 1090 of file tls.c.

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

References tls_connection::process, and process_add().

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

◆ tls_restart()

static void tls_restart ( struct tls_connection tls)
static

Restart negotiation.

Parameters
tlsTLS connection

Definition at line 1111 of file tls.c.

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

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

Referenced by add_tls(), and tls_new_hello_request().

◆ tls_send_handshake()

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

Transmit Handshake record.

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

Definition at line 1134 of file tls.c.

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

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

Referenced by tls_send_certificate(), tls_send_certificate_verify(), tls_send_client_hello(), tls_send_client_key_exchange_dhe(), tls_send_client_key_exchange_ecdhe(), tls_send_client_key_exchange_pubkey(), and tls_send_finished().

◆ tls_client_hello()

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

Digest or transmit Client Hello record.

Parameters
tlsTLS connection
actionAction to take on Client Hello record
Return values
rcReturn status code

Definition at line 1151 of file tls.c.

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

References __attribute__, tls_verify_data::client, tls_connection::client_random, code, tls_cipher_suite::code, tls_signature_hash_algorithm::code, cpu_to_le32, tls_named_curve::curve, data, for_each_table_entry, hello, htonl, htons, len, tls_session::list, max, memcpy(), memset(), tls_session::name, random(), tls_connection::secure_renegotiation, session, tls_connection::session, tls_connection::session_id, tls_connection::session_id_len, strlen(), TLS_CIPHER_SUITES, TLS_CLIENT_HELLO, TLS_MAX_FRAGMENT_LENGTH, TLS_MAX_FRAGMENT_LENGTH_4096, TLS_NAMED_CURVE, TLS_NAMED_CURVES, TLS_NUM_CIPHER_SUITES, TLS_NUM_NAMED_CURVES, TLS_NUM_SIG_HASH_ALGORITHMS, TLS_RENEGOTIATION_INFO, TLS_SERVER_NAME, TLS_SERVER_NAME_HOST_NAME, TLS_SESSION_TICKET, TLS_SIG_HASH_ALGORITHMS, TLS_SIGNATURE_ALGORITHMS, TLS_VERSION_MAX, type, typeof(), tls_connection::verify, and version.

Referenced by tls_new_server_hello(), and tls_send_client_hello().

◆ tls_send_client_hello()

static int tls_send_client_hello ( struct tls_connection tls)
static

Transmit Client Hello record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1321 of file tls.c.

1321  {
1322 
1323  return tls_client_hello ( tls, tls_send_handshake );
1324 }
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1134
static int tls_client_hello(struct tls_connection *tls, int(*action)(struct tls_connection *tls, const void *data, size_t len))
Digest or transmit Client Hello record.
Definition: tls.c:1151

References tls_client_hello(), and tls_send_handshake().

Referenced by tls_tx_step().

◆ tls_send_certificate()

static int tls_send_certificate ( struct tls_connection tls)
static

Transmit Certificate record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1332 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_send_client_key_exchange_pubkey()

static int tls_send_client_key_exchange_pubkey ( struct tls_connection tls)
static

Transmit Client Key Exchange record using public key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1394 of file tls.c.

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

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

◆ tls_verify_dh_params()

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

Verify Diffie-Hellman parameter signature.

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

Definition at line 1459 of file tls.c.

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

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

Referenced by tls_send_client_key_exchange_dhe(), and tls_send_client_key_exchange_ecdhe().

◆ tls_send_client_key_exchange_dhe()

static int tls_send_client_key_exchange_dhe ( struct tls_connection tls)
static

Transmit Client Key Exchange record using DHE key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1547 of file tls.c.

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

References __attribute__, tls_connection::client_random, cpu_to_le32, data, DBGC, DBGC_HDA, dhe_key(), EINVAL_KEY_EXCHANGE, ENOMEM, free, htonl, htons, len, malloc(), ntohs, tls_client_random::random, rc, tls_connection::server_key, tls_connection::server_key_len, strerror(), TLS_CLIENT_KEY_EXCHANGE, tls_generate_master_secret(), tls_generate_random(), tls_send_handshake(), tls_verify_dh_params(), and typeof().

◆ tls_send_client_key_exchange_ecdhe()

static int tls_send_client_key_exchange_ecdhe ( struct tls_connection tls)
static

Transmit Client Key Exchange record using ECDHE key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1672 of file tls.c.

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

References __attribute__, cpu_to_le32, tls_named_curve::curve, DBGC, DBGC_HDA, EINVAL_KEY_EXCHANGE, ENOTSUP_CURVE, htonl, elliptic_curve::keysize, len, elliptic_curve::name, ntohs, NULL, rc, tls_connection::server_key, tls_connection::server_key_len, strerror(), TLS_CLIENT_KEY_EXCHANGE, tls_find_named_curve(), tls_generate_master_secret(), tls_generate_random(), TLS_NAMED_CURVE_TYPE, tls_send_handshake(), and tls_verify_dh_params().

◆ tls_send_client_key_exchange()

static int tls_send_client_key_exchange ( struct tls_connection tls)
static

Transmit Client Key Exchange record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1785 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_send_certificate_verify()

static int tls_send_certificate_verify ( struct tls_connection tls)
static

Transmit Certificate Verify record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1813 of file tls.c.

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

References __attribute__, tls_connection::certs, tls_signature_hash_algorithm::code, cpu_to_le32, ctx, pubkey_algorithm::ctxsize, DBGC, digest, digest_algorithm::digestsize, ENOTSUP_SIG_HASH, tls_connection::handshake_digest, htonl, htons, key, tls_connection::key, len, max_len, memcpy(), digest_algorithm::name, pubkey_algorithm::name, NULL, privkey_cursor(), tls_signature_hash_algorithm::pubkey, asn1_algorithm::pubkey, rc, signature, x509_certificate::signature_algorithm, signature_len, strerror(), TLS_CERTIFICATE_VERIFY, tls_send_handshake(), tls_signature_hash_algorithm(), tls_verify_handshake(), tls_version(), TLS_VERSION_TLS_1_2, unused, and x509_first().

Referenced by tls_tx_step().

◆ tls_send_change_cipher()

static int tls_send_change_cipher ( struct tls_connection tls)
static

Transmit Change Cipher record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1903 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_send_finished()

static int tls_send_finished ( struct tls_connection tls)
static

Transmit Finished record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1920 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_new_change_cipher()

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

Receive new Change Cipher record.

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

Definition at line 1961 of file tls.c.

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

References __attribute__, io_buffer::data, DBGC, DBGC_HD, EINVAL_CHANGE_CIPHER, iob_len(), iob_pull, len, rc, tls_connection::rx_cipherspec, tls_connection::rx_cipherspec_pending, tls_connection::rx_seq, spec, strerror(), tls_change_cipher(), and TLS_CHANGE_CIPHER_SPEC.

Referenced by tls_new_record().

◆ tls_new_alert()

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

Receive new Alert record.

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

Definition at line 1997 of file tls.c.

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

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

Referenced by tls_new_record().

◆ tls_new_hello_request()

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

Receive new Hello Request handshake record.

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

Definition at line 2039 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_new_server_hello()

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

Receive new Server Hello handshake record.

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

Definition at line 2070 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_new_session_ticket()

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

Receive New Session Ticket handshake record.

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

Definition at line 2255 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_parse_chain()

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

Parse certificate chain.

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

Definition at line 2306 of file tls.c.

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

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

Referenced by tls_new_certificate().

◆ tls_new_certificate()

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

Receive new Certificate handshake record.

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

Definition at line 2384 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_new_server_key_exchange()

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

Receive new Server Key Exchange handshake record.

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

Definition at line 2424 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_new_certificate_request()

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

Receive new Certificate Request handshake record.

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

Definition at line 2455 of file tls.c.

2457  {
2458  struct x509_certificate *cert;
2459  int rc;
2460 
2461  /* We can only send a single certificate, so there is no point
2462  * in parsing the Certificate Request.
2463  */
2464 
2465  /* Free any existing client certificate chain */
2466  x509_chain_put ( tls->certs );
2467  tls->certs = NULL;
2468 
2469  /* Determine client certificate to be sent */
2470  cert = certstore_find_key ( tls->key );
2471  if ( ! cert ) {
2472  DBGC ( tls, "TLS %p could not find certificate corresponding "
2473  "to private key\n", tls );
2474  rc = -EPERM_CLIENT_CERT;
2475  goto err_find;
2476  }
2477  x509_get ( cert );
2478  DBGC ( tls, "TLS %p selected client certificate %s\n",
2479  tls, x509_name ( cert ) );
2480 
2481  /* Create client certificate chain */
2482  tls->certs = x509_alloc_chain();
2483  if ( ! tls->certs ) {
2484  rc = -ENOMEM;
2485  goto err_alloc;
2486  }
2487 
2488  /* Append client certificate to chain */
2489  if ( ( rc = x509_append ( tls->certs, cert ) ) != 0 )
2490  goto err_append;
2491 
2492  /* Append any relevant issuer certificates */
2493  if ( ( rc = x509_auto_append ( tls->certs, &certstore ) ) != 0 )
2494  goto err_auto_append;
2495 
2496  /* Drop local reference to client certificate */
2497