123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- #ifndef _IPXE_TLS_H
- #define _IPXE_TLS_H
-
- /**
- * @file
- *
- * Transport Layer Security Protocol
- */
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- #include <stdint.h>
- #include <ipxe/refcnt.h>
- #include <ipxe/interface.h>
- #include <ipxe/process.h>
- #include <ipxe/crypto.h>
- #include <ipxe/md5.h>
- #include <ipxe/sha1.h>
- #include <ipxe/sha256.h>
- #include <ipxe/x509.h>
- #include <ipxe/pending.h>
- #include <ipxe/iobuf.h>
- #include <ipxe/tables.h>
-
- /** A TLS header */
- struct tls_header {
- /** Content type
- *
- * This is a TLS_TYPE_XXX constant
- */
- uint8_t type;
- /** Protocol version
- *
- * This is a TLS_VERSION_XXX constant
- */
- uint16_t version;
- /** Length of payload */
- uint16_t length;
- } __attribute__ (( packed ));
-
- /** TLS version 1.0 */
- #define TLS_VERSION_TLS_1_0 0x0301
-
- /** TLS version 1.1 */
- #define TLS_VERSION_TLS_1_1 0x0302
-
- /** TLS version 1.2 */
- #define TLS_VERSION_TLS_1_2 0x0303
-
- /** Change cipher content type */
- #define TLS_TYPE_CHANGE_CIPHER 20
-
- /** Alert content type */
- #define TLS_TYPE_ALERT 21
-
- /** Handshake content type */
- #define TLS_TYPE_HANDSHAKE 22
-
- /** Application data content type */
- #define TLS_TYPE_DATA 23
-
- /* Handshake message types */
- #define TLS_HELLO_REQUEST 0
- #define TLS_CLIENT_HELLO 1
- #define TLS_SERVER_HELLO 2
- #define TLS_NEW_SESSION_TICKET 4
- #define TLS_CERTIFICATE 11
- #define TLS_SERVER_KEY_EXCHANGE 12
- #define TLS_CERTIFICATE_REQUEST 13
- #define TLS_SERVER_HELLO_DONE 14
- #define TLS_CERTIFICATE_VERIFY 15
- #define TLS_CLIENT_KEY_EXCHANGE 16
- #define TLS_FINISHED 20
-
- /* TLS alert levels */
- #define TLS_ALERT_WARNING 1
- #define TLS_ALERT_FATAL 2
-
- /* TLS cipher specifications */
- #define TLS_RSA_WITH_NULL_MD5 0x0001
- #define TLS_RSA_WITH_NULL_SHA 0x0002
- #define TLS_RSA_WITH_AES_128_CBC_SHA 0x002f
- #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
- #define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003c
- #define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003d
-
- /* TLS hash algorithm identifiers */
- #define TLS_MD5_ALGORITHM 1
- #define TLS_SHA1_ALGORITHM 2
- #define TLS_SHA224_ALGORITHM 3
- #define TLS_SHA256_ALGORITHM 4
- #define TLS_SHA384_ALGORITHM 5
- #define TLS_SHA512_ALGORITHM 6
-
- /* TLS signature algorithm identifiers */
- #define TLS_RSA_ALGORITHM 1
-
- /* TLS server name extension */
- #define TLS_SERVER_NAME 0
- #define TLS_SERVER_NAME_HOST_NAME 0
-
- /* TLS maximum fragment length extension */
- #define TLS_MAX_FRAGMENT_LENGTH 1
- #define TLS_MAX_FRAGMENT_LENGTH_512 1
- #define TLS_MAX_FRAGMENT_LENGTH_1024 2
- #define TLS_MAX_FRAGMENT_LENGTH_2048 3
- #define TLS_MAX_FRAGMENT_LENGTH_4096 4
-
- /* TLS signature algorithms extension */
- #define TLS_SIGNATURE_ALGORITHMS 13
-
- /* TLS session ticket extension */
- #define TLS_SESSION_TICKET 35
-
- /* TLS renegotiation information extension */
- #define TLS_RENEGOTIATION_INFO 0xff01
-
- /** TLS verification data */
- struct tls_verify_data {
- /** Client verification data */
- uint8_t client[12];
- /** Server verification data */
- uint8_t server[12];
- } __attribute__ (( packed ));
-
- /** TLS RX state machine state */
- enum tls_rx_state {
- TLS_RX_HEADER = 0,
- TLS_RX_DATA,
- };
-
- /** TLS TX pending flags */
- enum tls_tx_pending {
- TLS_TX_CLIENT_HELLO = 0x0001,
- TLS_TX_CERTIFICATE = 0x0002,
- TLS_TX_CLIENT_KEY_EXCHANGE = 0x0004,
- TLS_TX_CERTIFICATE_VERIFY = 0x0008,
- TLS_TX_CHANGE_CIPHER = 0x0010,
- TLS_TX_FINISHED = 0x0020,
- };
-
- /** A TLS cipher suite */
- struct tls_cipher_suite {
- /** Public-key encryption algorithm */
- struct pubkey_algorithm *pubkey;
- /** Bulk encryption cipher algorithm */
- struct cipher_algorithm *cipher;
- /** MAC digest algorithm */
- struct digest_algorithm *digest;
- /** Key length */
- uint16_t key_len;
- /** Numeric code (in network-endian order) */
- uint16_t code;
- };
-
- /** TLS cipher suite table */
- #define TLS_CIPHER_SUITES \
- __table ( struct tls_cipher_suite, "tls_cipher_suites" )
-
- /** Declare a TLS cipher suite */
- #define __tls_cipher_suite( pref ) \
- __table_entry ( TLS_CIPHER_SUITES, pref )
-
- /** A TLS cipher specification */
- struct tls_cipherspec {
- /** Cipher suite */
- struct tls_cipher_suite *suite;
- /** Dynamically-allocated storage */
- void *dynamic;
- /** Public key encryption context */
- void *pubkey_ctx;
- /** Bulk encryption cipher context */
- void *cipher_ctx;
- /** Next bulk encryption cipher context (TX only) */
- void *cipher_next_ctx;
- /** MAC secret */
- void *mac_secret;
- };
-
- /** A TLS signature and hash algorithm identifier */
- struct tls_signature_hash_id {
- /** Hash algorithm */
- uint8_t hash;
- /** Signature algorithm */
- uint8_t signature;
- } __attribute__ (( packed ));
-
- /** A TLS signature algorithm */
- struct tls_signature_hash_algorithm {
- /** Digest algorithm */
- struct digest_algorithm *digest;
- /** Public-key algorithm */
- struct pubkey_algorithm *pubkey;
- /** Numeric code */
- struct tls_signature_hash_id code;
- };
-
- /** TLS signature hash algorithm table
- *
- * Note that the default (TLSv1.1 and earlier) algorithm using
- * MD5+SHA1 is never explicitly specified.
- */
- #define TLS_SIG_HASH_ALGORITHMS \
- __table ( struct tls_signature_hash_algorithm, \
- "tls_sig_hash_algorithms" )
-
- /** Declare a TLS signature hash algorithm */
- #define __tls_sig_hash_algorithm \
- __table_entry ( TLS_SIG_HASH_ALGORITHMS, 01 )
-
- /** TLS pre-master secret */
- struct tls_pre_master_secret {
- /** TLS version */
- uint16_t version;
- /** Random data */
- uint8_t random[46];
- } __attribute__ (( packed ));
-
- /** TLS client random data */
- struct tls_client_random {
- /** GMT Unix time */
- uint32_t gmt_unix_time;
- /** Random data */
- uint8_t random[28];
- } __attribute__ (( packed ));
-
- /** An MD5+SHA1 context */
- struct md5_sha1_context {
- /** MD5 context */
- uint8_t md5[MD5_CTX_SIZE];
- /** SHA-1 context */
- uint8_t sha1[SHA1_CTX_SIZE];
- } __attribute__ (( packed ));
-
- /** MD5+SHA1 context size */
- #define MD5_SHA1_CTX_SIZE sizeof ( struct md5_sha1_context )
-
- /** An MD5+SHA1 digest */
- struct md5_sha1_digest {
- /** MD5 digest */
- uint8_t md5[MD5_DIGEST_SIZE];
- /** SHA-1 digest */
- uint8_t sha1[SHA1_DIGEST_SIZE];
- } __attribute__ (( packed ));
-
- /** MD5+SHA1 digest size */
- #define MD5_SHA1_DIGEST_SIZE sizeof ( struct md5_sha1_digest )
-
- /** A TLS session */
- struct tls_session {
- /** Reference counter */
- struct refcnt refcnt;
- /** List of sessions */
- struct list_head list;
-
- /** Server name */
- const char *name;
- /** Session ID */
- uint8_t id[32];
- /** Length of session ID */
- size_t id_len;
- /** Session ticket */
- void *ticket;
- /** Length of session ticket */
- size_t ticket_len;
- /** Master secret */
- uint8_t master_secret[48];
-
- /** List of connections */
- struct list_head conn;
- };
-
- /** A TLS connection */
- struct tls_connection {
- /** Reference counter */
- struct refcnt refcnt;
-
- /** Session */
- struct tls_session *session;
- /** List of connections within the same session */
- struct list_head list;
- /** Session ID */
- uint8_t session_id[32];
- /** Length of session ID */
- size_t session_id_len;
- /** New session ticket */
- void *new_session_ticket;
- /** Length of new session ticket */
- size_t new_session_ticket_len;
-
- /** Plaintext stream */
- struct interface plainstream;
- /** Ciphertext stream */
- struct interface cipherstream;
-
- /** Protocol version */
- uint16_t version;
- /** Current TX cipher specification */
- struct tls_cipherspec tx_cipherspec;
- /** Next TX cipher specification */
- struct tls_cipherspec tx_cipherspec_pending;
- /** Current RX cipher specification */
- struct tls_cipherspec rx_cipherspec;
- /** Next RX cipher specification */
- struct tls_cipherspec rx_cipherspec_pending;
- /** Premaster secret */
- struct tls_pre_master_secret pre_master_secret;
- /** Master secret */
- uint8_t master_secret[48];
- /** Server random bytes */
- uint8_t server_random[32];
- /** Client random bytes */
- struct tls_client_random client_random;
- /** MD5+SHA1 context for handshake verification */
- uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE];
- /** SHA256 context for handshake verification */
- uint8_t handshake_sha256_ctx[SHA256_CTX_SIZE];
- /** Digest algorithm used for handshake verification */
- struct digest_algorithm *handshake_digest;
- /** Digest algorithm context used for handshake verification */
- uint8_t *handshake_ctx;
- /** Client certificate (if used) */
- struct x509_certificate *cert;
- /** Secure renegotiation flag */
- int secure_renegotiation;
- /** Verification data */
- struct tls_verify_data verify;
-
- /** Server certificate chain */
- struct x509_chain *chain;
- /** Certificate validator */
- struct interface validator;
-
- /** Client security negotiation pending operation */
- struct pending_operation client_negotiation;
- /** Server security negotiation pending operation */
- struct pending_operation server_negotiation;
- /** Certificate validation pending operation */
- struct pending_operation validation;
-
- /** TX sequence number */
- uint64_t tx_seq;
- /** TX pending transmissions */
- unsigned int tx_pending;
- /** TX process */
- struct process process;
-
- /** RX sequence number */
- uint64_t rx_seq;
- /** RX state */
- enum tls_rx_state rx_state;
- /** Current received record header */
- struct tls_header rx_header;
- /** Current received record header (static I/O buffer) */
- struct io_buffer rx_header_iobuf;
- /** List of received data buffers */
- struct list_head rx_data;
- };
-
- /** RX I/O buffer size
- *
- * The maximum fragment length extension is optional, and many common
- * implementations (including OpenSSL) do not support it. We must
- * therefore be prepared to receive records of up to 16kB in length.
- * The chance of an allocation of this size failing is non-negligible,
- * so we must split received data into smaller allocations.
- */
- #define TLS_RX_BUFSIZE 4096
-
- /** Minimum RX I/O buffer size
- *
- * To simplify manipulations, we ensure that no RX I/O buffer is
- * smaller than this size. This allows us to assume that the MAC and
- * padding are entirely contained within the final I/O buffer.
- */
- #define TLS_RX_MIN_BUFSIZE 512
-
- /** RX I/O buffer alignment */
- #define TLS_RX_ALIGN 16
-
- extern int add_tls ( struct interface *xfer, const char *name,
- struct interface **next );
-
- #endif /* _IPXE_TLS_H */
|