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

Transport Layer Security Protocol. More...

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

Go to the source code of this file.

Data Structures

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

Macros

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

Functions

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

Variables

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

Detailed Description

Transport Layer Security Protocol.

Definition in file tls.c.

Macro Definition Documentation

◆ EINVAL_CHANGE_CIPHER

#define EINVAL_CHANGE_CIPHER   __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER )

Definition at line 58 of file tls.c.

◆ EINFO_EINVAL_CHANGE_CIPHER

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

Definition at line 59 of file tls.c.

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

Definition at line 62 of file tls.c.

◆ EINFO_EINVAL_ALERT

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

Definition at line 63 of file tls.c.

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

Definition at line 66 of file tls.c.

◆ EINFO_EINVAL_HELLO

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

Definition at line 67 of file tls.c.

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

Definition at line 70 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATE

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

Definition at line 71 of file tls.c.

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

Definition at line 74 of file tls.c.

◆ EINFO_EINVAL_CERTIFICATES

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

Definition at line 75 of file tls.c.

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

Definition at line 78 of file tls.c.

◆ EINFO_EINVAL_HELLO_DONE

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

Definition at line 79 of file tls.c.

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

Definition at line 82 of file tls.c.

◆ EINFO_EINVAL_FINISHED

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

Definition at line 83 of file tls.c.

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

Definition at line 86 of file tls.c.

◆ EINFO_EINVAL_HANDSHAKE

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

Definition at line 87 of file tls.c.

◆ EINVAL_IV

#define EINVAL_IV   __einfo_error ( EINFO_EINVAL_IV )

Definition at line 90 of file tls.c.

◆ EINFO_EINVAL_IV

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

Definition at line 91 of file tls.c.

◆ EINVAL_PADDING

#define EINVAL_PADDING   __einfo_error ( EINFO_EINVAL_PADDING )

Definition at line 94 of file tls.c.

◆ EINFO_EINVAL_PADDING

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

Definition at line 95 of file tls.c.

◆ EINVAL_RX_STATE

#define EINVAL_RX_STATE   __einfo_error ( EINFO_EINVAL_RX_STATE )

Definition at line 98 of file tls.c.

◆ EINFO_EINVAL_RX_STATE

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

Definition at line 99 of file tls.c.

◆ EINVAL_MAC

#define EINVAL_MAC   __einfo_error ( EINFO_EINVAL_MAC )

Definition at line 102 of file tls.c.

◆ EINFO_EINVAL_MAC

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

Definition at line 103 of file tls.c.

◆ EINVAL_TICKET

#define EINVAL_TICKET   __einfo_error ( EINFO_EINVAL_TICKET )

Definition at line 106 of file tls.c.

◆ EINFO_EINVAL_TICKET

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

Definition at line 107 of file tls.c.

◆ EINVAL_KEY_EXCHANGE

#define EINVAL_KEY_EXCHANGE   __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE )

Definition at line 110 of file tls.c.

◆ EINFO_EINVAL_KEY_EXCHANGE

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

Definition at line 111 of file tls.c.

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

Definition at line 114 of file tls.c.

◆ EINFO_EIO_ALERT

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

Definition at line 115 of file tls.c.

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

Definition at line 118 of file tls.c.

◆ EINFO_ENOMEM_CONTEXT

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

Definition at line 119 of file tls.c.

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

Definition at line 122 of file tls.c.

◆ EINFO_ENOMEM_CERTIFICATE

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

Definition at line 123 of file tls.c.

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

Definition at line 126 of file tls.c.

◆ EINFO_ENOMEM_CHAIN

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

Definition at line 127 of file tls.c.

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

Definition at line 130 of file tls.c.

◆ EINFO_ENOMEM_TX_PLAINTEXT

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

Definition at line 131 of file tls.c.

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

Definition at line 134 of file tls.c.

◆ EINFO_ENOMEM_TX_CIPHERTEXT

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

Definition at line 135 of file tls.c.

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

Definition at line 138 of file tls.c.

◆ EINFO_ENOMEM_RX_DATA

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

Definition at line 139 of file tls.c.

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

Definition at line 142 of file tls.c.

◆ EINFO_ENOMEM_RX_CONCAT

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

Definition at line 143 of file tls.c.

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

Definition at line 146 of file tls.c.

◆ EINFO_ENOTSUP_CIPHER

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

Definition at line 147 of file tls.c.

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

Definition at line 150 of file tls.c.

◆ EINFO_ENOTSUP_NULL

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

Definition at line 151 of file tls.c.

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

Definition at line 154 of file tls.c.

◆ EINFO_ENOTSUP_SIG_HASH

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

Definition at line 155 of file tls.c.

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

Definition at line 158 of file tls.c.

◆ EINFO_ENOTSUP_VERSION

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

Definition at line 159 of file tls.c.

◆ ENOTSUP_CURVE

#define ENOTSUP_CURVE   __einfo_error ( EINFO_ENOTSUP_CURVE )

Definition at line 162 of file tls.c.

◆ EINFO_ENOTSUP_CURVE

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

Definition at line 163 of file tls.c.

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

Definition at line 166 of file tls.c.

◆ EINFO_EPERM_ALERT

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

Definition at line 167 of file tls.c.

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

Definition at line 170 of file tls.c.

◆ EINFO_EPERM_VERIFY

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

Definition at line 171 of file tls.c.

◆ EPERM_CLIENT_CERT

#define EPERM_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )

Definition at line 174 of file tls.c.

◆ EINFO_EPERM_CLIENT_CERT

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

Definition at line 175 of file tls.c.

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

Definition at line 178 of file tls.c.

◆ EINFO_EPERM_RENEG_INSECURE

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

Definition at line 179 of file tls.c.

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

Definition at line 182 of file tls.c.

◆ EINFO_EPERM_RENEG_VERIFY

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

Definition at line 183 of file tls.c.

◆ EPERM_KEY_EXCHANGE

#define EPERM_KEY_EXCHANGE   __einfo_error ( EINFO_EPERM_KEY_EXCHANGE )

Definition at line 186 of file tls.c.

◆ EINFO_EPERM_KEY_EXCHANGE

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

Definition at line 187 of file tls.c.

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

Definition at line 190 of file tls.c.

◆ EINFO_EPROTO_VERSION

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

Definition at line 191 of file tls.c.

◆ tls_prf_label

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

Generate secure pseudo-random data.

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

Definition at line 617 of file tls.c.

◆ TLS_NUM_CIPHER_SUITES

#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )

Number of supported cipher suites.

Definition at line 831 of file tls.c.

◆ TLS_NUM_SIG_HASH_ALGORITHMS

#define TLS_NUM_SIG_HASH_ALGORITHMS   table_num_entries ( TLS_SIG_HASH_ALGORITHMS )

Number of supported signature and hash algorithms.

Definition at line 977 of file tls.c.

◆ TLS_NUM_NAMED_CURVES

#define TLS_NUM_NAMED_CURVES   table_num_entries ( TLS_NAMED_CURVES )

Number of supported named curves.

Definition at line 1049 of file tls.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ LIST_HEAD()

static LIST_HEAD ( tls_sessions  )
static

List of TLS session.

◆ tls_tx_resume_all()

static void tls_tx_resume_all ( struct tls_session session)
static

Resume TX state machine for all connections within a session.

Parameters
sessionTLS session

Definition at line 1091 of file tls.c.

1091  {
1092  struct tls_connection *tls;
1093 
1094  list_for_each_entry ( tls, &session->conn, list )
1095  tls_tx_resume ( tls );
1096 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:1082
struct tls_session * session
Session.
Definition: tls.h:428
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct list_head list
List of connections within the same session.
Definition: tls.h:430
A TLS connection.
Definition: tls.h:423
struct list_head conn
List of connections.
Definition: tls.h:355

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

Referenced by tls_close(), and tls_new_finished().

◆ tls_send_plaintext()

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

Send plaintext record.

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

Definition at line 2939 of file tls.c.

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

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

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

◆ tls_clear_cipher() [1/2]

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

◆ tls_uint24()

static unsigned long tls_uint24 ( const tls24_t field24)
inlinestatic

Extract 24-bit field value.

Parameters
field2424-bit field
Return values
valueField value

Definition at line 231 of file tls.c.

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

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

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

◆ tls_set_uint24()

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

Set 24-bit field value.

Parameters
field2424-bit field
valueField value

Definition at line 242 of file tls.c.

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

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

Referenced by tls_send_certificate().

◆ tls_ready()

static int tls_ready ( struct tls_connection tls)
static

Determine if TLS connection is ready for application data.

Parameters
tlsTLS connection
Return values
is_readyTLS connection is ready

Definition at line 254 of file tls.c.

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

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

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

◆ tls_version()

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

Check for TLS version.

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

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

Definition at line 271 of file tls.c.

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

References TLS_VERSION_MIN, tls_connection::version, and version.

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

◆ md5_sha1_init()

static void md5_sha1_init ( void *  ctx)
static

Initialise MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context

Definition at line 288 of file tls.c.

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

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

◆ md5_sha1_update()

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

Accumulate data with MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context
dataData
lenLength of data

Definition at line 302 of file tls.c.

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

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

◆ md5_sha1_final()

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

Generate MD5+SHA1 digest.

Parameters
ctxMD5+SHA1 context
outOutput buffer

Definition at line 315 of file tls.c.

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

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

◆ free_tls_session()

static void free_tls_session ( struct refcnt refcnt)
static

Free TLS session.

Parameters
refcntReference counter

Definition at line 353 of file tls.c.

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

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

Referenced by tls_session().

◆ free_tls()

static void free_tls ( struct refcnt refcnt)
static

Free TLS connection.

Parameters
refcntReference counter

Definition at line 377 of file tls.c.

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

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

Referenced by add_tls().

◆ tls_close()

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

Finish with TLS connection.

Parameters
tlsTLS connection
rcStatus code

Definition at line 416 of file tls.c.

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

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

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

◆ tls_generate_random()

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

Generate random data.

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

Definition at line 454 of file tls.c.

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

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

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

◆ tls_hmac_update_va()

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

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

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

Definition at line 477 of file tls.c.

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

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

Referenced by tls_p_hash_va().

◆ tls_p_hash_va()

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

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

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

Definition at line 499 of file tls.c.

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

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

Referenced by tls_prf().

◆ tls_prf()

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

Generate secure pseudo-random data.

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

Definition at line 561 of file tls.c.

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

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

◆ tls_generate_master_secret()

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

Generate master secret.

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

The client and server random values must already be known.

Definition at line 637 of file tls.c.

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

References tls_connection::client, DBGC, DBGC_HD, tls_connection::master_secret, tls_client::random, tls_server::random, tls_connection::server, and tls_prf_label.

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

◆ tls_generate_keys()

static int tls_generate_keys ( struct tls_connection tls)
static

Generate key material.

Parameters
tlsTLS connection

The master secret must already be known.

Definition at line 665 of file tls.c.

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

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

Referenced by tls_new_server_hello(), and tls_send_client_key_exchange().

◆ tls_clear_handshake()

static void tls_clear_handshake ( struct tls_connection tls)
static

Clear handshake digest algorithm.

Parameters
tlsTLS connection

Definition at line 750 of file tls.c.

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

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

Referenced by add_tls(), and tls_select_handshake().

◆ tls_select_handshake()

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

Select handshake digest algorithm.

Parameters
tlsTLS connection
digestHandshake digest algorithm
Return values
rcReturn status code

Definition at line 767 of file tls.c.

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

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

Referenced by tls_select_cipher().

◆ tls_add_handshake()

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

Add handshake record to verification hash.

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

Definition at line 791 of file tls.c.

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

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

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

◆ tls_verify_handshake()

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

Calculate handshake verification hash.

Parameters
tlsTLS connection
outOutput buffer

Calculates the digest over all handshake messages seen so far.

Definition at line 807 of file tls.c.

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

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

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

◆ tls_find_cipher_suite()

static struct tls_cipher_suite* tls_find_cipher_suite ( unsigned int  cipher_suite)
static

Identify cipher suite.

Parameters
cipher_suiteCipher suite specification
Return values
suiteCipher suite, or NULL

Definition at line 840 of file tls.c.

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

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

Referenced by tls_select_cipher().

◆ tls_clear_cipher() [2/2]

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

Clear cipher suite.

Parameters
cipherspecTLS cipher specification

Definition at line 857 of file tls.c.

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

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

◆ tls_set_cipher()

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

Set cipher suite.

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

Definition at line 873 of file tls.c.

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

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

Referenced by tls_select_cipher().

◆ tls_select_cipher()

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

Select next cipher suite.

Parameters
tlsTLS connection
cipher_suiteCipher suite specification
Return values
rcReturn status code

Definition at line 912 of file tls.c.

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

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

Referenced by tls_new_server_hello().

◆ tls_change_cipher()

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

Activate next cipher suite.

Parameters
tlsTLS connection
pairCipher specification pair
Return values
rcReturn status code

Definition at line 955 of file tls.c.

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

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

Referenced by tls_new_change_cipher(), and tls_tx_step().

◆ tls_signature_hash_algorithm()

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

Find TLS signature and hash algorithm.

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

Definition at line 988 of file tls.c.

989  {
990  struct tls_signature_hash_algorithm *sig_hash;
991 
992  /* Identify signature and hash algorithm */
994  if ( ( sig_hash->pubkey == pubkey ) &&
995  ( sig_hash->digest == digest ) ) {
996  return sig_hash;
997  }
998  }
999 
1000  return NULL;
1001 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:279
A TLS signature algorithm.
Definition: tls.h:277
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:291
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:281
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_send_certificate_verify().

◆ tls_signature_hash_pubkey()

static struct pubkey_algorithm* tls_signature_hash_pubkey ( struct tls_signature_hash_id  code)
static

Find TLS signature algorithm.

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

Definition at line 1010 of file tls.c.

1010  {
1011  struct tls_signature_hash_algorithm *sig_hash;
1012 
1013  /* Identify signature and hash algorithm */
1015  if ( sig_hash->code.signature == code.signature )
1016  return sig_hash->pubkey;
1017  }
1018 
1019  return NULL;
1020 }
static unsigned int code
Response code.
Definition: hyperv.h:26
A TLS signature algorithm.
Definition: tls.h:277
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
uint8_t signature
Signature algorithm.
Definition: tls.h:273
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:291
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:283
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:281
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_verify_dh_params().

◆ tls_signature_hash_digest()

static struct digest_algorithm* tls_signature_hash_digest ( struct tls_signature_hash_id  code)
static

Find TLS hash algorithm.

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

Definition at line 1029 of file tls.c.

1029  {
1030  struct tls_signature_hash_algorithm *sig_hash;
1031 
1032  /* Identify signature and hash algorithm */
1034  if ( sig_hash->code.hash == code.hash )
1035  return sig_hash->digest;
1036  }
1037 
1038  return NULL;
1039 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:279
static unsigned int code
Response code.
Definition: hyperv.h:26
A TLS signature algorithm.
Definition: tls.h:277
uint8_t hash
Hash algorithm.
Definition: tls.h:271
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:291
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:283
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_verify_dh_params().

◆ tls_find_named_curve()

static struct tls_named_curve* tls_find_named_curve ( unsigned int  named_curve)
static

Identify named curve.

Parameters
named_curveNamed curve specification
Return values
curveNamed curve, or NULL

Definition at line 1058 of file tls.c.

1058  {
1059  struct tls_named_curve *curve;
1060 
1061  /* Identify named curve */
1063  if ( curve->code == named_curve )
1064  return curve;
1065  }
1066 
1067  return NULL;
1068 }
#define TLS_NAMED_CURVES
TLS named curve table.
Definition: tls.h:239
struct elliptic_curve * curve
Elliptic curve.
Definition: tls.h:229
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
A TLS named curve.
Definition: tls.h:227
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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

Referenced by tls_send_client_key_exchange_ecdhe().

◆ tls_tx_resume()

static void tls_tx_resume ( struct tls_connection tls)
static

Resume TX state machine.

Parameters
tlsTLS connection

Definition at line 1082 of file tls.c.

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

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

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

◆ tls_restart()

static void tls_restart ( struct tls_connection tls)
static

Restart negotiation.

Parameters
tlsTLS connection

Definition at line 1103 of file tls.c.

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

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

Referenced by add_tls(), and tls_new_hello_request().

◆ tls_send_handshake()

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

Transmit Handshake record.

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

Definition at line 1126 of file tls.c.

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

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

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

◆ tls_client_hello()

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

Digest or transmit Client Hello record.

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

Definition at line 1143 of file tls.c.

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

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

Referenced by tls_new_server_hello(), and tls_send_client_hello().

◆ tls_send_client_hello()

static int tls_send_client_hello ( struct tls_connection tls)
static

Transmit Client Hello record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1313 of file tls.c.

1313  {
1314 
1315  return tls_client_hello ( tls, tls_send_handshake );
1316 }
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:1126
static int tls_client_hello(struct tls_connection *tls, int(*action)(struct tls_connection *tls, const void *data, size_t len))
Digest or transmit Client Hello record.
Definition: tls.c:1143

References tls_client_hello(), and tls_send_handshake().

Referenced by tls_tx_step().

◆ tls_send_certificate()

static int tls_send_certificate ( struct tls_connection tls)
static

Transmit Certificate record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1324 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_send_client_key_exchange_pubkey()

static int tls_send_client_key_exchange_pubkey ( struct tls_connection tls)
static

Transmit Client Key Exchange record using public key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1386 of file tls.c.

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

References __attribute__, tls_tx::cipherspec, cpu_to_le32, DBGC, htonl, htons, tls_server::key, len, pubkey_algorithm::max_len, memset(), tls_cipherspec_pair::pending, tls_cipher_suite::pubkey, pubkey_encrypt(), pubkey_max_len(), random(), rc, tls_connection::server, strerror(), tls_cipherspec::suite, TLS_CLIENT_KEY_EXCHANGE, tls_generate_master_secret(), tls_generate_random(), tls_send_handshake(), TLS_VERSION_MAX, tls_connection::tx, unused, and version.

◆ tls_verify_dh_params()

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

Verify Diffie-Hellman parameter signature.

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

Definition at line 1451 of file tls.c.

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

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

Referenced by tls_send_client_key_exchange_dhe(), and tls_send_client_key_exchange_ecdhe().

◆ tls_send_client_key_exchange_dhe()

static int tls_send_client_key_exchange_dhe ( struct tls_connection tls)
static

Transmit Client Key Exchange record using DHE key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1540 of file tls.c.

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

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

◆ tls_send_client_key_exchange_ecdhe()

static int tls_send_client_key_exchange_ecdhe ( struct tls_connection tls)
static

Transmit Client Key Exchange record using ECDHE key exchange.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1665 of file tls.c.

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

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

◆ tls_send_client_key_exchange()

static int tls_send_client_key_exchange ( struct tls_connection tls)
static

Transmit Client Key Exchange record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1795 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_send_certificate_verify()

static int tls_send_certificate_verify ( struct tls_connection tls)
static

Transmit Certificate Verify record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1823 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_send_change_cipher()

static int tls_send_change_cipher ( struct tls_connection tls)
static

Transmit Change Cipher record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1903 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_send_finished()

static int tls_send_finished ( struct tls_connection tls)
static

Transmit Finished record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1920 of file tls.c.

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

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

Referenced by tls_tx_step().

◆ tls_new_change_cipher()

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

Receive new Change Cipher record.

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

Definition at line 1961 of file tls.c.

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

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

Referenced by tls_new_record().

◆ tls_new_alert()

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

Receive new Alert record.

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

Definition at line 1996 of file tls.c.

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

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

Referenced by tls_new_record().

◆ tls_new_hello_request()

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

Receive new Hello Request handshake record.

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

Definition at line 2038 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_new_server_hello()

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

Receive new Server Hello handshake record.

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

Definition at line 2069 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_new_session_ticket()

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

Receive New Session Ticket handshake record.

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

Definition at line 2254 of file tls.c.

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

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

Referenced by tls_new_handshake().

◆ tls_parse_chain()

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

Parse certificate chain.

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

Definition at line 2305 of file tls.c.

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

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

Referenced by tls_new_certificate().

◆ tls_new_certificate()

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