176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef _GPXE_TLS_H
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define _GPXE_TLS_H
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @file
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Transport Layer Security Protocol
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER );
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdint.h>
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/refcnt.h>
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/filter.h>
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/process.h>
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/crypto.h>
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/md5.h>
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/sha1.h>
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/x509.h>
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** A TLS header */
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct tls_header {
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Content type
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is a TLS_TYPE_XXX constant
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t type;
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Protocol version
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * This is a TLS_VERSION_XXX constant
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t version;
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Length of payload */
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t length;
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} __attribute__ (( packed ));
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** TLS version 1.0 */
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_VERSION_TLS_1_0 0x0301
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** TLS version 1.1 */
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_VERSION_TLS_1_1 0x0302
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Change cipher content type */
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_TYPE_CHANGE_CIPHER 20
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Alert content type */
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_TYPE_ALERT 21
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Handshake content type */
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_TYPE_HANDSHAKE 22
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Application data content type */
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_TYPE_DATA 23
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Handshake message types */
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_HELLO_REQUEST 0
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_CLIENT_HELLO 1
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_SERVER_HELLO 2
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_CERTIFICATE 11
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_SERVER_KEY_EXCHANGE 12
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_CERTIFICATE_REQUEST 13
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_SERVER_HELLO_DONE 14
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_CERTIFICATE_VERIFY 15
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_CLIENT_KEY_EXCHANGE 16
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_FINISHED 20
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* TLS alert levels */
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_ALERT_WARNING 1
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_ALERT_FATAL 2
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* TLS cipher specifications */
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_RSA_WITH_NULL_MD5 0x0001
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_RSA_WITH_NULL_SHA 0x0002
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002f
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** TLS RX state machine state */
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum tls_rx_state {
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	TLS_RX_HEADER = 0,
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	TLS_RX_DATA,
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** TLS TX state machine state */
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum tls_tx_state {
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	TLS_TX_NONE = 0,
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	TLS_TX_CLIENT_HELLO,
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	TLS_TX_CLIENT_KEY_EXCHANGE,
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	TLS_TX_CHANGE_CIPHER,
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	TLS_TX_FINISHED,
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	TLS_TX_DATA
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** A TLS cipher specification */
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct tls_cipherspec {
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Public-key encryption algorithm */
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct pubkey_algorithm *pubkey;
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Bulk encryption cipher algorithm */
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct cipher_algorithm *cipher;
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** MAC digest algorithm */
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct digest_algorithm *digest;
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Key length */
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t key_len;
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Dynamically-allocated storage */
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void *dynamic;
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Public key encryption context */
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void *pubkey_ctx;
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Bulk encryption cipher context */
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void *cipher_ctx;
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Next bulk encryption cipher context (TX only) */
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void *cipher_next_ctx;
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** MAC secret */
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void *mac_secret;
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** TLS pre-master secret */
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct tls_pre_master_secret {
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** TLS version */
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint16_t version;
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Random data */
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t random[46];
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} __attribute__ (( packed ));
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** TLS client random data */
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct tls_client_random {
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** GMT Unix time */
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint32_t gmt_unix_time;
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Random data */
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t random[28];
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} __attribute__ (( packed ));
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** A TLS session */
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct tls_session {
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Reference counter */
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct refcnt refcnt;
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Plaintext stream */
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct xfer_filter_half plainstream;
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Ciphertext stream */
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct xfer_filter_half cipherstream;
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Current TX cipher specification */
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct tls_cipherspec tx_cipherspec;
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Next TX cipher specification */
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct tls_cipherspec tx_cipherspec_pending;
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Current RX cipher specification */
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct tls_cipherspec rx_cipherspec;
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Next RX cipher specification */
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct tls_cipherspec rx_cipherspec_pending;
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Premaster secret */
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct tls_pre_master_secret pre_master_secret;
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Master secret */
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t master_secret[48];
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Server random bytes */
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t server_random[32];
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Client random bytes */
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct tls_client_random client_random;
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** MD5 context for handshake verification */
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t handshake_md5_ctx[MD5_CTX_SIZE];
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** SHA1 context for handshake verification */
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint8_t handshake_sha1_ctx[SHA1_CTX_SIZE];
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Hack: server RSA public key */
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct x509_rsa_public_key rsa;
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** TX sequence number */
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint64_t tx_seq;
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** TX state */
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	enum tls_tx_state tx_state;
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** TX process */
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct process process;
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** RX sequence number */
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	uint64_t rx_seq;
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** RX state */
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	enum tls_rx_state rx_state;
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Offset within current RX state */
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t rx_rcvd;
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Current received record header */
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	struct tls_header rx_header;
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/** Current received raw data buffer */
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	void *rx_data;
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman};
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int add_tls ( struct xfer_interface *xfer,
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		     struct xfer_interface **next );
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* _GPXE_TLS_H */
188