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/rbg.h>
#include <ipxe/validator.h>
#include <ipxe/job.h>
#include <ipxe/tls.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_STREAM   __einfo_error ( EINFO_EINVAL_STREAM )
 
#define EINFO_EINVAL_STREAM
 
#define EINVAL_BLOCK   __einfo_error ( EINFO_EINVAL_BLOCK )
 
#define EINFO_EINVAL_BLOCK
 
#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 EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )
 
#define EINFO_EIO_ALERT
 
#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )
 
#define EINFO_ENOMEM_CONTEXT
 
#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )
 
#define EINFO_ENOMEM_CERTIFICATE
 
#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )
 
#define EINFO_ENOMEM_CHAIN
 
#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )
 
#define EINFO_ENOMEM_TX_PLAINTEXT
 
#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )
 
#define EINFO_ENOMEM_TX_CIPHERTEXT
 
#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )
 
#define EINFO_ENOMEM_RX_DATA
 
#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )
 
#define EINFO_ENOMEM_RX_CONCAT
 
#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )
 
#define EINFO_ENOTSUP_CIPHER
 
#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )
 
#define EINFO_ENOTSUP_NULL
 
#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )
 
#define EINFO_ENOTSUP_SIG_HASH
 
#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )
 
#define EINFO_ENOTSUP_VERSION
 
#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )
 
#define EINFO_EPERM_ALERT
 
#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )
 
#define EINFO_EPERM_VERIFY
 
#define EPERM_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )
 
#define EINFO_EPERM_CLIENT_CERT
 
#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )
 
#define EINFO_EPERM_RENEG_INSECURE
 
#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )
 
#define EINFO_EPERM_RENEG_VERIFY
 
#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )
 
#define EINFO_EPROTO_VERSION
 
#define tls_prf_label(tls, secret, secret_len, out, out_len, label, ...)
 Generate secure pseudo-random data. More...
 
#define TLS_NUM_CIPHER_SUITES   table_num_entries ( TLS_CIPHER_SUITES )
 Number of supported cipher suites. More...
 
#define TLS_NUM_SIG_HASH_ALGORITHMS   table_num_entries ( TLS_SIG_HASH_ALGORITHMS )
 Number of supported signature and hash algorithms. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
static LIST_HEAD (tls_sessions)
 List of TLS session. More...
 
static void tls_tx_resume_all (struct tls_session *session)
 Resume TX state machine for all connections within a session. More...
 
static int tls_send_plaintext (struct tls_connection *tls, unsigned int type, const void *data, size_t len)
 Send plaintext record. More...
 
static void tls_clear_cipher (struct tls_connection *tls, struct tls_cipherspec *cipherspec)
 
static unsigned long tls_uint24 (const tls24_t *field24)
 Extract 24-bit field value. More...
 
static void tls_set_uint24 (tls24_t *field24, unsigned long value)
 Set 24-bit field value. More...
 
static int tls_ready (struct tls_connection *tls)
 Determine if TLS connection is ready for application data. More...
 
static 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 *digest_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, 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, 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)
 Generate master secret. More...
 
static int tls_generate_keys (struct tls_connection *tls)
 Generate key material. More...
 
static struct tls_cipher_suitetls_find_cipher_suite (unsigned int cipher_suite)
 Identify cipher suite. More...
 
static void tls_clear_cipher (struct tls_connection *tls __unused, struct tls_cipherspec *cipherspec)
 Clear cipher suite. More...
 
static int tls_set_cipher (struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
 Set cipher suite. More...
 
static int tls_select_cipher (struct tls_connection *tls, unsigned int cipher_suite)
 Select next cipher suite. More...
 
static int tls_change_cipher (struct tls_connection *tls, struct tls_cipherspec *pending, struct tls_cipherspec *active)
 Activate next cipher suite. More...
 
static struct tls_signature_hash_algorithmtls_signature_hash_algorithm (struct pubkey_algorithm *pubkey, struct digest_algorithm *digest)
 Find TLS signature and hash algorithm. More...
 
static void 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 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, void *data, size_t len)
 Transmit Handshake 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 (struct tls_connection *tls)
 Transmit Client Key Exchange record. More...
 
static int tls_send_certificate_verify (struct tls_connection *tls)
 Transmit Certificate Verify record. More...
 
static int tls_send_change_cipher (struct tls_connection *tls)
 Transmit Change Cipher record. More...
 
static int tls_send_finished (struct tls_connection *tls)
 Transmit Finished record. More...
 
static int tls_new_change_cipher (struct tls_connection *tls, const void *data, size_t len)
 Receive new Change Cipher record. More...
 
static int tls_new_alert (struct tls_connection *tls, const void *data, size_t len)
 Receive new Alert record. More...
 
static int tls_new_hello_request (struct tls_connection *tls, const void *data __unused, size_t len __unused)
 Receive new Hello Request handshake record. More...
 
static int tls_new_server_hello (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Hello handshake record. More...
 
static int tls_new_session_ticket (struct tls_connection *tls, const void *data, size_t len)
 Receive New Session Ticket handshake record. More...
 
static int tls_parse_chain (struct tls_connection *tls, const void *data, size_t len)
 Parse certificate chain. More...
 
static int tls_new_certificate (struct tls_connection *tls, const void *data, size_t len)
 Receive new Certificate handshake record. More...
 
static int tls_new_certificate_request (struct tls_connection *tls, const void *data __unused, size_t len __unused)
 Receive new Certificate Request handshake record. More...
 
static int tls_new_server_hello_done (struct tls_connection *tls, const void *data, size_t len)
 Receive new Server Hello Done handshake record. More...
 
static int tls_new_finished (struct tls_connection *tls, const void *data, size_t len)
 Receive new Finished handshake record. More...
 
static int tls_new_handshake (struct tls_connection *tls, const void *data, size_t len)
 Receive new Handshake record. More...
 
static int tls_new_record (struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
 Receive new record. More...
 
static void tls_hmac_init (struct tls_cipherspec *cipherspec, void *ctx, uint64_t seq, struct tls_header *tlshdr)
 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, uint64_t seq, struct tls_header *tlshdr, const void *data, size_t len, void *hmac)
 Calculate HMAC. More...
 
static void *__malloc tls_assemble_stream (struct tls_connection *tls, const void *data, size_t len, void *digest, size_t *plaintext_len)
 Allocate and assemble stream-ciphered record from data and MAC portions. More...
 
static void * tls_assemble_block (struct tls_connection *tls, const void *data, size_t len, void *digest, size_t *plaintext_len)
 Allocate and assemble block-ciphered record from data and MAC portions. More...
 
static int tls_split_stream (struct tls_connection *tls, struct list_head *rx_data, void **mac)
 Split stream-ciphered record into data and MAC portions. More...
 
static int tls_split_block (struct tls_connection *tls, struct list_head *rx_data, void **mac)
 Split block-ciphered record into data and MAC portions. 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 interface **next)
 
 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...
 
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 54 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 55 of file tls.c.

◆ EINVAL_ALERT

#define EINVAL_ALERT   __einfo_error ( EINFO_EINVAL_ALERT )

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

◆ EINVAL_HELLO

#define EINVAL_HELLO   __einfo_error ( EINFO_EINVAL_HELLO )

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

◆ EINVAL_CERTIFICATE

#define EINVAL_CERTIFICATE   __einfo_error ( EINFO_EINVAL_CERTIFICATE )

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

◆ EINVAL_CERTIFICATES

#define EINVAL_CERTIFICATES   __einfo_error ( EINFO_EINVAL_CERTIFICATES )

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

◆ EINVAL_HELLO_DONE

#define EINVAL_HELLO_DONE   __einfo_error ( EINFO_EINVAL_HELLO_DONE )

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

◆ EINVAL_FINISHED

#define EINVAL_FINISHED   __einfo_error ( EINFO_EINVAL_FINISHED )

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

◆ EINVAL_HANDSHAKE

#define EINVAL_HANDSHAKE   __einfo_error ( EINFO_EINVAL_HANDSHAKE )

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

◆ EINVAL_STREAM

#define EINVAL_STREAM   __einfo_error ( EINFO_EINVAL_STREAM )

Definition at line 86 of file tls.c.

◆ EINFO_EINVAL_STREAM

#define EINFO_EINVAL_STREAM
Value:
"Invalid stream-ciphered 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_BLOCK

#define EINVAL_BLOCK   __einfo_error ( EINFO_EINVAL_BLOCK )

Definition at line 90 of file tls.c.

◆ EINFO_EINVAL_BLOCK

#define EINFO_EINVAL_BLOCK
Value:
"Invalid block-ciphered 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 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" )
#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.

◆ EIO_ALERT

#define EIO_ALERT   __einfo_error ( EINFO_EIO_ALERT )

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

◆ ENOMEM_CONTEXT

#define ENOMEM_CONTEXT   __einfo_error ( EINFO_ENOMEM_CONTEXT )

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

◆ ENOMEM_CERTIFICATE

#define ENOMEM_CERTIFICATE   __einfo_error ( EINFO_ENOMEM_CERTIFICATE )

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

◆ ENOMEM_CHAIN

#define ENOMEM_CHAIN   __einfo_error ( EINFO_ENOMEM_CHAIN )

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

◆ ENOMEM_TX_PLAINTEXT

#define ENOMEM_TX_PLAINTEXT   __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT )

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

◆ ENOMEM_TX_CIPHERTEXT

#define ENOMEM_TX_CIPHERTEXT   __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT )

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

◆ ENOMEM_RX_DATA

#define ENOMEM_RX_DATA   __einfo_error ( EINFO_ENOMEM_RX_DATA )

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

◆ ENOMEM_RX_CONCAT

#define ENOMEM_RX_CONCAT   __einfo_error ( EINFO_ENOMEM_RX_CONCAT )

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

◆ ENOTSUP_CIPHER

#define ENOTSUP_CIPHER   __einfo_error ( EINFO_ENOTSUP_CIPHER )

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

◆ ENOTSUP_NULL

#define ENOTSUP_NULL   __einfo_error ( EINFO_ENOTSUP_NULL )

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

◆ ENOTSUP_SIG_HASH

#define ENOTSUP_SIG_HASH   __einfo_error ( EINFO_ENOTSUP_SIG_HASH )

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

◆ ENOTSUP_VERSION

#define ENOTSUP_VERSION   __einfo_error ( EINFO_ENOTSUP_VERSION )

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

◆ EPERM_ALERT

#define EPERM_ALERT   __einfo_error ( EINFO_EPERM_ALERT )

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

◆ EPERM_VERIFY

#define EPERM_VERIFY   __einfo_error ( EINFO_EPERM_VERIFY )

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

◆ EPERM_CLIENT_CERT

#define EPERM_CLIENT_CERT   __einfo_error ( EINFO_EPERM_CLIENT_CERT )

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

◆ EPERM_RENEG_INSECURE

#define EPERM_RENEG_INSECURE   __einfo_error ( EINFO_EPERM_RENEG_INSECURE )

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

◆ EPERM_RENEG_VERIFY

#define EPERM_RENEG_VERIFY   __einfo_error ( EINFO_EPERM_RENEG_VERIFY )

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

◆ EPROTO_VERSION

#define EPROTO_VERSION   __einfo_error ( EINFO_EPROTO_VERSION )

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

◆ tls_prf_label

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

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 587 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 723 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 870 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 957 of file tls.c.

957  {
958  struct tls_connection *tls;
959 
960  list_for_each_entry ( tls, &session->conn, list )
961  tls_tx_resume ( tls );
962 }
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:948
struct ntlm_data session
Session key.
Definition: ntlm.h:24
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct list_head list
List of connections within the same session.
Definition: tls.h:281
A TLS connection.
Definition: tls.h:274

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

Referenced by tls_close(), and tls_new_finished().

◆ tls_send_plaintext()

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

Send plaintext record.

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

Definition at line 2294 of file tls.c.

2295  {
2296  struct tls_header plaintext_tlshdr;
2297  struct tls_header *tlshdr;
2298  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec;
2299  struct cipher_algorithm *cipher = cipherspec->suite->cipher;
2300  void *plaintext = NULL;
2301  size_t plaintext_len;
2302  struct io_buffer *ciphertext = NULL;
2303  size_t ciphertext_len;
2304  size_t mac_len = cipherspec->suite->digest->digestsize;
2305  uint8_t mac[mac_len];
2306  int rc;
2307 
2308  /* Construct header */
2309  plaintext_tlshdr.type = type;
2310  plaintext_tlshdr.version = htons ( tls->version );
2311  plaintext_tlshdr.length = htons ( len );
2312 
2313  /* Calculate MAC */
2314  tls_hmac ( cipherspec, tls->tx_seq, &plaintext_tlshdr, data, len, mac );
2315 
2316  /* Allocate and assemble plaintext struct */
2317  if ( is_stream_cipher ( cipher ) ) {
2318  plaintext = tls_assemble_stream ( tls, data, len, mac,
2319  &plaintext_len );
2320  } else {
2321  plaintext = tls_assemble_block ( tls, data, len, mac,
2322  &plaintext_len );
2323  }
2324  if ( ! plaintext ) {
2325  DBGC ( tls, "TLS %p could not allocate %zd bytes for "
2326  "plaintext\n", tls, plaintext_len );
2328  goto done;
2329  }
2330 
2331  DBGC2 ( tls, "Sending plaintext data:\n" );
2332  DBGC2_HD ( tls, plaintext, plaintext_len );
2333 
2334  /* Allocate ciphertext */
2335  ciphertext_len = ( sizeof ( *tlshdr ) + plaintext_len );
2336  ciphertext = xfer_alloc_iob ( &tls->cipherstream, ciphertext_len );
2337  if ( ! ciphertext ) {
2338  DBGC ( tls, "TLS %p could not allocate %zd bytes for "
2339  "ciphertext\n", tls, ciphertext_len );
2341  goto done;
2342  }
2343 
2344  /* Assemble ciphertext */
2345  tlshdr = iob_put ( ciphertext, sizeof ( *tlshdr ) );
2346  tlshdr->type = type;
2347  tlshdr->version = htons ( tls->version );
2348  tlshdr->length = htons ( plaintext_len );
2349  memcpy ( cipherspec->cipher_next_ctx, cipherspec->cipher_ctx,
2350  cipher->ctxsize );
2351  cipher_encrypt ( cipher, cipherspec->cipher_next_ctx, plaintext,
2352  iob_put ( ciphertext, plaintext_len ), plaintext_len );
2353 
2354  /* Free plaintext as soon as possible to conserve memory */
2355  free ( plaintext );
2356  plaintext = NULL;
2357 
2358  /* Send ciphertext */
2359  if ( ( rc = xfer_deliver_iob ( &tls->cipherstream,
2360  iob_disown ( ciphertext ) ) ) != 0 ) {
2361  DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
2362  tls, strerror ( rc ) );
2363  goto done;
2364  }
2365 
2366  /* Update TX state machine to next record */
2367  tls->tx_seq += 1;
2369  tls->tx_cipherspec.cipher_next_ctx, cipher->ctxsize );
2370 
2371  done:
2372  free ( plaintext );
2373  free_iob ( ciphertext );
2374  return rc;
2375 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:116
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:254
uint8_t type
Content type.
Definition: tls.h:31
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
uint8_t type
Type.
Definition: ena.h:16
#define DBGC(...)
Definition: compiler.h:505
uint16_t length
Length of payload.
Definition: tls.h:38
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A TLS cipher specification.
Definition: tls.h:165
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:202
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:299
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:173
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
#define ENOMEM_TX_CIPHERTEXT
Definition: tls.c:130
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:294
#define DBGC2_HD(...)
Definition: compiler.h:524
unsigned char uint8_t
Definition: stdint.h:10
static int is_stream_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:217
size_t ctxsize
Context size.
Definition: crypto.h:52
static void * tls_assemble_block(struct tls_connection *tls, const void *data, size_t len, void *digest, size_t *plaintext_len)
Allocate and assemble block-ciphered record from data and MAC portions.
Definition: tls.c:2247
A TLS header.
Definition: tls.h:26
#define ENOMEM_TX_PLAINTEXT
Definition: tls.c:126
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:24
uint16_t version
Protocol version.
Definition: tls.h:36
uint16_t version
Protocol version.
Definition: tls.h:297
A cipher algorithm.
Definition: crypto.h:48
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:147
static void *__malloc tls_assemble_stream(struct tls_connection *tls, const void *data, size_t len, void *digest, size_t *plaintext_len)
Allocate and assemble stream-ciphered record from data and MAC portions.
Definition: tls.c:2213
static void tls_hmac(struct tls_cipherspec *cipherspec, uint64_t seq, struct tls_header *tlshdr, const void *data, size_t len, void *hmac)
Calculate HMAC.
Definition: tls.c:2191
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135
struct bofm_section_header done
Definition: bofm_test.c:46
uint64_t tx_seq
TX sequence number.
Definition: tls.h:342
A persistent I/O buffer.
Definition: iobuf.h:32
void * cipher_next_ctx
Next bulk encryption cipher context (TX only)
Definition: tls.h:175

References tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_encrypt, tls_cipherspec::cipher_next_ctx, tls_connection::cipherstream, cipher_algorithm::ctxsize, data, DBGC, DBGC2, DBGC2_HD, tls_cipher_suite::digest, digest_algorithm::digestsize, done, ENOMEM_TX_CIPHERTEXT, ENOMEM_TX_PLAINTEXT, free, free_iob(), htons, iob_disown, iob_put, is_stream_cipher(), len, tls_header::length, mac, memcpy(), NULL, rc, strerror(), tls_cipherspec::suite, tls_assemble_block(), tls_assemble_stream(), tls_hmac(), tls_connection::tx_cipherspec, tls_connection::tx_seq, type, tls_header::type, tls_header::version, tls_connection::version, xfer_alloc_iob(), and xfer_deliver_iob().

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

◆ tls_clear_cipher() [1/2]

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

◆ tls_uint24()

static unsigned long tls_uint24 ( const tls24_t field24)
inlinestatic

Extract 24-bit field value.

Parameters
field2424-bit field
Return values
valueField value

Definition at line 219 of file tls.c.

219  {
220 
221  return ( ( field24->high << 16 ) | be16_to_cpu ( field24->low ) );
222 }
#define be16_to_cpu(value)
Definition: byteswap.h:115
uint16_t low
Low word.
Definition: tls.c:208
uint8_t high
High byte.
Definition: tls.c:206

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

230  {
231 
232  field24->high = ( value >> 16 );
233  field24->low = cpu_to_be16 ( value );
234 }
#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:208
uint8_t high
High byte.
Definition: tls.c:206

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

242  {
243  return ( ( ! is_pending ( &tls->client_negotiation ) ) &&
244  ( ! is_pending ( &tls->server_negotiation ) ) );
245 }
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:335
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:337

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

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

◆ md5_sha1_init()

static void md5_sha1_init ( void *  ctx)
static

Initialise MD5+SHA1 algorithm.

Parameters
ctxMD5+SHA1 context

Definition at line 259 of file tls.c.

259  {
260  struct md5_sha1_context *context = ctx;
261 
262  digest_init ( &md5_algorithm, context->md5 );
263  digest_init ( &sha1_algorithm, context->sha1 );
264 }
An MD5+SHA1 context.
Definition: tls.h:228
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:232
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:230
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:287
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258

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

273  {
274  struct md5_sha1_context *context = ctx;
275 
276  digest_update ( &md5_algorithm, context->md5, data, len );
277  digest_update ( &sha1_algorithm, context->sha1, data, len );
278 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:177
An MD5+SHA1 context.
Definition: tls.h:228
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint32_t len
Length.
Definition: ena.h:14
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:232
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:230
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:287
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258

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

286  {
287  struct md5_sha1_context *context = ctx;
288  struct md5_sha1_digest *digest = out;
289 
290  digest_final ( &md5_algorithm, context->md5, digest->md5 );
291  digest_final ( &sha1_algorithm, context->sha1, digest->sha1 );
292 }
An MD5+SHA1 context.
Definition: tls.h:228
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
__be32 out[4]
Definition: CIB_PRM.h:36
An MD5+SHA1 digest.
Definition: tls.h:239
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
Definition: tls.h:232
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition: tls.h:230
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:287
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258

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

◆ free_tls_session()

static void free_tls_session ( struct refcnt refcnt)
static

Free TLS session.

Parameters
refcntReference counter

Definition at line 324 of file tls.c.

324  {
325  struct tls_session *session =
326  container_of ( refcnt, struct tls_session, refcnt );
327 
328  /* Sanity check */
329  assert ( list_empty ( &session->conn ) );
330 
331  /* Remove from list of sessions */
332  list_del ( &session->list );
333 
334  /* Free session ticket */
335  free ( session->ticket );
336 
337  /* Free session */
338  free ( session );
339 }
A reference counter.
Definition: refcnt.h:26
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct ntlm_data session
Session key.
Definition: ntlm.h:24
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
A TLS session.
Definition: tls.h:250

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

Referenced by tls_session().

◆ free_tls()

static void free_tls ( struct refcnt refcnt)
static

Free TLS connection.

Parameters
refcntReference counter

Definition at line 346 of file tls.c.

346  {
347  struct tls_connection *tls =
349  struct tls_session *session = tls->session;
350  struct io_buffer *iobuf;
351  struct io_buffer *tmp;
352 
353  /* Free dynamically-allocated resources */
354  free ( tls->new_session_ticket );
355  tls_clear_cipher ( tls, &tls->tx_cipherspec );
357  tls_clear_cipher ( tls, &tls->rx_cipherspec );
359  list_for_each_entry_safe ( iobuf, tmp, &tls->rx_data, list ) {
360  list_del ( &iobuf->list );
361  free_iob ( iobuf );
362  }
363  x509_put ( tls->cert );
364  x509_chain_put ( tls->chain );
365 
366  /* Drop reference to session */
367  assert ( list_empty ( &tls->list ) );
368  ref_put ( &session->refcnt );
369 
370  /* Free TLS structure itself */
371  free ( tls );
372 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:330
struct tls_session * session
Session.
Definition: tls.h:279
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
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
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:299
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct ntlm_data session
Session key.
Definition: ntlm.h:24
void * new_session_ticket
New session ticket.
Definition: tls.h:287
struct list_head list
List of connections within the same session.
Definition: tls.h:281
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:447
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
uint8_t * tmp
Definition: entropy.h:156
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:303
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:301
struct list_head rx_data
List of received data buffers.
Definition: tls.h:357
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
A TLS session.
Definition: tls.h:250
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:247
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:305
A TLS connection.
Definition: tls.h:274
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct x509_certificate * cert
Client certificate (if used)
Definition: tls.h:323
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
A persistent I/O buffer.
Definition: iobuf.h:32

References assert(), tls_connection::cert, tls_connection::chain, container_of, free, free_iob(), io_buffer::list, tls_connection::list, list_del, list_empty, list_for_each_entry_safe, tls_connection::new_session_ticket, ref_put, tls_connection::rx_cipherspec, tls_connection::rx_cipherspec_pending, tls_connection::rx_data, session, tls_connection::session, tls_clear_cipher(), tmp, tls_connection::tx_cipherspec, tls_connection::tx_cipherspec_pending, x509_chain_put(), and x509_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 380 of file tls.c.

380  {
381 
382  /* Remove pending operations, if applicable */
385  pending_put ( &tls->validation );
386 
387  /* Remove process */
388  process_del ( &tls->process );
389 
390  /* Close all interfaces */
391  intf_shutdown ( &tls->cipherstream, rc );
392  intf_shutdown ( &tls->plainstream, rc );
393  intf_shutdown ( &tls->validator, rc );
394 
395  /* Remove from session */
396  list_del ( &tls->list );
397  INIT_LIST_HEAD ( &tls->list );
398 
399  /* Resume all other connections, in case we were the lead connection */
400  tls_tx_resume_all ( tls->session );
401 }
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:957
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:335
struct process process
TX process.
Definition: tls.h:346
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
struct tls_session * session
Session.
Definition: tls.h:279
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:339
struct list_head list
List of connections within the same session.
Definition: tls.h:281
struct interface cipherstream
Ciphertext stream.
Definition: tls.h:294
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:337
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
struct interface validator
Certificate validator.
Definition: tls.h:332
struct interface plainstream
Plaintext stream.
Definition: tls.h:292

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

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

◆ tls_generate_random()

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

Generate random data.

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

Definition at line 418 of file tls.c.

419  {
420  int rc;
421 
422  /* Generate random bits with no additional input and without
423  * prediction resistance
424  */
425  if ( ( rc = rbg_generate ( NULL, 0, 0, data, len ) ) != 0 ) {
426  DBGC ( tls, "TLS %p could not generate random data: %s\n",
427  tls, strerror ( rc ) );
428  return rc;
429  }
430 
431  return 0;
432 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
Definition: rbg.h:36
#define DBGC(...)
Definition: compiler.h:505
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

Referenced by add_tls(), and tls_assemble_block().

◆ tls_hmac_update_va()

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

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

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

Definition at line 441 of file tls.c.

442  {
443  void *data;
444  size_t len;
445 
446  while ( ( data = va_arg ( args, void * ) ) ) {
447  len = va_arg ( args, size_t );
448  hmac_update ( digest, digest_ctx, data, len );
449  }
450 }
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define va_arg(ap, type)
Definition: stdarg.h:8
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
static void hmac_update(struct digest_algorithm *digest, void *digest_ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:21

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

Referenced by tls_p_hash_va().

◆ tls_p_hash_va()

static void tls_p_hash_va ( struct tls_connection tls,
struct digest_algorithm digest,
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 463 of file tls.c.

467  {
468  uint8_t secret_copy[secret_len];
469  uint8_t digest_ctx[digest->ctxsize];
470  uint8_t digest_ctx_partial[digest->ctxsize];
471  uint8_t a[digest->digestsize];
472  uint8_t out_tmp[digest->digestsize];
473  size_t frag_len = digest->digestsize;
474  va_list tmp;
475 
476  /* Copy the secret, in case HMAC modifies it */
477  memcpy ( secret_copy, secret, secret_len );
478  secret = secret_copy;
479  DBGC2 ( tls, "TLS %p %s secret:\n", tls, digest->name );
480  DBGC2_HD ( tls, secret, secret_len );
481 
482  /* Calculate A(1) */
483  hmac_init ( digest, digest_ctx, secret, &secret_len );
484  va_copy ( tmp, seeds );
485  tls_hmac_update_va ( digest, digest_ctx, tmp );
486  va_end ( tmp );
487  hmac_final ( digest, digest_ctx, secret, &secret_len, a );
488  DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name );
489  DBGC2_HD ( tls, &a, sizeof ( a ) );
490 
491  /* Generate as much data as required */
492  while ( out_len ) {
493  /* Calculate output portion */
494  hmac_init ( digest, digest_ctx, secret, &secret_len );
495  hmac_update ( digest, digest_ctx, a, sizeof ( a ) );
496  memcpy ( digest_ctx_partial, digest_ctx, digest->ctxsize );
497  va_copy ( tmp, seeds );
498  tls_hmac_update_va ( digest, digest_ctx, tmp );
499  va_end ( tmp );
500  hmac_final ( digest, digest_ctx,
501  secret, &secret_len, out_tmp );
502 
503  /* Copy output */
504  if ( frag_len > out_len )
505  frag_len = out_len;
506  memcpy ( out, out_tmp, frag_len );
507  DBGC2 ( tls, "TLS %p %s output:\n", tls, digest->name );
508  DBGC2_HD ( tls, out, frag_len );
509 
510  /* Calculate A(i) */
511  hmac_final ( digest, digest_ctx_partial,
512  secret, &secret_len, a );
513  DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name );
514  DBGC2_HD ( tls, &a, sizeof ( a ) );
515 
516  out += frag_len;
517  out_len -= frag_len;
518  }
519 }
#define va_end(ap)
Definition: stdarg.h:9
void hmac_final(struct digest_algorithm *digest, void *digest_ctx, void *key, size_t *key_len, void *hmac)
Finalise HMAC.
Definition: hmac.c:115
static void tls_hmac_update_va(struct digest_algorithm *digest, void *digest_ctx, va_list args)
Update HMAC with a list of ( data, len ) pairs.
Definition: tls.c:441
#define va_copy(dest, src)
Definition: stdarg.h:10
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
void * memcpy(void *dest, const void *src, size_t len) __nonnull
__be32 out[4]
Definition: CIB_PRM.h:36
#define DBGC2_HD(...)
Definition: compiler.h:524
uint8_t * tmp
Definition: entropy.h:156
unsigned char uint8_t
Definition: stdint.h:10
#define DBGC2(...)
Definition: compiler.h:522
__builtin_va_list va_list
Definition: stdarg.h:6
void hmac_init(struct digest_algorithm *digest, void *digest_ctx, void *key, size_t *key_len)
Initialise HMAC.
Definition: hmac.c:80
static void hmac_update(struct digest_algorithm *digest, void *digest_ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:21

References DBGC2, DBGC2_HD, digest, hmac_final(), hmac_init(), hmac_update(), memcpy(), out, tls_hmac_update_va(), tmp, va_copy, and va_end.

Referenced by tls_prf().

◆ tls_prf()

static void tls_prf ( struct tls_connection tls,
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 531 of file tls.c.

532  {
533  va_list seeds;
534  va_list tmp;
535  size_t subsecret_len;
536  void *md5_secret;
537  void *sha1_secret;
538  uint8_t buf[out_len];
539  unsigned int i;
540 
541  va_start ( seeds, out_len );
542 
543  if ( tls->version >= TLS_VERSION_TLS_1_2 ) {
544  /* Use P_SHA256 for TLSv1.2 and later */
545  tls_p_hash_va ( tls, &sha256_algorithm, secret, secret_len,
546  out, out_len, seeds );
547  } else {
548  /* Use combination of P_MD5 and P_SHA-1 for TLSv1.1
549  * and earlier
550  */
551 
552  /* Split secret into two, with an overlap of up to one byte */
553  subsecret_len = ( ( secret_len + 1 ) / 2 );
554  md5_secret = secret;
555  sha1_secret = ( secret + secret_len - subsecret_len );
556 
557  /* Calculate MD5 portion */
558  va_copy ( tmp, seeds );
559  tls_p_hash_va ( tls, &md5_algorithm, md5_secret,
560  subsecret_len, out, out_len, seeds );
561  va_end ( tmp );
562 
563  /* Calculate SHA1 portion */
564  va_copy ( tmp, seeds );
565  tls_p_hash_va ( tls, &sha1_algorithm, sha1_secret,
566  subsecret_len, buf, out_len, seeds );
567  va_end ( tmp );
568 
569  /* XOR the two portions together into the final output buffer */
570  for ( i = 0 ; i < out_len ; i++ )
571  *( ( uint8_t * ) out + i ) ^= buf[i];
572  }
573 
574  va_end ( seeds );
575 }
#define va_end(ap)
Definition: stdarg.h:9
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:48
#define va_copy(dest, src)
Definition: stdarg.h:10
__be32 out[4]
Definition: CIB_PRM.h:36
uint8_t * tmp
Definition: entropy.h:156
unsigned char uint8_t
Definition: stdint.h:10
struct digest_algorithm sha256_algorithm
SHA-256 algorithm.
Definition: sha256.c:265
__builtin_va_list va_list
Definition: stdarg.h:6
uint16_t version
Protocol version.
Definition: tls.h:297
#define va_start(ap, last)
Definition: stdarg.h:7
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:287
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258
static void tls_p_hash_va(struct tls_connection *tls, struct digest_algorithm *digest, 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:463

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

◆ tls_generate_master_secret()

static void tls_generate_master_secret ( struct tls_connection tls)
static

Generate master secret.

Parameters
tlsTLS connection

The pre-master secret and the client and server random values must already be known.

Definition at line 606 of file tls.c.

606  {
607  DBGC ( tls, "TLS %p pre-master-secret:\n", tls );
608  DBGC_HD ( tls, &tls->pre_master_secret,
609  sizeof ( tls->pre_master_secret ) );
610  DBGC ( tls, "TLS %p client random bytes:\n", tls );
611  DBGC_HD ( tls, &tls->client_random, sizeof ( tls->client_random ) );
612  DBGC ( tls, "TLS %p server random bytes:\n", tls );
613  DBGC_HD ( tls, &tls->server_random, sizeof ( tls->server_random ) );
614 
615  tls_prf_label ( tls, &tls->pre_master_secret,
616  sizeof ( tls->pre_master_secret ),
617  &tls->master_secret, sizeof ( tls->master_secret ),
618  "master secret",
619  &tls->client_random, sizeof ( tls->client_random ),
620  &tls->server_random, sizeof ( tls->server_random ) );
621 
622  DBGC ( tls, "TLS %p generated master secret:\n", tls );
623  DBGC_HD ( tls, &tls->master_secret, sizeof ( tls->master_secret ) );
624 }
#define DBGC(...)
Definition: compiler.h:505
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:311
uint8_t master_secret[48]
Master secret.
Definition: tls.h:309
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:313
#define DBGC_HD(...)
Definition: compiler.h:507
struct tls_pre_master_secret pre_master_secret
Premaster secret.
Definition: tls.h:307
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:587

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

Referenced by tls_new_server_hello().

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

633  {
634  struct tls_cipherspec *tx_cipherspec = &tls->tx_cipherspec_pending;
635  struct tls_cipherspec *rx_cipherspec = &tls->rx_cipherspec_pending;
636  size_t hash_size = tx_cipherspec->suite->digest->digestsize;
637  size_t key_size = tx_cipherspec->suite->key_len;
638  size_t iv_size = tx_cipherspec->suite->cipher->blocksize;
639  size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
640  uint8_t key_block[total];
641  uint8_t *key;
642  int rc;
643 
644  /* Generate key block */
645  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
646  key_block, sizeof ( key_block ), "key expansion",
647  &tls->server_random, sizeof ( tls->server_random ),
648  &tls->client_random, sizeof ( tls->client_random ) );
649 
650  /* Split key block into portions */
651  key = key_block;
652 
653  /* TX MAC secret */
654  memcpy ( tx_cipherspec->mac_secret, key, hash_size );
655  DBGC ( tls, "TLS %p TX MAC secret:\n", tls );
656  DBGC_HD ( tls, key, hash_size );
657  key += hash_size;
658 
659  /* RX MAC secret */
660  memcpy ( rx_cipherspec->mac_secret, key, hash_size );
661  DBGC ( tls, "TLS %p RX MAC secret:\n", tls );
662  DBGC_HD ( tls, key, hash_size );
663  key += hash_size;
664 
665  /* TX key */
666  if ( ( rc = cipher_setkey ( tx_cipherspec->suite->cipher,
667  tx_cipherspec->cipher_ctx,
668  key, key_size ) ) != 0 ) {
669  DBGC ( tls, "TLS %p could not set TX key: %s\n",
670  tls, strerror ( rc ) );
671  return rc;
672  }
673  DBGC ( tls, "TLS %p TX key:\n", tls );
674  DBGC_HD ( tls, key, key_size );
675  key += key_size;
676 
677  /* RX key */
678  if ( ( rc = cipher_setkey ( rx_cipherspec->suite->cipher,
679  rx_cipherspec->cipher_ctx,
680  key, key_size ) ) != 0 ) {
681  DBGC ( tls, "TLS %p could not set TX key: %s\n",
682  tls, strerror ( rc ) );
683  return rc;
684  }
685  DBGC ( tls, "TLS %p RX key:\n", tls );
686  DBGC_HD ( tls, key, key_size );
687  key += key_size;
688 
689  /* TX initialisation vector */
690  cipher_setiv ( tx_cipherspec->suite->cipher,
691  tx_cipherspec->cipher_ctx, key );
692  DBGC ( tls, "TLS %p TX IV:\n", tls );
693  DBGC_HD ( tls, key, iv_size );
694  key += iv_size;
695 
696  /* RX initialisation vector */
697  cipher_setiv ( rx_cipherspec->suite->cipher,
698  rx_cipherspec->cipher_ctx, key );
699  DBGC ( tls, "TLS %p RX IV:\n", tls );
700  DBGC_HD ( tls, key, iv_size );
701  key += iv_size;
702 
703  assert ( ( key_block + total ) == key );
704 
705  return 0;
706 }
size_t blocksize
Block size.
Definition: crypto.h:54
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:311
A TLS cipher specification.
Definition: tls.h:165
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:173
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
uint8_t master_secret[48]
Master secret.
Definition: tls.h:309
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:313
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint16_t key_len
Key length.
Definition: tls.h:151
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:301
size_t digestsize
Digest size.
Definition: crypto.h:24
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:305
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:147
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:587
union @375 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:187
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv)
Definition: crypto.h:192
void * mac_secret
MAC secret.
Definition: tls.h:177

References assert(), cipher_algorithm::blocksize, tls_cipher_suite::cipher, tls_cipherspec::cipher_ctx, cipher_setiv(), cipher_setkey(), tls_connection::client_random, DBGC, DBGC_HD, tls_cipher_suite::digest, digest_algorithm::digestsize, key, tls_cipher_suite::key_len, tls_cipherspec::mac_secret, tls_connection::master_secret, memcpy(), rc, tls_connection::rx_cipherspec_pending, tls_connection::server_random, strerror(), tls_cipherspec::suite, tls_prf_label, and tls_connection::tx_cipherspec_pending.

Referenced by tls_new_server_hello().

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

732  {
733  struct tls_cipher_suite *suite;
734 
735  /* Identify cipher suite */
737  if ( suite->code == cipher_suite )
738  return suite;
739  }
740 
741  return NULL;
742 }
A TLS cipher suite.
Definition: tls.h:143
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:157
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:153

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

750  {
751 
752  if ( cipherspec->suite ) {
753  pubkey_final ( cipherspec->suite->pubkey,
754  cipherspec->pubkey_ctx );
755  }
756  free ( cipherspec->dynamic );
757  memset ( cipherspec, 0, sizeof ( *cipherspec ) );
758  cipherspec->suite = &tls_cipher_suite_null;
759 }
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:716
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:145
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:171
static void pubkey_final(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:254
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:169
void * memset(void *dest, int character, size_t len) __nonnull

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

◆ tls_set_cipher()

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

Set cipher suite.

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

Definition at line 769 of file tls.c.

771  {
772  struct pubkey_algorithm *pubkey = suite->pubkey;
773  struct cipher_algorithm *cipher = suite->cipher;
774  struct digest_algorithm *digest = suite->digest;
775  size_t total;
776  void *dynamic;
777 
778  /* Clear out old cipher contents, if any */
779  tls_clear_cipher ( tls, cipherspec );
780 
781  /* Allocate dynamic storage */
782  total = ( pubkey->ctxsize + 2 * cipher->ctxsize + digest->digestsize );
783  dynamic = zalloc ( total );
784  if ( ! dynamic ) {
785  DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto "
786  "context\n", tls, total );
787  return -ENOMEM_CONTEXT;
788  }
789 
790  /* Assign storage */
791  cipherspec->dynamic = dynamic;
792  cipherspec->pubkey_ctx = dynamic; dynamic += pubkey->ctxsize;
793  cipherspec->cipher_ctx = dynamic; dynamic += cipher->ctxsize;
794  cipherspec->cipher_next_ctx = dynamic; dynamic += cipher->ctxsize;
795  cipherspec->mac_secret = dynamic; dynamic += digest->digestsize;
796  assert ( ( cipherspec->dynamic + total ) == dynamic );
797 
798  /* Store parameters */
799  cipherspec->suite = suite;
800 
801  return 0;
802 }
#define DBGC(...)
Definition: compiler.h:505
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:145
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
size_t ctxsize
Context size.
Definition: crypto.h:98
#define ENOMEM_CONTEXT
Definition: tls.c:114
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:173
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:171
size_t ctxsize
Context size.
Definition: crypto.h:52
A message digest algorithm.
Definition: crypto.h:16
A cipher algorithm.
Definition: crypto.h:48
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:147
void * dynamic
Dynamically-allocated storage.
Definition: tls.h:169
A public key algorithm.
Definition: crypto.h:94
void * mac_secret
MAC secret.
Definition: tls.h:177
void * cipher_next_ctx
Next bulk encryption cipher context (TX only)
Definition: tls.h:175

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

Referenced by tls_select_cipher().

◆ tls_select_cipher()

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

Select next cipher suite.

Parameters
tlsTLS connection
cipher_suiteCipher suite specification
Return values
rcReturn status code

Definition at line 811 of file tls.c.

812  {
813  struct tls_cipher_suite *suite;
814  int rc;
815 
816  /* Identify cipher suite */
817  suite = tls_find_cipher_suite ( cipher_suite );
818  if ( ! suite ) {
819  DBGC ( tls, "TLS %p does not support cipher %04x\n",
820  tls, ntohs ( cipher_suite ) );
821  return -ENOTSUP_CIPHER;
822  }
823 
824  /* Set ciphers */
825  if ( ( rc = tls_set_cipher ( tls, &tls->tx_cipherspec_pending,
826  suite ) ) != 0 )
827  return rc;
828  if ( ( rc = tls_set_cipher ( tls, &tls->rx_cipherspec_pending,
829  suite ) ) != 0 )
830  return rc;
831 
832  DBGC ( tls, "TLS %p selected %s-%s-%d-%s\n", tls, suite->pubkey->name,
833  suite->cipher->name, ( suite->key_len * 8 ),
834  suite->digest->name );
835 
836  return 0;
837 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct tls_cipher_suite * tls_find_cipher_suite(unsigned int cipher_suite)
Identify cipher suite.
Definition: tls.c:732
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:145
#define ENOTSUP_CIPHER
Definition: tls.c:142
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
A TLS cipher suite.
Definition: tls.h:143
uint16_t key_len
Key length.
Definition: tls.h:151
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:301
const char * name
Algorithm name.
Definition: crypto.h:18
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:305
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:147
const char * name
Algorithm name.
Definition: crypto.h:50
static int tls_set_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
Set cipher suite.
Definition: tls.c:769
const char * name
Algorithm name.
Definition: crypto.h:96

References tls_cipher_suite::cipher, DBGC, tls_cipher_suite::digest, ENOTSUP_CIPHER, tls_cipher_suite::key_len, digest_algorithm::name, cipher_algorithm::name, pubkey_algorithm::name, ntohs, tls_cipher_suite::pubkey, rc, tls_connection::rx_cipherspec_pending, tls_find_cipher_suite(), tls_set_cipher(), and tls_connection::tx_cipherspec_pending.

Referenced by tls_new_server_hello().

◆ tls_change_cipher()

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

Activate next cipher suite.

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

Definition at line 847 of file tls.c.

849  {
850 
851  /* Sanity check */
852  if ( pending->suite == &tls_cipher_suite_null ) {
853  DBGC ( tls, "TLS %p refusing to use null cipher\n", tls );
854  return -ENOTSUP_NULL;
855  }
856 
857  tls_clear_cipher ( tls, active );
858  memswap ( active, pending, sizeof ( *active ) );
859  return 0;
860 }
void * memswap(void *first, void *second, size_t len)
Swap memory regions.
Definition: string.c:137
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
Definition: tls.c:716
#define DBGC(...)
Definition: compiler.h:505
uint32_t pending
Pending events.
Definition: hyperv.h:12
#define ENOTSUP_NULL
Definition: tls.c:146
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)

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

Referenced by tls_new_change_cipher(), and tls_tx_step().

◆ tls_signature_hash_algorithm()

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

Find TLS signature and hash algorithm.

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

Definition at line 881 of file tls.c.

882  {
883  struct tls_signature_hash_algorithm *sig_hash;
884 
885  /* Identify signature and hash algorithm */
887  if ( ( sig_hash->pubkey == pubkey ) &&
888  ( sig_hash->digest == digest ) ) {
889  return sig_hash;
890  }
891  }
892 
893  return NULL;
894 }
struct digest_algorithm * digest
Digest algorithm.
Definition: tls.h:191
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
A TLS signature algorithm.
Definition: tls.h:189
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:203
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:193
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

Referenced by tls_send_certificate_verify().

◆ tls_add_handshake()

static void 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

Definition at line 910 of file tls.c.

911  {
912 
914  data, len );
916  data, len );
917 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:177
uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE]
MD5+SHA1 context for handshake verification.
Definition: tls.h:315
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:295
struct digest_algorithm sha256_algorithm
SHA-256 algorithm.
Definition: sha256.c:265
uint32_t len
Length.
Definition: ena.h:14
uint8_t handshake_sha256_ctx[SHA256_CTX_SIZE]
SHA256 context for handshake verification.
Definition: tls.h:317
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References data, digest_update(), tls_connection::handshake_md5_sha1_ctx, tls_connection::handshake_sha256_ctx, len, md5_sha1_algorithm, and sha256_algorithm.

Referenced by tls_new_handshake(), 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 MD5+SHA1 or SHA256 digest over all handshake messages seen so far.

Definition at line 928 of file tls.c.

928  {
930  uint8_t ctx[ digest->ctxsize ];
931 
932  memcpy ( ctx, tls->handshake_ctx, sizeof ( ctx ) );
933  digest_final ( digest, ctx, out );
934 }
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:321
void * memcpy(void *dest, const void *src, size_t len) __nonnull
__be32 out[4]
Definition: CIB_PRM.h:36
unsigned char uint8_t
Definition: stdint.h:10
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:319
A message digest algorithm.
Definition: crypto.h:16

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

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

◆ tls_tx_resume()

static void tls_tx_resume ( struct tls_connection tls)
static

Resume TX state machine.

Parameters
tlsTLS connection

Definition at line 948 of file tls.c.

948  {
949  process_add ( &tls->process );
950 }
struct process process
TX process.
Definition: tls.h:346
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59

References tls_connection::process, and process_add().

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

◆ tls_restart()

static void tls_restart ( struct tls_connection tls)
static

Restart negotiation.

Parameters
tlsTLS connection

Definition at line 969 of file tls.c.

969  {
970 
971  /* Sanity check */
972  assert ( ! tls->tx_pending );
973  assert ( ! is_pending ( &tls->client_negotiation ) );
974  assert ( ! is_pending ( &tls->server_negotiation ) );
975  assert ( ! is_pending ( &tls->validation ) );
976 
977  /* (Re)initialise handshake context */
982 
983  /* (Re)start negotiation */
985  tls_tx_resume ( tls );
988 }
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:335
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:948
uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE]
MD5+SHA1 context for handshake verification.
Definition: tls.h:315
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:321
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:339
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:295
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:337
unsigned int tx_pending
TX pending transmissions.
Definition: tls.h:344
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:319
struct digest_algorithm sha256_algorithm
SHA-256 algorithm.
Definition: sha256.c:265
uint8_t handshake_sha256_ctx[SHA256_CTX_SIZE]
SHA256 context for handshake verification.
Definition: tls.h:317
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45

References assert(), tls_connection::client_negotiation, digest_init(), tls_connection::handshake_ctx, tls_connection::handshake_digest, tls_connection::handshake_md5_sha1_ctx, tls_connection::handshake_sha256_ctx, is_pending(), md5_sha1_algorithm, pending_get(), tls_connection::server_negotiation, sha256_algorithm, TLS_TX_CLIENT_HELLO, tls_tx_resume(), tls_connection::tx_pending, and tls_connection::validation.

Referenced by add_tls(), and tls_new_hello_request().

◆ tls_send_handshake()

static int tls_send_handshake ( struct tls_connection tls,
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 998 of file tls.c.

999  {
1000 
1001  /* Add to handshake digest */
1002  tls_add_handshake ( tls, data, len );
1003 
1004  /* Send record */
1005  return tls_send_plaintext ( tls, TLS_TYPE_HANDSHAKE, data, len );
1006 }
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:2294
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:57
uint32_t len
Length.
Definition: ena.h:14
static void tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:910
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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(), and tls_send_finished().

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

1014  {
1015  struct tls_session *session = tls->session;
1016  size_t name_len = strlen ( session->name );
1017  struct {
1018  uint32_t type_length;
1019  uint16_t version;
1020  uint8_t random[32];
1021  uint8_t session_id_len;
1022  uint8_t session_id[tls->session_id_len];
1023  uint16_t cipher_suite_len;
1024  uint16_t cipher_suites[TLS_NUM_CIPHER_SUITES];
1025  uint8_t compression_methods_len;
1026  uint8_t compression_methods[1];
1027  uint16_t extensions_len;
1028  struct {
1029  uint16_t server_name_type;
1030  uint16_t server_name_len;
1031  struct {
1032  uint16_t len;
1033  struct {
1034  uint8_t type;
1035  uint16_t len;
1036  uint8_t name[name_len];
1037  } __attribute__ (( packed )) list[1];
1038  } __attribute__ (( packed )) server_name;
1039  uint16_t max_fragment_length_type;
1040  uint16_t max_fragment_length_len;
1041  struct {
1042  uint8_t max;
1043  } __attribute__ (( packed )) max_fragment_length;
1044  uint16_t signature_algorithms_type;
1045  uint16_t signature_algorithms_len;
1046  struct {
1047  uint16_t len;
1048  struct tls_signature_hash_id
1050  } __attribute__ (( packed )) signature_algorithms;
1051  uint16_t renegotiation_info_type;
1052  uint16_t renegotiation_info_len;
1053  struct {
1054  uint8_t len;
1056  sizeof ( tls->verify.client ) :0];
1057  } __attribute__ (( packed )) renegotiation_info;
1058  uint16_t session_ticket_type;
1059  uint16_t session_ticket_len;
1060  struct {
1061  uint8_t data[session->ticket_len];
1062  } __attribute__ (( packed )) session_ticket;
1063  } __attribute__ (( packed )) extensions;
1064  } __attribute__ (( packed )) hello;
1065  struct tls_cipher_suite *suite;
1066  struct tls_signature_hash_algorithm *sighash;
1067  unsigned int i;
1068 
1069  /* Construct record */
1070  memset ( &hello, 0, sizeof ( hello ) );
1071  hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) |
1072  htonl ( sizeof ( hello ) -
1073  sizeof ( hello.type_length ) ) );
1074  hello.version = htons ( tls->version );
1075  memcpy ( &hello.random, &tls->client_random, sizeof ( hello.random ) );
1076  hello.session_id_len = tls->session_id_len;
1077  memcpy ( hello.session_id, tls->session_id,
1078  sizeof ( hello.session_id ) );
1079  hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) );
1080  i = 0 ; for_each_table_entry ( suite, TLS_CIPHER_SUITES )
1081  hello.cipher_suites[i++] = suite->code;
1082  hello.compression_methods_len = sizeof ( hello.compression_methods );
1083  hello.extensions_len = htons ( sizeof ( hello.extensions ) );
1084  hello.extensions.server_name_type = htons ( TLS_SERVER_NAME );
1085  hello.extensions.server_name_len
1086  = htons ( sizeof ( hello.extensions.server_name ) );
1087  hello.extensions.server_name.len
1088  = htons ( sizeof ( hello.extensions.server_name.list ) );
1089  hello.extensions.server_name.list[0].type = TLS_SERVER_NAME_HOST_NAME;
1090  hello.extensions.server_name.list[0].len
1091  = htons ( sizeof ( hello.extensions.server_name.list[0].name ));
1092  memcpy ( hello.extensions.server_name.list[0].name, session->name,
1093  sizeof ( hello.extensions.server_name.list[0].name ) );
1094  hello.extensions.max_fragment_length_type
1096  hello.extensions.max_fragment_length_len
1097  = htons ( sizeof ( hello.extensions.max_fragment_length ) );
1098  hello.extensions.max_fragment_length.max
1100  hello.extensions.signature_algorithms_type
1102  hello.extensions.signature_algorithms_len
1103  = htons ( sizeof ( hello.extensions.signature_algorithms ) );
1104  hello.extensions.signature_algorithms.len
1105  = htons ( sizeof ( hello.extensions.signature_algorithms.code));
1106  i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
1107  hello.extensions.signature_algorithms.code[i++] = sighash->code;
1108  hello.extensions.renegotiation_info_type
1110  hello.extensions.renegotiation_info_len
1111  = htons ( sizeof ( hello.extensions.renegotiation_info ) );
1112  hello.extensions.renegotiation_info.len
1113  = sizeof ( hello.extensions.renegotiation_info.data );
1114  memcpy ( hello.extensions.renegotiation_info.data, tls->verify.client,
1115  sizeof ( hello.extensions.renegotiation_info.data ) );
1116  hello.extensions.session_ticket_type = htons ( TLS_SESSION_TICKET );
1117  hello.extensions.session_ticket_len
1118  = htons ( sizeof ( hello.extensions.session_ticket ) );
1119  memcpy ( hello.extensions.session_ticket.data, session->ticket,
1120  sizeof ( hello.extensions.session_ticket.data ) );
1121 
1122  return tls_send_handshake ( tls, &hello, sizeof ( hello ) );
1123 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:327
#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:723
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:116
#define max(x, y)
Definition: ath.h:39
struct tls_session * session
Session.
Definition: tls.h:279
uint8_t type
Type.
Definition: ena.h:16
#define TLS_CLIENT_HELLO
Definition: tls.h:64
uint8_t session_id[32]
Session ID.
Definition: tls.h:283
#define htonl(value)
Definition: byteswap.h:133
#define TLS_MAX_FRAGMENT_LENGTH
Definition: tls.h:103
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Version number.
Definition: ath9k_hw.c:1983
struct ntlm_data session
Session key.
Definition: ntlm.h:24
#define TLS_SESSION_TICKET
Definition: tls.h:113
A TLS cipher suite.
Definition: tls.h:143
#define TLS_SERVER_NAME
Definition: tls.h:99
A TLS signature algorithm.
Definition: tls.h:189
struct list_head list
List of sessions.
Definition: tls.h:254
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define TLS_NUM_SIG_HASH_ALGORITHMS
Number of supported signature and hash algorithms.
Definition: tls.c:870
struct tls_client_random client_random
Client random bytes.
Definition: tls.h:313
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:30
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
Definition: tls.h:203
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:195
#define TLS_SERVER_NAME_HOST_NAME
Definition: tls.h:100
uint8_t client[12]
Client verification data.
Definition: tls.h:121
uint8_t code
Response code.
Definition: scsi.h:16
uint32_t len
Length.
Definition: ena.h:14
A TLS session.
Definition: tls.h:250
uint16_t version
Protocol version.
Definition: tls.h:297
static int tls_send_handshake(struct tls_connection *tls, void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:998
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:325
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define TLS_MAX_FRAGMENT_LENGTH_4096
Definition: tls.h:107
const char * name
Server name.
Definition: tls.h:257
A TLS signature and hash algorithm identifier.
Definition: tls.h:181
size_t session_id_len
Length of session ID.
Definition: tls.h:285
#define TLS_CIPHER_SUITES
TLS cipher suite table.
Definition: tls.h:157
#define htons(value)
Definition: byteswap.h:135
#define TLS_SIGNATURE_ALGORITHMS
Definition: tls.h:110
uint16_t code
Numeric code (in network-endian order)
Definition: tls.h:153
void * memset(void *dest, int character, size_t len) __nonnull

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

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

1131  {
1132  struct {
1133  uint32_t type_length;
1134  tls24_t length;
1135  struct {
1136  tls24_t length;
1137  uint8_t data[ tls->cert->raw.len ];
1138  } __attribute__ (( packed )) certificates[1];
1139  } __attribute__ (( packed )) *certificate;
1140  int rc;
1141 
1142  /* Allocate storage for Certificate record (which may be too
1143  * large for the stack).
1144  */
1145  certificate = zalloc ( sizeof ( *certificate ) );
1146  if ( ! certificate )
1147  return -ENOMEM_CERTIFICATE;
1148 
1149  /* Populate record */
1150  certificate->type_length =
1152  htonl ( sizeof ( *certificate ) -
1153  sizeof ( certificate->type_length ) ) );
1154  tls_set_uint24 ( &certificate->length,
1155  sizeof ( certificate->certificates ) );
1156  tls_set_uint24 ( &certificate->certificates[0].length,
1157  sizeof ( certificate->certificates[0].data ) );
1158  memcpy ( certificate->certificates[0].data,
1159  tls->cert->raw.data,
1160  sizeof ( certificate->certificates[0].data ) );
1161 
1162  /* Transmit record */
1163  rc = tls_send_handshake ( tls, certificate, sizeof ( *certificate ) );
1164 
1165  /* Free record */
1166  free ( certificate );
1167 
1168  return rc;
1169 }
#define __attribute__(x)
Definition: compiler.h:10
uint16_t length
Length.
Definition: intel.h:14
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const void * data
Start of data.
Definition: asn1.h:21
#define TLS_CERTIFICATE
Definition: tls.h:67
#define htonl(value)
Definition: byteswap.h:133
size_t len
Length of data.
Definition: asn1.h:23
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define cpu_to_le32(value)
Definition: byteswap.h:107
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
A TLS 24-bit integer.
Definition: tls.c:204
#define ENOMEM_CERTIFICATE
Definition: tls.c:118
static int tls_send_handshake(struct tls_connection *tls, void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:998
static void tls_set_uint24(tls24_t *field24, unsigned long value)
Set 24-bit field value.
Definition: tls.c:230
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
struct asn1_cursor raw
Raw certificate.
Definition: x509.h:198
struct x509_certificate * cert
Client certificate (if used)
Definition: tls.h:323

References __attribute__, tls_connection::cert, cpu_to_le32, data, asn1_cursor::data, ENOMEM_CERTIFICATE, free, htonl, asn1_cursor::len, length, memcpy(), x509_certificate::raw, rc, TLS_CERTIFICATE, tls_send_handshake(), tls_set_uint24(), and zalloc().

Referenced by tls_tx_step().

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

1177  {
1178  struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
1179  struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1180  size_t max_len = pubkey_max_len ( pubkey, cipherspec->pubkey_ctx );
1181  struct {
1182  uint32_t type_length;
1183  uint16_t encrypted_pre_master_secret_len;
1184  uint8_t encrypted_pre_master_secret[max_len];
1185  } __attribute__ (( packed )) key_xchg;
1186  size_t unused;
1187  int len;
1188  int rc;
1189 
1190  /* Encrypt pre-master secret using server's public key */
1191  memset ( &key_xchg, 0, sizeof ( key_xchg ) );
1192  len = pubkey_encrypt ( pubkey, cipherspec->pubkey_ctx,
1193  &tls->pre_master_secret,
1194  sizeof ( tls->pre_master_secret ),
1195  key_xchg.encrypted_pre_master_secret );
1196  if ( len < 0 ) {
1197  rc = len;
1198  DBGC ( tls, "TLS %p could not encrypt pre-master secret: %s\n",
1199  tls, strerror ( rc ) );
1200  return rc;
1201  }
1202  unused = ( max_len - len );
1203  key_xchg.type_length =
1205  htonl ( sizeof ( key_xchg ) -
1206  sizeof ( key_xchg.type_length ) - unused ) );
1207  key_xchg.encrypted_pre_master_secret_len =
1208  htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) -
1209  unused );
1210 
1211  return tls_send_handshake ( tls, &key_xchg,
1212  ( sizeof ( key_xchg ) - unused ) );
1213 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static void size_t size_t max_len
Definition: entropy.h:153
#define DBGC(...)
Definition: compiler.h:505
A TLS cipher specification.
Definition: tls.h:165
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
Definition: tls.h:145
#define htonl(value)
Definition: byteswap.h:133
static size_t pubkey_max_len(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:226
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * pubkey_ctx
Public key encryption context.
Definition: tls.h:171
unsigned char uint8_t
Definition: stdint.h:10
size_t(* max_len)(void *ctx)
Calculate maximum output length.
Definition: crypto.h:112
unsigned int uint32_t
Definition: stdint.h:12
struct tls_cipherspec tx_cipherspec_pending
Next TX cipher specification.
Definition: tls.h:301
struct tls_pre_master_secret pre_master_secret
Premaster secret.
Definition: tls.h:307
uint32_t len
Length.
Definition: ena.h:14
uint8_t unused[32]
Unused.
Definition: eltorito.h:15
static int pubkey_encrypt(struct pubkey_algorithm *pubkey, void *ctx, const void *data, size_t len, void *out)
Definition: crypto.h:231
static int tls_send_handshake(struct tls_connection *tls, void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:998
A public key algorithm.
Definition: crypto.h:94
#define htons(value)
Definition: byteswap.h:135
#define TLS_CLIENT_KEY_EXCHANGE
Definition: tls.h:72
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, cpu_to_le32, DBGC, htonl, htons, len, pubkey_algorithm::max_len, max_len, memset(), tls_connection::pre_master_secret, tls_cipher_suite::pubkey, tls_cipherspec::pubkey_ctx, pubkey_encrypt(), pubkey_max_len(), rc, strerror(), tls_cipherspec::suite, TLS_CLIENT_KEY_EXCHANGE, tls_send_handshake(), tls_connection::tx_cipherspec_pending, and unused.

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

1221  {
1222  struct digest_algorithm *digest = tls->handshake_digest;
1223  struct x509_certificate *cert = tls->cert;
1224  struct pubkey_algorithm *pubkey = cert->signature_algorithm->pubkey;
1225  uint8_t digest_out[ digest->digestsize ];
1226  uint8_t ctx[ pubkey->ctxsize ];
1227  struct tls_signature_hash_algorithm *sig_hash = NULL;
1228  int rc;
1229 
1230  /* Generate digest to be signed */
1231  tls_verify_handshake ( tls, digest_out );
1232 
1233  /* Initialise public-key algorithm */
1234  if ( ( rc = pubkey_init ( pubkey, ctx, private_key.data,
1235  private_key.len ) ) != 0 ) {
1236  DBGC ( tls, "TLS %p could not initialise %s client private "
1237  "key: %s\n", tls, pubkey->name, strerror ( rc ) );
1238  goto err_pubkey_init;
1239  }
1240 
1241  /* TLSv1.2 and later use explicit algorithm identifiers */
1242  if ( tls->version >= TLS_VERSION_TLS_1_2 ) {
1243  sig_hash = tls_signature_hash_algorithm ( pubkey, digest );
1244  if ( ! sig_hash ) {
1245  DBGC ( tls, "TLS %p could not identify (%s,%s) "
1246  "signature and hash algorithm\n", tls,
1247  pubkey->name, digest->name );
1248  rc = -ENOTSUP_SIG_HASH;
1249  goto err_sig_hash;
1250  }
1251  }
1252 
1253  /* Generate and transmit record */
1254  {
1255  size_t max_len = pubkey_max_len ( pubkey, ctx );
1256  int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
1257  struct {
1258  uint32_t type_length;
1259  struct tls_signature_hash_id sig_hash[use_sig_hash];
1260  uint16_t signature_len;
1262  } __attribute__ (( packed )) certificate_verify;
1263  size_t unused;
1264  int len;
1265 
1266  /* Sign digest */
1267  len = pubkey_sign ( pubkey, ctx, digest, digest_out,
1268  certificate_verify.signature );
1269  if ( len < 0 ) {
1270  rc = len;
1271  DBGC ( tls, "TLS %p could not sign %s digest using %s "
1272  "client private key: %s\n", tls, digest->name,
1273  pubkey->name, strerror ( rc ) );
1274  goto err_pubkey_sign;
1275  }
1276  unused = ( max_len - len );
1277 
1278  /* Construct Certificate Verify record */
1279  certificate_verify.type_length =
1281  htonl ( sizeof ( certificate_verify ) -
1282  sizeof ( certificate_verify.type_length ) -
1283  unused ) );
1284  if ( use_sig_hash ) {
1285  memcpy ( &certificate_verify.sig_hash[0],
1286  &sig_hash->code,
1287  sizeof ( certificate_verify.sig_hash[0] ) );
1288  }
1289  certificate_verify.signature_len =
1290  htons ( sizeof ( certificate_verify.signature ) -
1291  unused );
1292 
1293  /* Transmit record */
1294  rc = tls_send_handshake ( tls, &certificate_verify,
1295  ( sizeof ( certificate_verify ) - unused ) );
1296  }
1297 
1298  err_pubkey_sign:
1299  err_sig_hash:
1300  pubkey_final ( pubkey, ctx );
1301  err_pubkey_init:
1302  return rc;
1303 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static void size_t size_t max_len
Definition: entropy.h:153
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:928
struct asn1_algorithm * signature_algorithm
Signature algorithm.
Definition: x509.h:206
const void * data
Start of data.
Definition: asn1.h:21
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:48
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define htonl(value)
Definition: byteswap.h:133
size_t ctxsize
Context size.
Definition: crypto.h:98
size_t len
Length of data.
Definition: asn1.h:23
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:304
static size_t pubkey_max_len(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:226
u8 signature
Definition: CIB_PRM.h:35
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:881
A TLS signature algorithm.
Definition: tls.h:189
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:185
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
struct tls_signature_hash_id code
Numeric code.
Definition: tls.h:195
struct asn1_cursor private_key
Private key.
Definition: privkey.c:67
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:319
uint32_t len
Length.
Definition: ena.h:14
uint8_t unused[32]
Unused.
Definition: eltorito.h:15
static int pubkey_sign(struct pubkey_algorithm *pubkey, void *ctx, struct digest_algorithm *digest, const void *value, void *signature)
Definition: crypto.h:241
A message digest algorithm.
Definition: crypto.h:16
uint16_t version
Protocol version.
Definition: tls.h:297
static int tls_send_handshake(struct tls_connection *tls, void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:998
static void pubkey_final(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:254
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: tls.h:193
A TLS signature and hash algorithm identifier.
Definition: tls.h:181
#define TLS_CERTIFICATE_VERIFY
Definition: tls.h:71
#define ENOTSUP_SIG_HASH
Definition: tls.c:150
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A public key algorithm.
Definition: crypto.h:94
#define htons(value)
Definition: byteswap.h:135
struct x509_certificate * cert
Client certificate (if used)
Definition: tls.h:323
const char * name
Algorithm name.
Definition: crypto.h:96
static int pubkey_init(struct pubkey_algorithm *pubkey, void *ctx, const void *key, size_t key_len)
Definition: crypto.h:221

References __attribute__, tls_connection::cert, tls_signature_hash_algorithm::code, cpu_to_le32, ctx, pubkey_algorithm::ctxsize, asn1_cursor::data, DBGC, digest, ENOTSUP_SIG_HASH, tls_connection::handshake_digest, htonl, htons, len, asn1_cursor::len, max_len, memcpy(), pubkey_algorithm::name, NULL, private_key, tls_signature_hash_algorithm::pubkey, asn1_algorithm::pubkey, pubkey_final(), pubkey_init(), pubkey_max_len(), pubkey_sign(), rc, signature, x509_certificate::signature_algorithm, strerror(), TLS_CERTIFICATE_VERIFY, tls_send_handshake(), tls_signature_hash_algorithm(), tls_verify_handshake(), TLS_VERSION_TLS_1_2, unused, and tls_connection::version.

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

1311  {
1312  static const uint8_t change_cipher[1] = { 1 };
1314  change_cipher, sizeof ( change_cipher ) );
1315 }
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
Definition: tls.h:51
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
Definition: tls.c:2294
unsigned char uint8_t
Definition: stdint.h:10

References tls_send_plaintext(), and TLS_TYPE_CHANGE_CIPHER.

Referenced by tls_tx_step().

◆ tls_send_finished()

static int tls_send_finished ( struct tls_connection tls)
static

Transmit Finished record.

Parameters
tlsTLS connection
Return values
rcReturn status code

Definition at line 1323 of file tls.c.

1323  {
1324  struct digest_algorithm *digest = tls->handshake_digest;
1325  struct {
1326  uint32_t type_length;
1327  uint8_t verify_data[ sizeof ( tls->verify.client ) ];
1328  } __attribute__ (( packed )) finished;
1329  uint8_t digest_out[ digest->digestsize ];
1330  int rc;
1331 
1332  /* Construct client verification data */
1333  tls_verify_handshake ( tls, digest_out );
1334  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
1335  tls->verify.client, sizeof ( tls->verify.client ),
1336  "client finished", digest_out, sizeof ( digest_out ) );
1337 
1338  /* Construct record */
1339  memset ( &finished, 0, sizeof ( finished ) );
1340  finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
1341  htonl ( sizeof ( finished ) -
1342  sizeof ( finished.type_length ) ) );
1343  memcpy ( finished.verify_data, tls->verify.client,
1344  sizeof ( finished.verify_data ) );
1345 
1346  /* Transmit record */
1347  if ( ( rc = tls_send_handshake ( tls, &finished,
1348  sizeof ( finished ) ) ) != 0 )
1349  return rc;
1350 
1351  /* Mark client as finished */
1352  pending_put ( &tls->client_negotiation );
1353 
1354  return 0;
1355 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:327
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:335
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:928
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define htonl(value)
Definition: byteswap.h:133
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint8_t master_secret[48]
Master secret.
Definition: tls.h:309
#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:121
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:319
A message digest algorithm.
Definition: crypto.h:16
static int tls_send_handshake(struct tls_connection *tls, void *data, size_t len)
Transmit Handshake record.
Definition: tls.c:998
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:587
#define TLS_FINISHED
Definition: tls.h:73
void * memset(void *dest, int character, size_t len) __nonnull

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

Referenced by tls_tx_step().

◆ tls_new_change_cipher()

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

Receive new Change Cipher record.

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

Definition at line 1365 of file tls.c.

1366  {
1367  int rc;
1368 
1369  if ( ( len != 1 ) || ( *( ( uint8_t * ) data ) != 1 ) ) {
1370  DBGC ( tls, "TLS %p received invalid Change Cipher\n", tls );
1371  DBGC_HD ( tls, data, len );
1372  return -EINVAL_CHANGE_CIPHER;
1373  }
1374 
1375  if ( ( rc = tls_change_cipher ( tls, &tls->rx_cipherspec_pending,
1376  &tls->rx_cipherspec ) ) != 0 ) {
1377  DBGC ( tls, "TLS %p could not activate RX cipher: %s\n",
1378  tls, strerror ( rc ) );
1379  return rc;
1380  }
1381  tls->rx_seq = ~( ( uint64_t ) 0 );
1382 
1383  return 0;
1384 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint64_t rx_seq
RX sequence number.
Definition: tls.h:349
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
#define EINVAL_CHANGE_CIPHER
Definition: tls.c:54
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec *pending, struct tls_cipherspec *active)
Activate next cipher suite.
Definition: tls.c:847
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:303
uint32_t len
Length.
Definition: ena.h:14
struct tls_cipherspec rx_cipherspec_pending
Next RX cipher specification.
Definition: tls.h:305
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

Referenced by tls_new_record().

◆ tls_new_alert()

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

Receive new Alert record.

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

Definition at line 1394 of file tls.c.

1395  {
1396  const struct {
1397  uint8_t level;
1398  uint8_t description;
1399  char next[0];
1400  } __attribute__ (( packed )) *alert = data;
1401 
1402  /* Sanity check */
1403  if ( sizeof ( *alert ) != len ) {
1404  DBGC ( tls, "TLS %p received overlength Alert\n", tls );
1405  DBGC_HD ( tls, data, len );
1406  return -EINVAL_ALERT;
1407  }
1408 
1409  switch ( alert->level ) {
1410  case TLS_ALERT_WARNING:
1411  DBGC ( tls, "TLS %p received warning alert %d\n",
1412  tls, alert->description );
1413  return 0;
1414  case TLS_ALERT_FATAL:
1415  DBGC ( tls, "TLS %p received fatal alert %d\n",
1416  tls, alert->description );
1417  return -EPERM_ALERT;
1418  default:
1419  DBGC ( tls, "TLS %p received unknown alert level %d"
1420  "(alert %d)\n", tls, alert->level, alert->description );
1421  return -EIO_ALERT;
1422  }
1423 }
#define __attribute__(x)
Definition: compiler.h:10
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
#define EIO_ALERT
Definition: tls.c:110
#define TLS_ALERT_WARNING
Definition: tls.h:76
#define EINVAL_ALERT
Definition: tls.c:58
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
#define TLS_ALERT_FATAL
Definition: tls.h:77
uint32_t len
Length.
Definition: ena.h:14
static void alert(const char *fmt,...)
Print alert message.
Definition: settings_ui.c:324
#define EPERM_ALERT
Definition: tls.c:158
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

Referenced by tls_new_record().

◆ tls_new_hello_request()

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

Receive new Hello Request handshake record.

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

Definition at line 1433 of file tls.c.

1435  {
1436 
1437  /* Ignore if a handshake is in progress */
1438  if ( ! tls_ready ( tls ) ) {
1439  DBGC ( tls, "TLS %p ignoring Hello Request\n", tls );
1440  return 0;
1441  }
1442 
1443  /* Fail unless server supports secure renegotiation */
1444  if ( ! tls->secure_renegotiation ) {
1445  DBGC ( tls, "TLS %p refusing to renegotiate insecurely\n",
1446  tls );
1447  return -EPERM_RENEG_INSECURE;
1448  }
1449 
1450  /* Restart negotiation */
1451  tls_restart ( tls );
1452 
1453  return 0;
1454 }
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
Definition: tls.c:969
#define DBGC(...)
Definition: compiler.h:505
#define EPERM_RENEG_INSECURE
Definition: tls.c:170
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:325
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:242

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

1465  {
1466  const struct {
1467  uint16_t version;
1468  uint8_t random[32];
1469  uint8_t session_id_len;
1470  uint8_t session_id[0];
1471  } __attribute__ (( packed )) *hello_a = data;
1472  const uint8_t *session_id;
1473  const struct {
1474  uint16_t cipher_suite;
1475  uint8_t compression_method;
1476  char next[0];
1477  } __attribute__ (( packed )) *hello_b;
1478  const struct {
1479  uint16_t len;
1480  uint8_t data[0];
1481  } __attribute__ (( packed )) *exts;
1482  const struct {
1483  uint16_t type;
1484  uint16_t len;
1485  uint8_t data[0];
1486  } __attribute__ (( packed )) *ext;
1487  const struct {
1488  uint8_t len;
1489  uint8_t data[0];
1490  } __attribute__ (( packed )) *reneg = NULL;
1491  uint16_t version;
1492  size_t exts_len;
1493  size_t ext_len;
1494  size_t remaining;
1495  int rc;
1496 
1497  /* Parse header */
1498  if ( ( sizeof ( *hello_a ) > len ) ||
1499  ( hello_a->session_id_len > ( len - sizeof ( *hello_a ) ) ) ||
1500  ( sizeof ( *hello_b ) > ( len - sizeof ( *hello_a ) -
1501  hello_a->session_id_len ) ) ) {
1502  DBGC ( tls, "TLS %p received underlength Server Hello\n", tls );
1503  DBGC_HD ( tls, data, len );
1504  return -EINVAL_HELLO;
1505  }
1506  session_id = hello_a->session_id;
1507  hello_b = ( ( void * ) ( session_id + hello_a->session_id_len ) );
1508 
1509  /* Parse extensions, if present */
1510  remaining = ( len - sizeof ( *hello_a ) - hello_a->session_id_len -
1511  sizeof ( *hello_b ) );
1512  if ( remaining ) {
1513 
1514  /* Parse extensions length */
1515  exts = ( ( void * ) hello_b->next );
1516  if ( ( sizeof ( *exts ) > remaining ) ||
1517  ( ( exts_len = ntohs ( exts->len ) ) >
1518  ( remaining - sizeof ( *exts ) ) ) ) {
1519  DBGC ( tls, "TLS %p received underlength extensions\n",
1520  tls );
1521  DBGC_HD ( tls, data, len );
1522  return -EINVAL_HELLO;
1523  }
1524 
1525  /* Parse extensions */
1526  for ( ext = ( ( void * ) exts->data ), remaining = exts_len ;
1527  remaining ;
1528  ext = ( ( ( void * ) ext ) + sizeof ( *ext ) + ext_len ),
1529  remaining -= ( sizeof ( *ext ) + ext_len ) ) {
1530 
1531  /* Parse extension length */
1532  if ( ( sizeof ( *ext ) > remaining ) ||
1533  ( ( ext_len = ntohs ( ext->len ) ) >
1534  ( remaining - sizeof ( *ext ) ) ) ) {
1535  DBGC ( tls, "TLS %p received underlength "
1536  "extension\n", tls );
1537  DBGC_HD ( tls, data, len );
1538  return -EINVAL_HELLO;
1539  }
1540 
1541  /* Record known extensions */
1542  switch ( ext->type ) {
1543  case htons ( TLS_RENEGOTIATION_INFO ) :
1544  reneg = ( ( void * ) ext->data );
1545  if ( ( sizeof ( *reneg ) > ext_len ) ||
1546  ( reneg->len >
1547  ( ext_len - sizeof ( *reneg ) ) ) ) {
1548  DBGC ( tls, "TLS %p received "
1549  "underlength renegotiation "
1550  "info\n", tls );
1551  DBGC_HD ( tls, data, len );
1552  return -EINVAL_HELLO;
1553  }
1554  break;
1555  }
1556  }
1557  }
1558 
1559  /* Check and store protocol version */
1560  version = ntohs ( hello_a->version );
1561  if ( version < TLS_VERSION_TLS_1_0 ) {
1562  DBGC ( tls, "TLS %p does not support protocol version %d.%d\n",
1563  tls, ( version >> 8 ), ( version & 0xff ) );
1564  return -ENOTSUP_VERSION;
1565  }
1566  if ( version > tls->version ) {
1567  DBGC ( tls, "TLS %p server attempted to illegally upgrade to "
1568  "protocol version %d.%d\n",
1569  tls, ( version >> 8 ), ( version & 0xff ) );
1570  return -EPROTO_VERSION;
1571  }
1572  tls->version = version;
1573  DBGC ( tls, "TLS %p using protocol version %d.%d\n",
1574  tls, ( version >> 8 ), ( version & 0xff ) );
1575 
1576  /* Use MD5+SHA1 digest algorithm for handshake verification
1577  * for versions earlier than TLSv1.2.
1578  */
1579  if ( tls->version < TLS_VERSION_TLS_1_2 ) {
1582  }
1583 
1584  /* Copy out server random bytes */
1585  memcpy ( &tls->server_random, &hello_a->random,
1586  sizeof ( tls->server_random ) );
1587 
1588  /* Select cipher suite */
1589  if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 )
1590  return rc;
1591 
1592  /* Reuse or generate master secret */
1593  if ( hello_a->session_id_len &&
1594  ( hello_a->session_id_len == tls->session_id_len ) &&
1595  ( memcmp ( session_id, tls->session_id,
1596  tls->session_id_len ) == 0 ) ) {
1597 
1598  /* Session ID match: reuse master secret */
1599  DBGC ( tls, "TLS %p resuming session ID:\n", tls );
1600  DBGC_HDA ( tls, 0, tls->session_id, tls->session_id_len );
1601 
1602  } else {
1603 
1604  /* Generate new master secret */
1606 
1607  /* Record new session ID, if present */
1608  if ( hello_a->session_id_len &&
1609  ( hello_a->session_id_len <= sizeof ( tls->session_id ))){
1610  tls->session_id_len = hello_a->session_id_len;
1611  memcpy ( tls->session_id, session_id,
1612  tls->session_id_len );
1613  DBGC ( tls, "TLS %p new session ID:\n", tls );
1614  DBGC_HDA ( tls, 0, tls->session_id,
1615  tls->session_id_len );
1616  }
1617  }
1618 
1619  /* Generate keys */
1620  if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
1621  return rc;
1622 
1623  /* Handle secure renegotiation */
1624  if ( tls->secure_renegotiation ) {
1625 
1626  /* Secure renegotiation is expected; verify data */
1627  if ( ( reneg == NULL ) ||
1628  ( reneg->len != sizeof ( tls->verify ) ) ||
1629  ( memcmp ( reneg->data, &tls->verify,
1630  sizeof ( tls->verify ) ) != 0 ) ) {
1631  DBGC ( tls, "TLS %p server failed secure "
1632  "renegotiation\n", tls );
1633  return -EPERM_RENEG_VERIFY;
1634  }
1635 
1636  } else if ( reneg != NULL ) {
1637 
1638  /* Secure renegotiation is being enabled */
1639  if ( reneg->len != 0 ) {
1640  DBGC ( tls, "TLS %p server provided non-empty initial "
1641  "renegotiation\n", tls );
1642  return -EPERM_RENEG_VERIFY;
1643  }
1644  tls->secure_renegotiation = 1;
1645  }
1646 
1647  return 0;
1648 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:327
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static int tls_select_cipher(struct tls_connection *tls, unsigned int cipher_suite)
Select next cipher suite.
Definition: tls.c:811
#define TLS_RENEGOTIATION_INFO
Definition: tls.h:116
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define EINVAL_HELLO
Definition: tls.c:62
uint8_t type
Type.
Definition: ena.h:16
#define ENOTSUP_VERSION
Definition: tls.c:154
uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE]
MD5+SHA1 context for handshake verification.
Definition: tls.h:315
#define DBGC(...)
Definition: compiler.h:505
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
Definition: tls.h:48
uint8_t server_random[32]
Server random bytes.
Definition: tls.h:311
uint8_t session_id[32]
Session ID.
Definition: tls.h:283
#define EPROTO_VERSION
Definition: tls.c:178
#define ntohs(value)
Definition: byteswap.h:136
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
Definition: tls.h:321
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Version number.
Definition: ath9k_hw.c:1983
#define DBGC_HDA(...)
Definition: compiler.h:506
#define TLS_VERSION_TLS_1_0
TLS version 1.0.
Definition: tls.h:42
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
Definition: tls.c:295
#define DBGC_HD(...)
Definition: compiler.h:507
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:30
unsigned char uint8_t
Definition: stdint.h:10
#define EPERM_RENEG_VERIFY
Definition: tls.c:174
uint16_t ext
Extended status.
Definition: ena.h:20
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
Definition: tls.c:633
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:319
uint32_t len
Length.
Definition: ena.h:14
uint16_t version
Protocol version.
Definition: tls.h:297
int secure_renegotiation
Secure renegotiation flag.
Definition: tls.h:325
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
static void tls_generate_master_secret(struct tls_connection *tls)
Generate master secret.
Definition: tls.c:606
size_t session_id_len
Length of session ID.
Definition: tls.h:285
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#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, tls_connection::handshake_ctx, tls_connection::handshake_digest, tls_connection::handshake_md5_sha1_ctx, htons, len, md5_sha1_algorithm, memcmp(), memcpy(), next, ntohs, NULL, random(), rc, tls_connection::secure_renegotiation, tls_connection::server_random, tls_connection::session_id, tls_connection::session_id_len, tls_generate_keys(), tls_generate_master_secret(), TLS_RENEGOTIATION_INFO, tls_select_cipher(), TLS_VERSION_TLS_1_0, TLS_VERSION_TLS_1_2, 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 1658 of file tls.c.

1659  {
1660  const struct {
1662  uint16_t len;
1663  uint8_t ticket[0];
1664  } __attribute__ (( packed )) *new_session_ticket = data;
1665  size_t ticket_len;
1666 
1667  /* Parse header */
1668  if ( sizeof ( *new_session_ticket ) > len ) {
1669  DBGC ( tls, "TLS %p received underlength New Session Ticket\n",
1670  tls );
1671  DBGC_HD ( tls, data, len );
1672  return -EINVAL_TICKET;
1673  }
1674  ticket_len = ntohs ( new_session_ticket->len );
1675  if ( ticket_len > ( len - sizeof ( *new_session_ticket ) ) ) {
1676  DBGC ( tls, "TLS %p received overlength New Session Ticket\n",
1677  tls );
1678  DBGC_HD ( tls, data, len );
1679  return -EINVAL_TICKET;
1680  }
1681 
1682  /* Free any unapplied new session ticket */
1683  free ( tls->new_session_ticket );
1684  tls->new_session_ticket = NULL;
1685  tls->new_session_ticket_len = 0;
1686 
1687  /* Record ticket */
1688  tls->new_session_ticket = malloc ( ticket_len );
1689  if ( ! tls->new_session_ticket )
1690  return -ENOMEM;
1691  memcpy ( tls->new_session_ticket, new_session_ticket->ticket,
1692  ticket_len );
1693  tls->new_session_ticket_len = ticket_len;
1694  DBGC ( tls, "TLS %p new session ticket:\n", tls );
1695  DBGC_HDA ( tls, 0, tls->new_session_ticket,
1696  tls->new_session_ticket_len );
1697 
1698  return 0;
1699 }
#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:289
#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:287
#define DBGC_HDA(...)
Definition: compiler.h:506
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
Definition: wpa.h:54
unsigned int uint32_t
Definition: stdint.h:12
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
#define EINVAL_TICKET
Definition: tls.c:106
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

1710  {
1711  size_t remaining = len;
1712  int rc;
1713 
1714  /* Free any existing certificate chain */
1715  x509_chain_put ( tls->chain );
1716  tls->chain = NULL;
1717 
1718  /* Create certificate chain */
1719  tls->chain = x509_alloc_chain();
1720  if ( ! tls->chain ) {
1721  rc = -ENOMEM_CHAIN;
1722  goto err_alloc_chain;
1723  }
1724 
1725  /* Add certificates to chain */
1726  while ( remaining ) {
1727  const struct {
1728  tls24_t length;
1729  uint8_t data[0];
1730  } __attribute__ (( packed )) *certificate = data;
1731  size_t certificate_len;
1732  size_t record_len;
1733  struct x509_certificate *cert;
1734 
1735  /* Parse header */
1736  if ( sizeof ( *certificate ) > remaining ) {
1737  DBGC ( tls, "TLS %p underlength certificate:\n", tls );
1738  DBGC_HDA ( tls, 0, data, remaining );
1740  goto err_underlength;
1741  }
1742  certificate_len = tls_uint24 ( &certificate->length );
1743  if ( certificate_len > ( remaining - sizeof ( *certificate ) )){
1744  DBGC ( tls, "TLS %p overlength certificate:\n", tls );
1745  DBGC_HDA ( tls, 0, data, remaining );
1747  goto err_overlength;
1748  }
1749  record_len = ( sizeof ( *certificate ) + certificate_len );
1750 
1751  /* Add certificate to chain */
1752  if ( ( rc = x509_append_raw ( tls->chain, certificate->data,
1753  certificate_len ) ) != 0 ) {
1754  DBGC ( tls, "TLS %p could not append certificate: %s\n",
1755  tls, strerror ( rc ) );
1756  DBGC_HDA ( tls, 0, data, remaining );
1757  goto err_parse;
1758  }
1759  cert = x509_last ( tls->chain );
1760  DBGC ( tls, "TLS %p found certificate %s\n",
1761  tls, x509_name ( cert ) );
1762 
1763  /* Move to next certificate in list */
1764  data += record_len;
1765  remaining -= record_len;
1766  }
1767 
1768  return 0;
1769 
1770  err_parse:
1771  err_overlength:
1772  err_underlength:
1773  x509_chain_put ( tls->chain );
1774  tls->chain = NULL;
1775  err_alloc_chain:
1776  return rc;
1777 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
#define __attribute__(x)
Definition: compiler.h:10
uint16_t length
Length.
Definition: intel.h:14
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:330
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:219
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:1625
#define DBGC(...)
Definition: compiler.h:505
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1577
#define ENOMEM_CHAIN
Definition: tls.c:122
#define EINVAL_CERTIFICATE
Definition: tls.c:66
#define DBGC_HDA(...)
Definition: compiler.h:506
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition: x509.h:294
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:185
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:204
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

Referenced by tls_new_certificate().

◆ tls_new_certificate()

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

Receive new Certificate handshake record.

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

Definition at line 1787 of file tls.c.

1788  {
1789  const struct {
1790  tls24_t length;
1791  uint8_t certificates[0];
1792  } __attribute__ (( packed )) *certificate = data;
1793  size_t certificates_len;
1794  int rc;
1795 
1796  /* Parse header */
1797  if ( sizeof ( *certificate ) > len ) {
1798  DBGC ( tls, "TLS %p received underlength Server Certificate\n",
1799  tls );
1800  DBGC_HD ( tls, data, len );
1801  return -EINVAL_CERTIFICATES;
1802  }
1803  certificates_len = tls_uint24 ( &certificate->length );
1804  if ( certificates_len > ( len - sizeof ( *certificate ) ) ) {
1805  DBGC ( tls, "TLS %p received overlength Server Certificate\n",
1806  tls );
1807  DBGC_HD ( tls, data, len );
1808  return -EINVAL_CERTIFICATES;
1809  }
1810 
1811  /* Parse certificate chain */
1812  if ( ( rc = tls_parse_chain ( tls, certificate->certificates,
1813  certificates_len ) ) != 0 )
1814  return rc;
1815 
1816  return 0;
1817 }
#define __attribute__(x)
Definition: compiler.h:10
uint16_t length
Length.
Definition: intel.h:14
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:219
#define DBGC(...)
Definition: compiler.h:505
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
A TLS 24-bit integer.
Definition: tls.c:204
uint32_t len
Length.
Definition: ena.h:14
static int tls_parse_chain(struct tls_connection *tls, const void *data, size_t len)
Parse certificate chain.
Definition: tls.c:1709
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define EINVAL_CERTIFICATES
Definition: tls.c:70

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

Referenced by tls_new_handshake().

◆ tls_new_certificate_request()

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

Receive new Certificate Request handshake record.

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

Definition at line 1827 of file tls.c.

1829  {
1830 
1831  /* We can only send a single certificate, so there is no point
1832  * in parsing the Certificate Request.
1833  */
1834 
1835  /* Free any existing client certificate */
1836  x509_put ( tls->cert );
1837 
1838  /* Determine client certificate to be sent */
1839  tls->cert = certstore_find_key ( &private_key );
1840  if ( ! tls->cert ) {
1841  DBGC ( tls, "TLS %p could not find certificate corresponding "
1842  "to private key\n", tls );
1843  return -EPERM_CLIENT_CERT;
1844  }
1845  x509_get ( tls->cert );
1846  DBGC ( tls, "TLS %p sending client certificate %s\n",
1847  tls, x509_name ( tls->cert ) );
1848 
1849  return 0;
1850 }
#define EPERM_CLIENT_CERT
Definition: tls.c:166
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition: x509.h:236
#define DBGC(...)
Definition: compiler.h:505
struct x509_certificate * certstore_find_key(struct asn1_cursor *key)
Find certificate in store corresponding to a private key.
Definition: certstore.c:119
struct asn1_cursor private_key
Private key.
Definition: privkey.c:67
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:247
struct x509_certificate * cert
Client certificate (if used)
Definition: tls.h:323

References tls_connection::cert, certstore_find_key(), DBGC, EPERM_CLIENT_CERT, private_key, x509_get(), x509_name(), and x509_put().

Referenced by tls_new_handshake().

◆ tls_new_server_hello_done()

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

Receive new Server Hello Done handshake record.

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

Definition at line 1860 of file tls.c.

1861  {
1862  const struct {
1863  char next[0];
1864  } __attribute__ (( packed )) *hello_done = data;
1865  int rc;
1866 
1867  /* Sanity check */
1868  if ( sizeof ( *hello_done ) != len ) {
1869  DBGC ( tls, "TLS %p received overlength Server Hello Done\n",
1870  tls );
1871  DBGC_HD ( tls, data, len );
1872  return -EINVAL_HELLO_DONE;
1873  }
1874 
1875  /* Begin certificate validation */
1876  if ( ( rc = create_validator ( &tls->validator, tls->chain ) ) != 0 ) {
1877  DBGC ( tls, "TLS %p could not start certificate validation: "
1878  "%s\n", tls, strerror ( rc ) );
1879  return rc;
1880  }
1881  pending_get ( &tls->validation );
1882 
1883  return 0;
1884 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_chain * chain
Server certificate chain.
Definition: tls.h:330
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
#define EINVAL_HELLO_DONE
Definition: tls.c:74
struct pending_operation validation
Certificate validation pending operation.
Definition: tls.h:339
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC_HD(...)
Definition: compiler.h:507
uint32_t len
Length.
Definition: ena.h:14
struct interface validator
Certificate validator.
Definition: tls.h:332
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int create_validator(struct interface *job, struct x509_chain *chain)
Instantiate a certificate validator.
Definition: validator.c:626
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:45

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

Referenced by tls_new_handshake().

◆ tls_new_finished()

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

Receive new Finished handshake record.

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

Definition at line 1894 of file tls.c.

1895  {
1896  struct tls_session *session = tls->session;
1897  struct digest_algorithm *digest = tls->handshake_digest;
1898  const struct {
1899  uint8_t verify_data[ sizeof ( tls->verify.server ) ];
1900  char next[0];
1901  } __attribute__ (( packed )) *finished = data;
1902  uint8_t digest_out[ digest->digestsize ];
1903 
1904  /* Sanity check */
1905  if ( sizeof ( *finished ) != len ) {
1906  DBGC ( tls, "TLS %p received overlength Finished\n", tls );
1907  DBGC_HD ( tls, data, len );
1908  return -EINVAL_FINISHED;
1909  }
1910 
1911  /* Verify data */
1912  tls_verify_handshake ( tls, digest_out );
1913  tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
1914  tls->verify.server, sizeof ( tls->verify.server ),
1915  "server finished", digest_out, sizeof ( digest_out ) );
1916  if ( memcmp ( tls->verify.server, finished->verify_data,
1917  sizeof ( tls->verify.server ) ) != 0 ) {
1918  DBGC ( tls, "TLS %p verification failed\n", tls );
1919  return -EPERM_VERIFY;
1920  }
1921 
1922  /* Mark server as finished */
1923  pending_put ( &tls->server_negotiation );
1924 
1925  /* If we are resuming a session (i.e. if the server Finished
1926  * arrives before the client Finished is sent), then schedule
1927  * transmission of Change Cipher and Finished.
1928  */
1929  if ( is_pending ( &tls->client_negotiation ) ) {
1931  tls_tx_resume ( tls );
1932  }
1933 
1934  /* Record session ID, ticket, and master secret, if applicable */
1935  if ( tls->session_id_len || tls->new_session_ticket_len ) {
1936  memcpy ( session->master_secret, tls->master_secret,
1937  sizeof ( session->master_secret ) );
1938  }
1939  if ( tls->session_id_len ) {
1940  session->id_len = tls->session_id_len;
1941  memcpy ( session->id, tls->session_id, sizeof ( session->id ) );
1942  }
1943  if ( tls->new_session_ticket_len ) {
1944  free ( session->ticket );
1945  session->ticket = tls->new_session_ticket;
1946  session->ticket_len = tls->new_session_ticket_len;
1947  tls->new_session_ticket = NULL;
1948  tls->new_session_ticket_len = 0;
1949  }
1950 
1951  /* Move to end of session's connection list and allow other
1952  * connections to start making progress.
1953  */
1954  list_del ( &tls->list );
1955  list_add_tail ( &tls->list, &session->conn );
1957 
1958  /* Send notification of a window change */
1959  xfer_window_changed ( &tls->plainstream );
1960 
1961  return 0;
1962 }
struct tls_verify_data verify
Verification data.
Definition: tls.h:327
#define __attribute__(x)
Definition: compiler.h:10
static void tls_tx_resume_all(struct tls_session *session)
Resume TX state machine for all connections within a session.
Definition: tls.c:957
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:145
struct pending_operation client_negotiation
Client security negotiation pending operation.
Definition: tls.h:335
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
Definition: tls.c:948
struct tls_session * session
Session.
Definition: tls.h:279
uint32_t next
Next descriptor address.
Definition: myson.h:18
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
Definition: tls.c:928
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:58
#define DBGC(...)
Definition: compiler.h:505
size_t new_session_ticket_len
Length of new session ticket.
Definition: tls.h:289
uint8_t session_id[32]
Session ID.
Definition: tls.h:283
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct ntlm_data session
Session key.
Definition: ntlm.h:24
void * new_session_ticket
New session ticket.
Definition: tls.h:287
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define EINVAL_FINISHED
Definition: tls.c:78
struct list_head list
List of connections within the same session.
Definition: tls.h:281
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
Definition: pending.h:24
#define EPERM_VERIFY
Definition: tls.c:162
uint8_t master_secret[48]
Master secret.
Definition: tls.h:309
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
struct pending_operation server_negotiation
Server security negotiation pending operation.
Definition: tls.h:337
unsigned int tx_pending
TX pending transmissions.
Definition: tls.h:344
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
Definition: tls.h:319
uint32_t len
Length.
Definition: ena.h:14
A TLS session.
Definition: tls.h:250
A message digest algorithm.
Definition: crypto.h:16
uint8_t server[12]
Server verification data.
Definition: tls.h:123
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
size_t session_id_len
Length of session ID.
Definition: tls.h:285
struct interface plainstream
Plaintext stream.
Definition: tls.h:292
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
Definition: tls.c:587

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

Referenced by tls_new_handshake().

◆ tls_new_handshake()

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

Receive new Handshake record.

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

Definition at line 1972 of file tls.c.

1973  {
1974  size_t remaining = len;
1975  int rc;
1976 
1977  while ( remaining ) {
1978  const struct {
1979  uint8_t type;
1980  tls24_t length;
1981  uint8_t payload[0];
1982  } __attribute__ (( packed )) *handshake = data;
1983  const void *payload;
1984  size_t payload_len;
1985  size_t record_len;
1986 
1987  /* Parse header */
1988  if ( sizeof ( *handshake ) > remaining ) {
1989  DBGC ( tls, "TLS %p received underlength Handshake\n",
1990  tls );
1991  DBGC_HD ( tls, data, remaining );
1992  return -EINVAL_HANDSHAKE;
1993  }
1994  payload_len = tls_uint24 ( &handshake->length );
1995  if ( payload_len > ( remaining - sizeof ( *handshake ) ) ) {
1996  DBGC ( tls, "TLS %p received overlength Handshake\n",
1997  tls );
1998  DBGC_HD ( tls, data, len );
1999  return -EINVAL_HANDSHAKE;
2000  }
2001  payload = &handshake->payload;
2002  record_len = ( sizeof ( *handshake ) + payload_len );
2003 
2004  /* Handle payload */
2005  switch ( handshake->type ) {
2006  case TLS_HELLO_REQUEST:
2007  rc = tls_new_hello_request ( tls, payload,
2008  payload_len );
2009  break;
2010  case TLS_SERVER_HELLO:
2011  rc = tls_new_server_hello ( tls, payload, payload_len );
2012  break;
2014  rc = tls_new_session_ticket ( tls, payload,
2015  payload_len );
2016  break;
2017  case TLS_CERTIFICATE:
2018  rc = tls_new_certificate ( tls, payload, payload_len );
2019  break;
2021  rc = tls_new_certificate_request ( tls, payload,
2022  payload_len );
2023  break;
2024  case TLS_SERVER_HELLO_DONE:
2025  rc = tls_new_server_hello_done ( tls, payload,
2026  payload_len );
2027  break;
2028  case TLS_FINISHED:
2029  rc = tls_new_finished ( tls, payload, payload_len );
2030  break;
2031  default:
2032  DBGC ( tls, "TLS %p ignoring handshake type %d\n",
2033  tls, handshake->type );
2034  rc = 0;
2035  break;
2036  }
2037 
2038  /* Add to handshake digest (except for Hello Requests,
2039  * which are explicitly excluded).
2040  */
2041  if ( handshake->type != TLS_HELLO_REQUEST )
2042  tls_add_handshake ( tls, data, record_len );
2043 
2044  /* Abort on failure */
2045  if ( rc != 0 )
2046  return rc;
2047 
2048  /* Move to next handshake record */
2049  data += record_len;
2050  remaining -= record_len;
2051  }
2052 
2053  return 0;
2054 }
#define __attribute__(x)
Definition: compiler.h:10
uint16_t length
Length.
Definition: intel.h:14
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
Definition: tls.c:219
uint8_t type
Type.
Definition: ena.h:16
#define DBGC(...)
Definition: compiler.h:505
#define TLS_CERTIFICATE
Definition: tls.h:67
#define EINVAL_HANDSHAKE
Definition: tls.c:82
#define TLS_SERVER_HELLO_DONE
Definition: tls.h:70
#define TLS_CERTIFICATE_REQUEST
Definition: tls.h:69
static int tls_new_hello_request(struct tls_connection *tls, const void *data __unused, size_t len __unused)
Receive new Hello Request handshake record.
Definition: tls.c:1433
static int tls_new_session_ticket(struct tls_connection *tls, const void *data, size_t len)
Receive New Session Ticket handshake record.
Definition: tls.c:1658
#define TLS_HELLO_REQUEST
Definition: tls.h:63
static int tls_new_finished(struct tls_connection *tls, const void *data, size_t len)
Receive new Finished handshake record.
Definition: tls.c:1894
static int tls_new_server_hello(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Hello handshake record.
Definition: tls.c:1464
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
static int tls_new_certificate_request(struct tls_connection *tls, const void *data __unused, size_t len __unused)
Receive new Certificate Request handshake record.
Definition: tls.c:1827
#define TLS_NEW_SESSION_TICKET
Definition: tls.h:66
A TLS 24-bit integer.
Definition: tls.c:204
uint32_t len
Length.
Definition: ena.h:14
static void tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
Definition: tls.c:910
static int tls_new_certificate(struct tls_connection *tls, const void *data, size_t len)
Receive new Certificate handshake record.
Definition: tls.c:1787
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define TLS_SERVER_HELLO
Definition: tls.h:65
static int tls_new_server_hello_done(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Hello Done handshake record.
Definition: tls.c:1860
#define TLS_FINISHED
Definition: tls.h:73

References __attribute__, data, DBGC, DBGC_HD, EINVAL_HANDSHAKE, len, length, rc, tls_add_handshake(), TLS_CERTIFICATE, TLS_CERTIFICATE_REQUEST, TLS_FINISHED, TLS_HELLO_REQUEST, tls_new_certificate(), tls_new_certificate_request(), tls_new_finished(), tls_new_hello_request(), tls_new_server_hello(), tls_new_server_hello_done(), TLS_NEW_SESSION_TICKET, tls_new_session_ticket(), TLS_SERVER_HELLO, TLS_SERVER_HELLO_DONE, tls_uint24(), and type.

Referenced by tls_new_record().

◆ tls_new_record()

static int tls_new_record ( struct tls_connection tls,
unsigned int  type,
struct list_head rx_data 
)
static

Receive new record.

Parameters
tlsTLS connection
typeRecord type
rx_dataList of received data buffers
Return values
rcReturn status code

Definition at line 2064 of file tls.c.

2065  {
2066  struct io_buffer *iobuf;
2067  int ( * handler ) ( struct tls_connection *tls, const void *data,
2068  size_t len );
2069  int rc;
2070 
2071  /* Deliver data records to the plainstream interface */
2072  if ( type == TLS_TYPE_DATA ) {
2073 
2074  /* Fail unless we are ready to receive data */
2075  if ( ! tls_ready ( tls ) )
2076  return -ENOTCONN;
2077 
2078  /* Deliver each I/O buffer in turn */
2079  while ( ( iobuf = list_first_entry ( rx_data, struct io_buffer,
2080  list ) ) ) {
2081  list_del ( &iobuf->list );
2082  if ( ( rc = xfer_deliver_iob ( &tls->plainstream,
2083  iobuf ) ) != 0 ) {
2084  DBGC ( tls, "TLS %p could not deliver data: "
2085  "%s\n", tls, strerror ( rc ) );
2086  return rc;
2087  }
2088  }
2089  return 0;
2090  }
2091 
2092  /* For all other records, merge into a single I/O buffer */
2093  iobuf = iob_concatenate ( rx_data );
2094  if ( ! iobuf ) {
2095  DBGC ( tls, "TLS %p could not concatenate non-data record "
2096  "type %d\n", tls, type );
2097  return -ENOMEM_RX_CONCAT;
2098  }
2099 
2100  /* Determine handler */
2101  switch ( type ) {
2103  handler = tls_new_change_cipher;
2104  break;
2105  case TLS_TYPE_ALERT:
2106  handler = tls_new_alert;
2107  break;
2108  case TLS_TYPE_HANDSHAKE:
2109  handler = tls_new_handshake;
2110  break;
2111  default:
2112  /* RFC4346 says that we should just ignore unknown
2113  * record types.
2114  */
2115  handler = NULL;
2116  DBGC ( tls, "TLS %p ignoring record type %d\n", tls, type );
2117  break;
2118  }
2119 
2120  /* Handle record and free I/O buffer */
2121  rc = ( handler ? handler ( tls, iobuf->data, iob_len ( iobuf ) ) : 0 );
2122  free_iob ( iobuf );
2123  return rc;
2124 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:254
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
uint8_t type
Type.
Definition: ena.h:16
#define DBGC(...)
Definition: compiler.h:505
#define ENOMEM_RX_CONCAT
Definition: tls.c:138
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
Definition: tls.h:51
struct list_head list
List of connections within the same session.
Definition: tls.h:281
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
Definition: iobuf.c:198
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:151
#define TLS_TYPE_HANDSHAKE
Handshake content type.
Definition: tls.h:57
struct list_head rx_data
List of received data buffers.
Definition: tls.h:357
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:44
A TLS connection.
Definition: tls.h:274
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
static int tls_new_handshake(struct tls_connection *tls, const void *data, size_t len)
Receive new Handshake record.
Definition: tls.c:1972
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
Definition: tls.c:242
#define TLS_TYPE_DATA
Application data content type.
Definition: tls.h:60
#define TLS_TYPE_ALERT
Alert content type.
Definition: tls.h:54
struct interface plainstream
Plaintext stream.
Definition: tls.h:292
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static int tls_new_change_cipher(struct tls_connection *tls, const void *data, size_t len)
Receive new Change Cipher record.
Definition: tls.c:1365
static int tls_new_alert(struct tls_connection *tls, const void *data, size_t len)
Receive new Alert record.
Definition: tls.c:1394
A persistent I/O buffer.
Definition: iobuf.h:32

References data, io_buffer::data, DBGC, ENOMEM_RX_CONCAT, ENOTCONN, free_iob(), iob_concatenate(), iob_len(), len, io_buffer::list, tls_connection::list, list_del, list_first_entry, NULL, tls_connection::plainstream, rc, tls_connection::rx_data, strerror(), tls_new_alert(), tls_new_change_cipher(), tls_new_handshake(), tls_ready(), TLS_TYPE_ALERT, TLS_TYPE_CHANGE_CIPHER, TLS_TYPE_DATA, TLS_TYPE_HANDSHAKE, type, and xfer_deliver_iob().

Referenced by tls_new_ciphertext().

◆ tls_hmac_init()

static void tls_hmac_init ( struct tls_cipherspec cipherspec,
void *  ctx,
uint64_t  seq,
struct tls_header tlshdr 
)
static

Initialise HMAC.

Parameters
cipherspecCipher specification
ctxContext
seqSequence number
tlshdrTLS header

Definition at line 2141 of file tls.c.

2142  {
2143  struct digest_algorithm *digest = cipherspec->suite->digest;
2144 
2145  hmac_init ( digest, ctx, cipherspec->mac_secret, &digest->digestsize );
2146  seq = cpu_to_be64 ( seq );
2147  hmac_update ( digest, ctx, &seq, sizeof ( seq ) );
2148  hmac_update ( digest, ctx, tlshdr, sizeof ( *tlshdr ) );
2149 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
u16 seq
802.11 Sequence Control field
Definition: ieee80211.h:19
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
void hmac_init(struct digest_algorithm *digest, void *digest_ctx, void *key, size_t *key_len)
Initialise HMAC.
Definition: hmac.c:80
A message digest algorithm.
Definition: crypto.h:16
#define cpu_to_be64(value)
Definition: byteswap.h:111
static void hmac_update(struct digest_algorithm *digest, void *digest_ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:21
void * mac_secret
MAC secret.
Definition: tls.h:177

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

Referenced by tls_hmac(), and tls_new_ciphertext().

◆ tls_hmac_update()

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

Update HMAC.

Parameters
cipherspecCipher specification
ctxContext
dataData
lenLength of data

Definition at line 2159 of file tls.c.

2160  {
2161  struct digest_algorithm *digest = cipherspec->suite->digest;
2162 
2163  hmac_update ( digest, ctx, data, len );
2164 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
uint32_t len
Length.
Definition: ena.h:14
A message digest algorithm.
Definition: crypto.h:16
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
static void hmac_update(struct digest_algorithm *digest, void *digest_ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:21

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

Referenced by tls_hmac(), and tls_new_ciphertext().

◆ tls_hmac_final()

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

Finalise HMAC.

Parameters
cipherspecCipher specification
ctxContext
macHMAC to fill in

Definition at line 2173 of file tls.c.

2174  {
2175  struct digest_algorithm *digest = cipherspec->suite->digest;
2176 
2177  hmac_final ( digest, ctx, cipherspec->mac_secret,
2178  &digest->digestsize, hmac );
2179 }
void hmac_final(struct digest_algorithm *digest, void *digest_ctx, void *key, size_t *key_len, void *hmac)
Finalise HMAC.
Definition: hmac.c:115
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
A message digest algorithm.
Definition: crypto.h:16
void * mac_secret
MAC secret.
Definition: tls.h:177

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

Referenced by tls_hmac(), and tls_new_ciphertext().

◆ tls_hmac()

static void tls_hmac ( struct tls_cipherspec cipherspec,
uint64_t  seq,
struct tls_header tlshdr,
const void *  data,
size_t  len,
void *  hmac 
)
static

Calculate HMAC.

Parameters
cipherspecCipher specification
seqSequence number
tlshdrTLS header
dataData
lenLength of data
macHMAC to fill in

Definition at line 2191 of file tls.c.

2193  {
2194  struct digest_algorithm *digest = cipherspec->suite->digest;
2195  uint8_t ctx[digest->ctxsize];
2196 
2197  tls_hmac_init ( cipherspec, ctx, seq, tlshdr );
2198  tls_hmac_update ( cipherspec, ctx, data, len );
2199  tls_hmac_final ( cipherspec, ctx, hmac );
2200 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition: tls.c:2173
u16 seq
802.11 Sequence Control field
Definition: ieee80211.h:19
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2159
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
unsigned char uint8_t
Definition: stdint.h:10
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, uint64_t seq, struct tls_header *tlshdr)
Initialise HMAC.
Definition: tls.c:2141
uint32_t len
Length.
Definition: ena.h:14
A message digest algorithm.
Definition: crypto.h:16
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

Referenced by tls_send_plaintext().

◆ tls_assemble_stream()

static void* __malloc tls_assemble_stream ( struct tls_connection tls,
const void *  data,
size_t  len,
void *  digest,
size_t plaintext_len 
)
static

Allocate and assemble stream-ciphered record from data and MAC portions.

Parameters
tlsTLS connection
Return values
dataData
lenLength of data
digestMAC digest
plaintext_lenLength of plaintext record
plaintextAllocated plaintext record

Definition at line 2213 of file tls.c.

2214  {
2215  size_t mac_len = tls->tx_cipherspec.suite->digest->digestsize;
2216  void *plaintext;
2217  void *content;
2218  void *mac;
2219 
2220  /* Calculate stream-ciphered struct length */
2221  *plaintext_len = ( len + mac_len );
2222 
2223  /* Allocate stream-ciphered struct */
2224  plaintext = malloc ( *plaintext_len );
2225  if ( ! plaintext )
2226  return NULL;
2227  content = plaintext;
2228  mac = ( content + len );
2229 
2230  /* Fill in stream-ciphered struct */
2231  memcpy ( content, data, len );
2232  memcpy ( mac, digest, mac_len );
2233 
2234  return plaintext;
2235 }
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:299
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
size_t digestsize
Digest size.
Definition: crypto.h:24
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References data, digest, tls_cipher_suite::digest, digest_algorithm::digestsize, len, mac, malloc(), memcpy(), NULL, tls_cipherspec::suite, and tls_connection::tx_cipherspec.

Referenced by tls_send_plaintext().

◆ tls_assemble_block()

static void* tls_assemble_block ( struct tls_connection tls,
const void *  data,
size_t  len,
void *  digest,
size_t plaintext_len 
)
static

Allocate and assemble block-ciphered record from data and MAC portions.

Parameters
tlsTLS connection
Return values
dataData
lenLength of data
digestMAC digest
plaintext_lenLength of plaintext record
plaintextAllocated plaintext record

Definition at line 2247 of file tls.c.

2249  {
2250  size_t blocksize = tls->tx_cipherspec.suite->cipher->blocksize;
2251  size_t mac_len = tls->tx_cipherspec.suite->digest->digestsize;
2252  size_t iv_len;
2253  size_t padding_len;
2254  void *plaintext;
2255  void *iv;
2256  void *content;
2257  void *mac;
2258  void *padding;
2259 
2260  /* TLSv1.1 and later use an explicit IV */
2261  iv_len = ( ( tls->version >= TLS_VERSION_TLS_1_1 ) ? blocksize : 0 );
2262 
2263  /* Calculate block-ciphered struct length */
2264  padding_len = ( ( blocksize - 1 ) & -( iv_len + len + mac_len + 1 ) );
2265  *plaintext_len = ( iv_len + len + mac_len + padding_len + 1 );
2266 
2267  /* Allocate block-ciphered struct */
2268  plaintext = malloc ( *plaintext_len );
2269  if ( ! plaintext )
2270  return NULL;
2271  iv = plaintext;
2272  content = ( iv + iv_len );
2273  mac = ( content + len );
2274  padding = ( mac + mac_len );
2275 
2276  /* Fill in block-ciphered struct */
2277  tls_generate_random ( tls, iv, iv_len );
2278  memcpy ( content, data, len );
2279  memcpy ( mac, digest, mac_len );
2280  memset ( padding, padding_len, ( padding_len + 1 ) );
2281 
2282  return plaintext;
2283 }
size_t blocksize
Block size.
Definition: crypto.h:54
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
#define TLS_VERSION_TLS_1_1
TLS version 1.1.
Definition: tls.h:45
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
size_t blocksize
Block size.
Definition: crypto.h:22
struct tls_cipherspec tx_cipherspec
Current TX cipher specification.
Definition: tls.h:299
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
size_t digestsize
Digest size.
Definition: crypto.h:24
uint16_t version
Protocol version.
Definition: tls.h:297
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:147
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
Definition: tls.c:418
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
void * memset(void *dest, int character, size_t len) __nonnull

References digest_algorithm::blocksize, cipher_algorithm::blocksize, tls_cipher_suite::cipher, data, digest, tls_cipher_suite::digest, digest_algorithm::digestsize, iv, len, mac, malloc(), memcpy(), memset(), NULL, tls_cipherspec::suite, tls_generate_random(), TLS_VERSION_TLS_1_1, tls_connection::tx_cipherspec, and tls_connection::version.

Referenced by tls_send_plaintext().

◆ tls_split_stream()

static int tls_split_stream ( struct tls_connection tls,
struct list_head rx_data,
void **  mac 
)
static

Split stream-ciphered record into data and MAC portions.

Parameters
tlsTLS connection
rx_dataList of received data buffers
macMAC to fill in
Return values
rcReturn status code

Definition at line 2385 of file tls.c.

2386  {
2387  size_t mac_len = tls->rx_cipherspec.suite->digest->digestsize;
2388  struct io_buffer *iobuf;
2389 
2390  /* Extract MAC */
2391  iobuf = list_last_entry ( rx_data, struct io_buffer, list );
2392  assert ( iobuf != NULL );
2393  if ( iob_len ( iobuf ) < mac_len ) {
2394  DBGC ( tls, "TLS %p received underlength MAC\n", tls );
2395  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
2396  return -EINVAL_STREAM;
2397  }
2398  iob_unput ( iobuf, mac_len );
2399  *mac = iobuf->tail;
2400 
2401  return 0;
2402 }
#define DBGC(...)
Definition: compiler.h:505
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:346
void * tail
End of data.
Definition: iobuf.h:46
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
#define iob_unput(iobuf, len)
Definition: iobuf.h:131
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
#define DBGC_HD(...)
Definition: compiler.h:507
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:303
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
size_t digestsize
Digest size.
Definition: crypto.h:24
void * data
Start of data.
Definition: iobuf.h:44
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define EINVAL_STREAM
Definition: tls.c:86
A persistent I/O buffer.
Definition: iobuf.h:32

References assert(), io_buffer::data, DBGC, DBGC_HD, tls_cipher_suite::digest, digest_algorithm::digestsize, EINVAL_STREAM, iob_len(), iob_unput, io_buffer::list, list_last_entry, mac, NULL, tls_connection::rx_cipherspec, tls_cipherspec::suite, and io_buffer::tail.

Referenced by tls_new_ciphertext().

◆ tls_split_block()

static int tls_split_block ( struct tls_connection tls,
struct list_head rx_data,
void **  mac 
)
static

Split block-ciphered record into data and MAC portions.

Parameters
tlsTLS connection
rx_dataList of received data buffers
macMAC to fill in
Return values
rcReturn status code

Definition at line 2412 of file tls.c.

2413  {
2414  size_t mac_len = tls->rx_cipherspec.suite->digest->digestsize;
2415  struct io_buffer *iobuf;
2416  size_t iv_len;
2417  uint8_t *padding_final;
2418  uint8_t *padding;
2419  size_t padding_len;
2420 
2421  /* TLSv1.1 and later use an explicit IV */
2422  iobuf = list_first_entry ( rx_data, struct io_buffer, list );
2423  iv_len = ( ( tls->version >= TLS_VERSION_TLS_1_1 ) ?
2424  tls->rx_cipherspec.suite->cipher->blocksize : 0 );
2425  if ( iob_len ( iobuf ) < iv_len ) {
2426  DBGC ( tls, "TLS %p received underlength IV\n", tls );
2427  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
2428  return -EINVAL_BLOCK;
2429  }
2430  iob_pull ( iobuf, iv_len );
2431 
2432  /* Extract and verify padding */
2433  iobuf = list_last_entry ( rx_data, struct io_buffer, list );
2434  padding_final = ( iobuf->tail - 1 );
2435  padding_len = *padding_final;
2436  if ( ( padding_len + 1 ) > iob_len ( iobuf ) ) {
2437  DBGC ( tls, "TLS %p received underlength padding\n", tls );
2438  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
2439  return -EINVAL_BLOCK;
2440  }
2441  iob_unput ( iobuf, ( padding_len + 1 ) );
2442  for ( padding = iobuf->tail ; padding < padding_final ; padding++ ) {
2443  if ( *padding != padding_len ) {
2444  DBGC ( tls, "TLS %p received bad padding\n", tls );
2445  DBGC_HD ( tls, padding, padding_len );
2446  return -EINVAL_PADDING;
2447  }
2448  }
2449 
2450  /* Extract MAC */
2451  if ( iob_len ( iobuf ) < mac_len ) {
2452  DBGC ( tls, "TLS %p received underlength MAC\n", tls );
2453  DBGC_HD ( tls, iobuf->data, iob_len ( iobuf ) );
2454  return -EINVAL_BLOCK;
2455  }
2456  iob_unput ( iobuf, mac_len );
2457  *mac = iobuf->tail;
2458 
2459  return 0;
2460 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:98
size_t blocksize
Block size.
Definition: crypto.h:54
#define EINVAL_PADDING
Definition: tls.c:94
#define DBGC(...)
Definition: compiler.h:505
#define EINVAL_BLOCK
Definition: tls.c:90
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:346
#define TLS_VERSION_TLS_1_1
TLS version 1.1.
Definition: tls.h:45
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
void * tail
End of data.
Definition: iobuf.h:46
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
#define iob_unput(iobuf, len)
Definition: iobuf.h:131
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
#define DBGC_HD(...)
Definition: compiler.h:507
unsigned char uint8_t
Definition: stdint.h:10
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:303
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
size_t digestsize
Digest size.
Definition: crypto.h:24
void * data
Start of data.
Definition: iobuf.h:44
uint16_t version
Protocol version.
Definition: tls.h:297
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
Definition: tls.h:147
A persistent I/O buffer.
Definition: iobuf.h:32

References cipher_algorithm::blocksize, tls_cipher_suite::cipher, io_buffer::data, DBGC, DBGC_HD, tls_cipher_suite::digest, digest_algorithm::digestsize, EINVAL_BLOCK, EINVAL_PADDING, iob_len(), iob_pull, iob_unput, io_buffer::list, list_first_entry, list_last_entry, mac, tls_connection::rx_cipherspec, tls_cipherspec::suite, io_buffer::tail, TLS_VERSION_TLS_1_1, and tls_connection::version.

Referenced by tls_new_ciphertext().

◆ tls_new_ciphertext()

static int tls_new_ciphertext ( struct tls_connection tls,
struct tls_header tlshdr,
struct list_head rx_data 
)
static

Receive new ciphertext record.

Parameters
tlsTLS connection
tlshdrRecord header
rx_dataList of received data buffers
Return values
rcReturn status code

Definition at line 2470 of file tls.c.

2472  {
2473  struct tls_header plaintext_tlshdr;
2474  struct tls_cipherspec *cipherspec = &tls->rx_cipherspec;
2475  struct cipher_algorithm *cipher = cipherspec->suite->cipher;
2476  struct digest_algorithm *digest = cipherspec->suite->digest;
2477  uint8_t ctx[digest->ctxsize];
2478  uint8_t verify_mac[digest->digestsize];
2479  struct io_buffer *iobuf;
2480  void *mac;
2481  size_t len = 0;
2482  int rc;
2483 
2484  /* Decrypt the received data */
2485  list_for_each_entry ( iobuf, &tls->rx_data, list ) {
2486  cipher_decrypt ( cipher, cipherspec->cipher_ctx,
2487  iobuf->data, iobuf->data, iob_len ( iobuf ) );
2488  }
2489 
2490  /* Split record into content and MAC */
2491  if ( is_stream_cipher ( cipher ) ) {
2492  if ( ( rc = tls_split_stream ( tls, rx_data, &mac ) ) != 0 )
2493  return rc;
2494  } else {
2495  if ( ( rc = tls_split_block ( tls, rx_data, &mac ) ) != 0 )
2496  return rc;
2497  }
2498 
2499  /* Calculate total length */
2500  DBGC2 ( tls, "Received plaintext data:\n" );
2501  list_for_each_entry ( iobuf, rx_data, list ) {
2502  DBGC2_HD ( tls, iobuf->data, iob_len ( iobuf ) );
2503  len += iob_len ( iobuf );
2504  }
2505 
2506  /* Verify MAC */
2507  plaintext_tlshdr.type = tlshdr->type;
2508  plaintext_tlshdr.version = tlshdr->version;
2509  plaintext_tlshdr.length = htons ( len );
2510  tls_hmac_init ( cipherspec, ctx, tls->rx_seq, &plaintext_tlshdr );
2511  list_for_each_entry ( iobuf, rx_data, list ) {
2512  tls_hmac_update ( cipherspec, ctx, iobuf->data,
2513  iob_len ( iobuf ) );
2514  }
2515  tls_hmac_final ( cipherspec, ctx, verify_mac );
2516  if ( memcmp ( mac, verify_mac, sizeof ( verify_mac ) ) != 0 ) {
2517  DBGC ( tls, "TLS %p failed MAC verification\n", tls );
2518  return -EINVAL_MAC;
2519  }
2520 
2521  /* Process plaintext record */
2522  if ( ( rc = tls_new_record ( tls, tlshdr->type, rx_data ) ) != 0 )
2523  return rc;
2524 
2525  return 0;
2526 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint64_t rx_seq
RX sequence number.
Definition: tls.h:349
uint8_t type
Content type.
Definition: tls.h:31
#define DBGC(...)
Definition: compiler.h:505
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
A TLS cipher specification.
Definition: tls.h:165
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
Definition: tls.c:2173
#define EINVAL_MAC
Definition: tls.c:102
void * cipher_ctx
Bulk encryption cipher context.
Definition: tls.h:173
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct tls_cipher_suite * suite
Cipher suite.
Definition: tls.h:167
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
Definition: tls.c:2159
struct digest_algorithm * digest
MAC digest algorithm.
Definition: tls.h:149
#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:151
unsigned char uint8_t
Definition: stdint.h:10
static int is_stream_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:217
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:212
struct tls_cipherspec rx_cipherspec
Current RX cipher specification.
Definition: tls.h:303
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, uint64_t seq, struct tls_header *tlshdr)
Initialise HMAC.
Definition: tls.c:2141
static int tls_split_block(struct tls_connection *tls, struct list_head *rx_data, void **mac)
Split block-ciphered record into data and MAC portions.
Definition: tls.c:2412
A TLS header.
Definition: tls.h:26
struct list_head rx_data
List of received data buffers.
Definition: tls.h:357
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:44
static int tls_split_stream(struct tls_connection *tls, struct list_head *rx_data, void **mac)
Split stream-ciphered record into data and MAC portions.
Definition: tls.c:2385
uint16_t version
Protocol version.
Definition: tls.h:36
A message digest algorithm.
Definition: crypto.h:16
A cipher algorithm.
Definition: crypto.h:48
static int tls_new_record(struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
Receive new record.
Definition: tls.c:2064