iPXE
tls.h
Go to the documentation of this file.
00001 #ifndef _IPXE_TLS_H
00002 #define _IPXE_TLS_H
00003 
00004 /**
00005  * @file
00006  *
00007  * Transport Layer Security Protocol
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdint.h>
00013 #include <ipxe/refcnt.h>
00014 #include <ipxe/interface.h>
00015 #include <ipxe/process.h>
00016 #include <ipxe/crypto.h>
00017 #include <ipxe/md5.h>
00018 #include <ipxe/sha1.h>
00019 #include <ipxe/sha256.h>
00020 #include <ipxe/x509.h>
00021 #include <ipxe/pending.h>
00022 #include <ipxe/iobuf.h>
00023 #include <ipxe/tables.h>
00024 
00025 /** A TLS header */
00026 struct tls_header {
00027         /** Content type
00028          *
00029          * This is a TLS_TYPE_XXX constant
00030          */
00031         uint8_t type;
00032         /** Protocol version
00033          *
00034          * This is a TLS_VERSION_XXX constant
00035          */
00036         uint16_t version;
00037         /** Length of payload */
00038         uint16_t length;
00039 } __attribute__ (( packed ));
00040 
00041 /** TLS version 1.0 */
00042 #define TLS_VERSION_TLS_1_0 0x0301
00043 
00044 /** TLS version 1.1 */
00045 #define TLS_VERSION_TLS_1_1 0x0302
00046 
00047 /** TLS version 1.2 */
00048 #define TLS_VERSION_TLS_1_2 0x0303
00049 
00050 /** Change cipher content type */
00051 #define TLS_TYPE_CHANGE_CIPHER 20
00052 
00053 /** Alert content type */
00054 #define TLS_TYPE_ALERT 21
00055 
00056 /** Handshake content type */
00057 #define TLS_TYPE_HANDSHAKE 22
00058 
00059 /** Application data content type */
00060 #define TLS_TYPE_DATA 23
00061 
00062 /* Handshake message types */
00063 #define TLS_HELLO_REQUEST 0
00064 #define TLS_CLIENT_HELLO 1
00065 #define TLS_SERVER_HELLO 2
00066 #define TLS_CERTIFICATE 11
00067 #define TLS_SERVER_KEY_EXCHANGE 12
00068 #define TLS_CERTIFICATE_REQUEST 13
00069 #define TLS_SERVER_HELLO_DONE 14
00070 #define TLS_CERTIFICATE_VERIFY 15
00071 #define TLS_CLIENT_KEY_EXCHANGE 16
00072 #define TLS_FINISHED 20
00073 
00074 /* TLS alert levels */
00075 #define TLS_ALERT_WARNING 1
00076 #define TLS_ALERT_FATAL 2
00077 
00078 /* TLS cipher specifications */
00079 #define TLS_RSA_WITH_NULL_MD5 0x0001
00080 #define TLS_RSA_WITH_NULL_SHA 0x0002
00081 #define TLS_RSA_WITH_AES_128_CBC_SHA 0x002f
00082 #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
00083 #define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003c
00084 #define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003d
00085 
00086 /* TLS hash algorithm identifiers */
00087 #define TLS_MD5_ALGORITHM 1
00088 #define TLS_SHA1_ALGORITHM 2
00089 #define TLS_SHA224_ALGORITHM 3
00090 #define TLS_SHA256_ALGORITHM 4
00091 #define TLS_SHA384_ALGORITHM 5
00092 #define TLS_SHA512_ALGORITHM 6
00093 
00094 /* TLS signature algorithm identifiers */
00095 #define TLS_RSA_ALGORITHM 1
00096 
00097 /* TLS server name extension */
00098 #define TLS_SERVER_NAME 0
00099 #define TLS_SERVER_NAME_HOST_NAME 0
00100 
00101 /* TLS maximum fragment length extension */
00102 #define TLS_MAX_FRAGMENT_LENGTH 1
00103 #define TLS_MAX_FRAGMENT_LENGTH_512 1
00104 #define TLS_MAX_FRAGMENT_LENGTH_1024 2
00105 #define TLS_MAX_FRAGMENT_LENGTH_2048 3
00106 #define TLS_MAX_FRAGMENT_LENGTH_4096 4
00107 
00108 /* TLS signature algorithms extension */
00109 #define TLS_SIGNATURE_ALGORITHMS 13
00110 
00111 /* TLS renegotiation information extension */
00112 #define TLS_RENEGOTIATION_INFO 0xff01
00113 
00114 /** TLS verification data */
00115 struct tls_verify_data {
00116         /** Client verification data */
00117         uint8_t client[12];
00118         /** Server verification data */
00119         uint8_t server[12];
00120 } __attribute__ (( packed ));
00121 
00122 /** TLS RX state machine state */
00123 enum tls_rx_state {
00124         TLS_RX_HEADER = 0,
00125         TLS_RX_DATA,
00126 };
00127 
00128 /** TLS TX pending flags */
00129 enum tls_tx_pending {
00130         TLS_TX_CLIENT_HELLO = 0x0001,
00131         TLS_TX_CERTIFICATE = 0x0002,
00132         TLS_TX_CLIENT_KEY_EXCHANGE = 0x0004,
00133         TLS_TX_CERTIFICATE_VERIFY = 0x0008,
00134         TLS_TX_CHANGE_CIPHER = 0x0010,
00135         TLS_TX_FINISHED = 0x0020,
00136 };
00137 
00138 /** A TLS cipher suite */
00139 struct tls_cipher_suite {
00140         /** Public-key encryption algorithm */
00141         struct pubkey_algorithm *pubkey;
00142         /** Bulk encryption cipher algorithm */
00143         struct cipher_algorithm *cipher;
00144         /** MAC digest algorithm */
00145         struct digest_algorithm *digest;
00146         /** Key length */
00147         uint16_t key_len;
00148         /** Numeric code (in network-endian order) */
00149         uint16_t code;
00150 };
00151 
00152 /** TLS cipher suite table */
00153 #define TLS_CIPHER_SUITES                                               \
00154         __table ( struct tls_cipher_suite, "tls_cipher_suites" )
00155 
00156 /** Declare a TLS cipher suite */
00157 #define __tls_cipher_suite( pref )                                      \
00158         __table_entry ( TLS_CIPHER_SUITES, pref )
00159 
00160 /** A TLS cipher specification */
00161 struct tls_cipherspec {
00162         /** Cipher suite */
00163         struct tls_cipher_suite *suite;
00164         /** Dynamically-allocated storage */
00165         void *dynamic;
00166         /** Public key encryption context */
00167         void *pubkey_ctx;
00168         /** Bulk encryption cipher context */
00169         void *cipher_ctx;
00170         /** Next bulk encryption cipher context (TX only) */
00171         void *cipher_next_ctx;
00172         /** MAC secret */
00173         void *mac_secret;
00174 };
00175 
00176 /** A TLS signature and hash algorithm identifier */
00177 struct tls_signature_hash_id {
00178         /** Hash algorithm */
00179         uint8_t hash;
00180         /** Signature algorithm */
00181         uint8_t signature;
00182 } __attribute__ (( packed ));
00183 
00184 /** A TLS signature algorithm */
00185 struct tls_signature_hash_algorithm {
00186         /** Digest algorithm */
00187         struct digest_algorithm *digest;
00188         /** Public-key algorithm */
00189         struct pubkey_algorithm *pubkey;
00190         /** Numeric code */
00191         struct tls_signature_hash_id code;
00192 };
00193 
00194 /** TLS signature hash algorithm table
00195  *
00196  * Note that the default (TLSv1.1 and earlier) algorithm using
00197  * MD5+SHA1 is never explicitly specified.
00198  */
00199 #define TLS_SIG_HASH_ALGORITHMS                                         \
00200         __table ( struct tls_signature_hash_algorithm,                  \
00201                   "tls_sig_hash_algorithms" )
00202 
00203 /** Declare a TLS signature hash algorithm */
00204 #define __tls_sig_hash_algorithm                                        \
00205         __table_entry ( TLS_SIG_HASH_ALGORITHMS, 01 )
00206 
00207 /** TLS pre-master secret */
00208 struct tls_pre_master_secret {
00209         /** TLS version */
00210         uint16_t version;
00211         /** Random data */
00212         uint8_t random[46];
00213 } __attribute__ (( packed ));
00214 
00215 /** TLS client random data */
00216 struct tls_client_random {
00217         /** GMT Unix time */
00218         uint32_t gmt_unix_time;
00219         /** Random data */
00220         uint8_t random[28];
00221 } __attribute__ (( packed ));
00222 
00223 /** An MD5+SHA1 context */
00224 struct md5_sha1_context {
00225         /** MD5 context */
00226         uint8_t md5[MD5_CTX_SIZE];
00227         /** SHA-1 context */
00228         uint8_t sha1[SHA1_CTX_SIZE];
00229 } __attribute__ (( packed ));
00230 
00231 /** MD5+SHA1 context size */
00232 #define MD5_SHA1_CTX_SIZE sizeof ( struct md5_sha1_context )
00233 
00234 /** An MD5+SHA1 digest */
00235 struct md5_sha1_digest {
00236         /** MD5 digest */
00237         uint8_t md5[MD5_DIGEST_SIZE];
00238         /** SHA-1 digest */
00239         uint8_t sha1[SHA1_DIGEST_SIZE];
00240 } __attribute__ (( packed ));
00241 
00242 /** MD5+SHA1 digest size */
00243 #define MD5_SHA1_DIGEST_SIZE sizeof ( struct md5_sha1_digest )
00244 
00245 /** A TLS connection */
00246 struct tls_connection {
00247         /** Reference counter */
00248         struct refcnt refcnt;
00249 
00250         /** Server name */
00251         const char *name;
00252         /** Plaintext stream */
00253         struct interface plainstream;
00254         /** Ciphertext stream */
00255         struct interface cipherstream;
00256 
00257         /** Protocol version */
00258         uint16_t version;
00259         /** Current TX cipher specification */
00260         struct tls_cipherspec tx_cipherspec;
00261         /** Next TX cipher specification */
00262         struct tls_cipherspec tx_cipherspec_pending;
00263         /** Current RX cipher specification */
00264         struct tls_cipherspec rx_cipherspec;
00265         /** Next RX cipher specification */
00266         struct tls_cipherspec rx_cipherspec_pending;
00267         /** Premaster secret */
00268         struct tls_pre_master_secret pre_master_secret;
00269         /** Master secret */
00270         uint8_t master_secret[48];
00271         /** Server random bytes */
00272         uint8_t server_random[32];
00273         /** Client random bytes */
00274         struct tls_client_random client_random;
00275         /** MD5+SHA1 context for handshake verification */
00276         uint8_t handshake_md5_sha1_ctx[MD5_SHA1_CTX_SIZE];
00277         /** SHA256 context for handshake verification */
00278         uint8_t handshake_sha256_ctx[SHA256_CTX_SIZE];
00279         /** Digest algorithm used for handshake verification */
00280         struct digest_algorithm *handshake_digest;
00281         /** Digest algorithm context used for handshake verification */
00282         uint8_t *handshake_ctx;
00283         /** Client certificate (if used) */
00284         struct x509_certificate *cert;
00285         /** Secure renegotiation flag */
00286         int secure_renegotiation;
00287         /** Verification data */
00288         struct tls_verify_data verify;
00289 
00290         /** Server certificate chain */
00291         struct x509_chain *chain;
00292         /** Certificate validator */
00293         struct interface validator;
00294 
00295         /** Client security negotiation pending operation */
00296         struct pending_operation client_negotiation;
00297         /** Server security negotiation pending operation */
00298         struct pending_operation server_negotiation;
00299 
00300         /** TX sequence number */
00301         uint64_t tx_seq;
00302         /** TX pending transmissions */
00303         unsigned int tx_pending;
00304         /** TX process */
00305         struct process process;
00306 
00307         /** RX sequence number */
00308         uint64_t rx_seq;
00309         /** RX state */
00310         enum tls_rx_state rx_state;
00311         /** Current received record header */
00312         struct tls_header rx_header;
00313         /** Current received record header (static I/O buffer) */
00314         struct io_buffer rx_header_iobuf;
00315         /** List of received data buffers */
00316         struct list_head rx_data;
00317 };
00318 
00319 /** RX I/O buffer size
00320  *
00321  * The maximum fragment length extension is optional, and many common
00322  * implementations (including OpenSSL) do not support it.  We must
00323  * therefore be prepared to receive records of up to 16kB in length.
00324  * The chance of an allocation of this size failing is non-negligible,
00325  * so we must split received data into smaller allocations.
00326  */
00327 #define TLS_RX_BUFSIZE 4096
00328 
00329 /** Minimum RX I/O buffer size
00330  *
00331  * To simplify manipulations, we ensure that no RX I/O buffer is
00332  * smaller than this size.  This allows us to assume that the MAC and
00333  * padding are entirely contained within the final I/O buffer.
00334  */
00335 #define TLS_RX_MIN_BUFSIZE 512
00336 
00337 /** RX I/O buffer alignment */
00338 #define TLS_RX_ALIGN 16
00339 
00340 extern int add_tls ( struct interface *xfer, const char *name,
00341                      struct interface **next );
00342 
00343 #endif /* _IPXE_TLS_H */