Document everything in ssl_ciph.c, now ssl_cipher.c.
Just about everything depends on SSL_CIPHER. Move it to the top as the first
section in ssl.h. Match the header order and the source file order and document
everything. Also make a couple of minor style guide tweaks.
Change-Id: I6a810dbe79238278ac480e5ced1447055715a79f
Reviewed-on: https://boringssl-review.googlesource.com/4290
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 1aa5959..f6e03e6 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -164,6 +164,87 @@
#endif
+/* Initialization. */
+
+/* SSL_library_init initializes the crypto and SSL libraries and returns one. */
+OPENSSL_EXPORT int SSL_library_init(void);
+
+
+/* Cipher suites. */
+
+/* An SSL_CIPHER represents a cipher suite. */
+typedef struct ssl_cipher_st {
+ /* name is the OpenSSL name for the cipher. */
+ const char *name;
+ /* id is the cipher suite value bitwise OR-d with 0x03000000. */
+ uint32_t id;
+
+ /* The following are internal fields. See ssl/internal.h for their values. */
+
+ uint32_t algorithm_mkey;
+ uint32_t algorithm_auth;
+ uint32_t algorithm_enc;
+ uint32_t algorithm_mac;
+ uint32_t algorithm_ssl;
+ uint32_t algo_strength;
+
+ /* algorithm2 contains extra flags. See ssl/internal.h. */
+ uint32_t algorithm2;
+
+ /* strength_bits is the strength of the cipher in bits. */
+ int strength_bits;
+ /* alg_bits is the number of bits of key material used by the algorithm. */
+ int alg_bits;
+} SSL_CIPHER;
+
+DECLARE_STACK_OF(SSL_CIPHER)
+
+/* SSL_get_cipher_by_value returns the structure representing a TLS cipher
+ * suite based on its assigned number, or NULL if unknown. See
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. */
+OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value);
+
+/* SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to
+ * get the cipher suite value. */
+OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_AES returns one if |cipher| uses AES (either GCM or CBC
+ * mode). */
+OPENSSL_EXPORT int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_has_MD5_HMAC returns one if |cipher| uses HMAC-MD5. */
+OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_AESGCM returns one if |cipher| uses AES-GCM. */
+OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_CHACHA20POLY1305 returns one if |cipher| uses
+ * CHACHA20_POLY1305. */
+OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_kx_name returns a string that describes the key-exchange
+ * method used by |cipher|. For example, "ECDHE_ECDSA". */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_rfc_name returns a newly-allocated string with the standard
+ * name for |cipher|. For example, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". The
+ * caller is responsible for calling |OPENSSL_free| on the result. */
+OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If
+ * |out_alg_bits| is not NULL, it writes the number of bits consumed by the
+ * symmetric algorithm to |*out_alg_bits|. */
+OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher,
+ int *out_alg_bits);
+
+
+/* Underdocumented functions.
+ *
+ * Functions below here haven't been touched up and may be underdocumented. */
+
/* SSLeay version number for ASN.1 encoding of the session information */
/* Version 0 - initial version
* Version 1 - added the optional peer certificate. */
@@ -254,14 +335,11 @@
typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
-typedef struct ssl_cipher_st SSL_CIPHER;
typedef struct ssl_session_st SSL_SESSION;
typedef struct tls_sigalgs_st TLS_SIGALGS;
typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
typedef struct ssl3_enc_method SSL3_ENC_METHOD;
-DECLARE_STACK_OF(SSL_CIPHER)
-
/* SRTP protection profiles for use with the use_srtp extension (RFC 5764). */
typedef struct srtp_protection_profile_st {
const char *name;
@@ -270,26 +348,6 @@
DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
-/* used to hold info on the particular ciphers used */
-struct ssl_cipher_st {
- const char *name; /* text name */
- uint32_t id; /* id, 4 bytes, first is version */
-
- /* changed in 0.9.9: these four used to be portions of a single value
- * 'algorithms' */
- uint32_t algorithm_mkey; /* key exchange algorithm */
- uint32_t algorithm_auth; /* server authentication */
- uint32_t algorithm_enc; /* symmetric encryption */
- uint32_t algorithm_mac; /* symmetric authentication */
- uint32_t algorithm_ssl; /* (major) protocol version */
-
- uint32_t algo_strength; /* strength and export flags */
- uint32_t algorithm2; /* Extra flags. See algorithm2 section in
- ssl/internal.h */
- int strength_bits; /* Number of bits really used */
- int alg_bits; /* Number of bits for algorithm */
-};
-
/* An SSL_SESSION represents an SSL session that may be resumed in an
* abbreviated handshake. */
struct ssl_session_st {
@@ -1790,20 +1848,6 @@
OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
-OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits);
-OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *c);
-OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *c);
-
-/* SSL_CIPHER_get_kx_name returns a string that describes the key-exchange
- * method used by |cipher|. For example, "ECDHE-ECDSA". */
-OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_get_rfc_name returns a newly-allocated string with the standard
- * name for |cipher|. For example, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". The
- * caller is responsible for calling |OPENSSL_free| on the result. */
-OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher);
-
-OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c);
OPENSSL_EXPORT int SSL_get_fd(const SSL *s);
OPENSSL_EXPORT int SSL_get_rfd(const SSL *s);
@@ -2007,11 +2051,6 @@
* |sess|. For example, "TLSv1.2" or "SSLv3". */
OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *sess);
-OPENSSL_EXPORT int SSL_CIPHER_is_AES(const SSL_CIPHER *c);
-OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *c);
-OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *c);
-OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c);
-
/* TLS_method is the SSL_METHOD used for TLS (and SSLv3) connections. */
OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
@@ -2081,12 +2120,6 @@
OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *s);
-/* SSL_library_init initializes the crypto and SSL libraries, loads their error
- * strings, and returns one. */
-OPENSSL_EXPORT int SSL_library_init(void);
-
-OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf,
- int size);
OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl);
@@ -2196,9 +2229,6 @@
OPENSSL_EXPORT const void *SSL_get_current_compression(SSL *s);
OPENSSL_EXPORT const void *SSL_get_current_expansion(SSL *s);
-OPENSSL_EXPORT const char *SSL_COMP_get_name(const void *comp);
-OPENSSL_EXPORT void *SSL_COMP_get_compression_methods(void);
-OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, void *cm);
OPENSSL_EXPORT int SSL_cache_hit(SSL *s);
OPENSSL_EXPORT int SSL_is_server(SSL *s);
@@ -2218,11 +2248,6 @@
OPENSSL_EXPORT void ERR_load_SSL_strings(void);
-/* SSL_get_cipher_by_value returns the structure representing a TLS cipher
- * suite based on its assigned number, or NULL if unknown. See
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. */
-OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value);
-
/* SSL_get_rc4_state sets |*read_key| and |*write_key| to the RC4 states for
* the read and write directions. It returns one on success or zero if |ssl|
* isn't using an RC4-based cipher suite. */
@@ -2230,6 +2255,32 @@
const RC4_KEY **write_key);
+/* Deprecated functions. */
+
+/* SSL_CIPHER_description writes a description of |cipher| into |buf| and
+ * returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be
+ * freed with |OPENSSL_free|, or NULL on error.
+ *
+ * The description includes a trailing newline and has the form:
+ * AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
+ *
+ * Consider |SSL_CIPHER_get_name| or |SSL_CIPHER_get_rfc_name| instead. */
+OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher,
+ char *buf, int len);
+
+/* SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
+
+/* SSL_COMP_get_compression_methods returns NULL. */
+OPENSSL_EXPORT void *SSL_COMP_get_compression_methods(void);
+
+/* SSL_COMP_add_compression_method returns one. */
+OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, void *cm);
+
+/* SSL_COMP_get_name returns NULL. */
+OPENSSL_EXPORT const char *SSL_COMP_get_name(const void *comp);
+
+
/* Android compatibility section.
*
* These functions are declared, temporarily, for Android because
diff --git a/ssl/CMakeLists.txt b/ssl/CMakeLists.txt
index 7559bfb..9cc6de4 100644
--- a/ssl/CMakeLists.txt
+++ b/ssl/CMakeLists.txt
@@ -22,7 +22,7 @@
ssl_algs.c
ssl_asn1.c
ssl_cert.c
- ssl_ciph.c
+ ssl_cipher.c
ssl_lib.c
ssl_rsa.c
ssl_sess.c
diff --git a/ssl/internal.h b/ssl/internal.h
index cef609d..a1183bc 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -149,6 +149,142 @@
#include <openssl/stack.h>
+/* Cipher suites. */
+
+/* Bits for |algorithm_mkey| (key exchange algorithm). */
+#define SSL_kRSA 0x00000001L
+#define SSL_kDHE 0x00000002L
+#define SSL_kECDHE 0x00000004L
+/* SSL_kPSK is only set for plain PSK, not ECDHE_PSK. */
+#define SSL_kPSK 0x00000008L
+
+/* Bits for |algorithm_auth| (server authentication). */
+#define SSL_aRSA 0x00000001L
+#define SSL_aECDSA 0x00000002L
+/* SSL_aPSK is set for both PSK and ECDHE_PSK. */
+#define SSL_aPSK 0x00000004L
+
+/* Bits for |algorithm_enc| (symmetric encryption). */
+#define SSL_3DES 0x00000001L
+#define SSL_RC4 0x00000002L
+#define SSL_AES128 0x00000004L
+#define SSL_AES256 0x00000008L
+#define SSL_AES128GCM 0x00000010L
+#define SSL_AES256GCM 0x00000020L
+#define SSL_CHACHA20POLY1305 0x00000040L
+
+#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM)
+
+/* Bits for |algorithm_mac| (symmetric authentication). */
+#define SSL_MD5 0x00000001L
+#define SSL_SHA1 0x00000002L
+#define SSL_SHA256 0x00000004L
+#define SSL_SHA384 0x00000008L
+/* SSL_AEAD is set for all AEADs. */
+#define SSL_AEAD 0x00000010L
+
+/* Bits for |algorithm_ssl| (protocol version). These denote the first protocol
+ * version which introduced the cipher.
+ *
+ * TODO(davidben): These are extremely confusing, both in code and in
+ * cipher rules. Try to remove them. */
+#define SSL_SSLV3 0x00000002L
+#define SSL_TLSV1 SSL_SSLV3
+#define SSL_TLSV1_2 0x00000004L
+
+/* Bits for |algorithm2| (handshake digests and other extra flags). */
+
+#define SSL_HANDSHAKE_MAC_MD5 0x10
+#define SSL_HANDSHAKE_MAC_SHA 0x20
+#define SSL_HANDSHAKE_MAC_SHA256 0x40
+#define SSL_HANDSHAKE_MAC_SHA384 0x80
+#define SSL_HANDSHAKE_MAC_DEFAULT \
+ (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
+
+/* SSL_MAX_DIGEST is the number of digest types which exist. When adding a new
+ * one, update the table in ssl_cipher.c. */
+#define SSL_MAX_DIGEST 4
+
+#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT)
+
+#define TLS1_PRF_DGST_SHIFT 10
+#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
+
+/* SSL_CIPHER_ALGORITHM2_AEAD is a flag in SSL_CIPHER.algorithm2 which
+ * indicates that the cipher is implemented via an EVP_AEAD. */
+#define SSL_CIPHER_ALGORITHM2_AEAD (1 << 23)
+
+/* SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD is a flag in
+ * SSL_CIPHER.algorithm2 which indicates that the variable part of the nonce is
+ * included as a prefix of the record. (AES-GCM, for example, does with with an
+ * 8-byte variable nonce.) */
+#define SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD (1<<22)
+
+/* Bits for |algo_strength|, cipher strength information. */
+#define SSL_MEDIUM 0x00000001L
+#define SSL_HIGH 0x00000002L
+#define SSL_FIPS 0x00000004L
+
+/* ssl_cipher_get_evp_aead sets |*out_aead| to point to the correct EVP_AEAD
+ * object for |cipher| protocol version |version|. It sets |*out_mac_secret_len|
+ * and |*out_fixed_iv_len| to the MAC key length and fixed IV length,
+ * respectively. The MAC key length is zero except for legacy block and stream
+ * ciphers. It returns 1 on success and 0 on error. */
+int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
+ size_t *out_mac_secret_len,
+ size_t *out_fixed_iv_len,
+ const SSL_CIPHER *cipher, uint16_t version);
+
+/* ssl_get_handshake_digest looks up the |i|th handshake digest type and sets
+ * |*out_mask| to the |SSL_HANDSHAKE_MAC_*| mask and |*out_md| to the
+ * |EVP_MD|. It returns one on successs and zero if |i| >= |SSL_MAX_DIGEST|. */
+int ssl_get_handshake_digest(uint32_t *out_mask, const EVP_MD **out_md,
+ size_t i);
+
+/* ssl_create_cipher_list evaluates |rule_str| according to the ciphers in
+ * |ssl_method|. It sets |*out_cipher_list| to a newly-allocated
+ * |ssl_cipher_preference_list_st| containing the result.
+ * |*out_cipher_list_by_id| is set to a list of selected ciphers sorted by
+ * id. It returns |(*out_cipher_list)->ciphers| on success and NULL on
+ * failure. */
+STACK_OF(SSL_CIPHER) *
+ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
+ struct ssl_cipher_preference_list_st **out_cipher_list,
+ STACK_OF(SSL_CIPHER) **out_cipher_list_by_id,
+ const char *rule_str);
+
+/* SSL_PKEY_* denote certificate types. */
+#define SSL_PKEY_RSA_ENC 0
+#define SSL_PKEY_RSA_SIGN 1
+#define SSL_PKEY_ECC 2
+#define SSL_PKEY_NUM 3
+
+/* ssl_cipher_get_cert_index returns the |SSL_PKEY_*| value corresponding to the
+ * certificate type of |cipher| or -1 if there is none. */
+int ssl_cipher_get_cert_index(const SSL_CIPHER *cipher);
+
+/* ssl_cipher_has_server_public_key returns 1 if |cipher| involves a server
+ * public key in the key exchange, sent in a server Certificate message.
+ * Otherwise it returns 0. */
+int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher);
+
+/* ssl_cipher_requires_server_key_exchange returns 1 if |cipher| requires a
+ * ServerKeyExchange message. Otherwise it returns 0.
+ *
+ * Unlike ssl_cipher_has_server_public_key, some ciphers take optional
+ * ServerKeyExchanges. PSK and RSA_PSK only use the ServerKeyExchange to
+ * communicate a psk_identity_hint, so it is optional. */
+int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher);
+
+
+/* Underdocumented functions.
+ *
+ * Functions below here haven't been touched up and may be underdocumented. */
+
#define c2l(c, l) \
(l = ((unsigned long)(*((c)++))), l |= (((unsigned long)(*((c)++))) << 8), \
l |= (((unsigned long)(*((c)++))) << 16), \
@@ -263,95 +399,8 @@
#define DEC32(a) ((a) = ((a)-1) & 0xffffffffL)
#define MAX_MAC_SIZE 20 /* up from 16 for SSLv3 */
-/* Define the Bitmasks for SSL_CIPHER.algorithms.
- *
- * This bits are used packed as dense as possible. If new methods/ciphers etc
- * will be added, the bits a likely to change, so this information is for
- * internal library use only, even though SSL_CIPHER.algorithms can be publicly
- * accessed. Use the according functions for cipher management instead.
- *
- * The bit mask handling in the selection and sorting scheme in
- * ssl_create_cipher_list() has only limited capabilities, reflecting that the
- * different entities within are mutually exclusive:
- * ONLY ONE BIT PER MASK CAN BE SET AT A TIME. */
-
-/* Bits for algorithm_mkey (key exchange algorithm) */
-#define SSL_kRSA 0x00000001L /* RSA key exchange */
-#define SSL_kDHE 0x00000002L /* tmp DH key no DH cert */
-#define SSL_kECDHE 0x00000004L /* ephemeral ECDH */
-#define SSL_kPSK 0x00000008L /* PSK */
-
-/* Bits for algorithm_auth (server authentication) */
-#define SSL_aRSA 0x00000001L /* RSA auth */
-#define SSL_aECDSA 0x00000002L /* ECDSA auth*/
-#define SSL_aPSK 0x00000004L /* PSK auth */
-
-/* Bits for algorithm_enc (symmetric encryption) */
-#define SSL_3DES 0x00000001L
-#define SSL_RC4 0x00000002L
-#define SSL_AES128 0x00000004L
-#define SSL_AES256 0x00000008L
-#define SSL_AES128GCM 0x00000010L
-#define SSL_AES256GCM 0x00000020L
-#define SSL_CHACHA20POLY1305 0x00000040L
-
-#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM)
-
-/* Bits for algorithm_mac (symmetric authentication) */
-
-#define SSL_MD5 0x00000001L
-#define SSL_SHA1 0x00000002L
-#define SSL_SHA256 0x00000004L
-#define SSL_SHA384 0x00000008L
-/* Not a real MAC, just an indication it is part of cipher */
-#define SSL_AEAD 0x00000010L
-
-/* Bits for algorithm_ssl (protocol version) */
-#define SSL_SSLV3 0x00000002L
-#define SSL_TLSV1 SSL_SSLV3 /* for now */
-#define SSL_TLSV1_2 0x00000004L
-
-/* Bits for algorithm2 (handshake digests and other extra flags) */
-
-#define SSL_HANDSHAKE_MAC_MD5 0x10
-#define SSL_HANDSHAKE_MAC_SHA 0x20
-#define SSL_HANDSHAKE_MAC_SHA256 0x40
-#define SSL_HANDSHAKE_MAC_SHA384 0x80
-#define SSL_HANDSHAKE_MAC_DEFAULT \
- (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
-
-/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX
- * make sure to update this constant too */
-#define SSL_MAX_DIGEST 4
-
-#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT)
-
-#define TLS1_PRF_DGST_SHIFT 10
-#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
-
#define TLSEXT_CHANNEL_ID_SIZE 128
-/* SSL_CIPHER_ALGORITHM2_AEAD is a flag in SSL_CIPHER.algorithm2 which
- * indicates that the cipher is implemented via an EVP_AEAD. */
-#define SSL_CIPHER_ALGORITHM2_AEAD (1 << 23)
-
-/* SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD is a flag in
- * SSL_CIPHER.algorithm2 which indicates that the variable part of the nonce is
- * included as a prefix of the record. (AES-GCM, for example, does with with an
- * 8-byte variable nonce.) */
-#define SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD (1<<22)
-
-/* Cipher strength information. */
-#define SSL_MEDIUM 0x00000001L
-#define SSL_HIGH 0x00000002L
-#define SSL_FIPS 0x00000004L
-
-/* we have used 000001ff - 23 bits left to go */
-
/* Check if an SSL structure is using DTLS */
#define SSL_IS_DTLS(s) (s->method->is_dtls)
/* See if we need explicit IV */
@@ -370,12 +419,6 @@
((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \
(!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION))
-/* Mostly for SSLv3 */
-#define SSL_PKEY_RSA_ENC 0
-#define SSL_PKEY_RSA_SIGN 1
-#define SSL_PKEY_ECC 2
-#define SSL_PKEY_NUM 3
-
/* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) |
* <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN)
* SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
@@ -644,11 +687,6 @@
int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp);
STACK_OF(SSL_CIPHER) * ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs);
int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) * sk, uint8_t *p);
-STACK_OF(SSL_CIPHER) *
- ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *meth,
- struct ssl_cipher_preference_list_st **pref,
- STACK_OF(SSL_CIPHER) * *sorted, const char *rule_str,
- CERT *c);
struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
struct ssl_cipher_preference_list_st *cipher_list);
void ssl_cipher_preference_list_free(
@@ -657,21 +695,6 @@
STACK_OF(SSL_CIPHER) * ciphers);
struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *s);
-/* ssl_cipher_get_evp_aead sets |*out_aead| to point to the correct EVP_AEAD
-* object for |cipher| protocol version |version|. It sets |*out_mac_secret_len|
-* and |*out_fixed_iv_len| to the MAC key length and fixed IV length,
-* respectively. The MAC key length is zero except for legacy block and stream
-* ciphers. It returns 1 on success and 0 on error. */
-int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
- size_t *out_mac_secret_len,
- size_t *out_fixed_iv_len,
- const SSL_CIPHER *cipher, uint16_t version);
-
-int ssl_get_handshake_digest(size_t i, uint32_t *mask, const EVP_MD **md);
-int ssl_cipher_get_cert_index(const SSL_CIPHER *c);
-int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher);
-int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher);
-
int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) * chain);
int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) * chain);
int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index eed95f8..50df40c 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -304,7 +304,7 @@
}
/* Loop through bits of algorithm2 field and create MD_CTX-es */
- for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
+ for (i = 0; ssl_get_handshake_digest(&mask, &md, i); i++) {
if ((mask & ssl_get_algorithm2(s)) && md) {
s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
if (s->s3->handshake_dgst[i] == NULL) {
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_cipher.c
similarity index 93%
rename from ssl/ssl_ciph.c
rename to ssl/ssl_cipher.c
index 7a5c8be..857b2a4 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_cipher.c
@@ -142,11 +142,12 @@
#include <stdio.h>
#include <string.h>
+#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <openssl/sha.h>
+#include <openssl/stack.h>
#include "internal.h"
@@ -376,12 +377,13 @@
}
}
-int ssl_get_handshake_digest(size_t idx, uint32_t *mask, const EVP_MD **md) {
+int ssl_get_handshake_digest(uint32_t *out_mask, const EVP_MD **out_md,
+ size_t idx) {
if (idx >= SSL_MAX_DIGEST) {
return 0;
}
- *mask = ssl_handshake_digests[idx].mask;
- *md = ssl_handshake_digests[idx].md_func();
+ *out_mask = ssl_handshake_digests[idx].mask;
+ *out_md = ssl_handshake_digests[idx].md_func();
return 1;
}
@@ -846,9 +848,9 @@
STACK_OF(SSL_CIPHER) *
ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
- struct ssl_cipher_preference_list_st **cipher_list,
- STACK_OF(SSL_CIPHER) * *cipher_list_by_id,
- const char *rule_str, CERT *c) {
+ struct ssl_cipher_preference_list_st **out_cipher_list,
+ STACK_OF(SSL_CIPHER) **out_cipher_list_by_id,
+ const char *rule_str) {
int ok;
size_t num_of_ciphers;
STACK_OF(SSL_CIPHER) *cipherstack = NULL, *tmp_cipher_list = NULL;
@@ -859,7 +861,7 @@
struct ssl_cipher_preference_list_st *pref_list = NULL;
/* Return with error if nothing to do. */
- if (rule_str == NULL || cipher_list == NULL) {
+ if (rule_str == NULL || out_cipher_list == NULL) {
return NULL;
}
@@ -994,21 +996,22 @@
memcpy(pref_list->in_group_flags, in_group_flags, num_in_group_flags);
OPENSSL_free(in_group_flags);
in_group_flags = NULL;
- if (*cipher_list != NULL) {
- ssl_cipher_preference_list_free(*cipher_list);
+ if (*out_cipher_list != NULL) {
+ ssl_cipher_preference_list_free(*out_cipher_list);
}
- *cipher_list = pref_list;
+ *out_cipher_list = pref_list;
pref_list = NULL;
- if (cipher_list_by_id != NULL) {
- if (*cipher_list_by_id != NULL) {
- sk_SSL_CIPHER_free(*cipher_list_by_id);
+ if (out_cipher_list_by_id != NULL) {
+ if (*out_cipher_list_by_id != NULL) {
+ sk_SSL_CIPHER_free(*out_cipher_list_by_id);
}
- *cipher_list_by_id = tmp_cipher_list;
+ *out_cipher_list_by_id = tmp_cipher_list;
tmp_cipher_list = NULL;
- (void) sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, ssl_cipher_ptr_id_cmp);
+ (void) sk_SSL_CIPHER_set_cmp_func(*out_cipher_list_by_id,
+ ssl_cipher_ptr_id_cmp);
- sk_SSL_CIPHER_sort(*cipher_list_by_id);
+ sk_SSL_CIPHER_sort(*out_cipher_list_by_id);
} else {
sk_SSL_CIPHER_free(tmp_cipher_list);
tmp_cipher_list = NULL;
@@ -1038,6 +1041,161 @@
return NULL;
}
+uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; }
+
+int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_enc & SSL_AES) != 0;
+}
+
+int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_mac & SSL_MD5) != 0;
+}
+
+int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_mac & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
+}
+
+int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_enc & SSL_CHACHA20POLY1305) != 0;
+}
+
+/* return the actual cipher being used */
+const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) {
+ if (cipher != NULL) {
+ return cipher->name;
+ }
+
+ return "(NONE)";
+}
+
+const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) {
+ if (cipher == NULL) {
+ return "";
+ }
+
+ switch (cipher->algorithm_mkey) {
+ case SSL_kRSA:
+ return "RSA";
+
+ case SSL_kDHE:
+ switch (cipher->algorithm_auth) {
+ case SSL_aRSA:
+ return "DHE_RSA";
+ default:
+ assert(0);
+ return "UNKNOWN";
+ }
+
+ case SSL_kECDHE:
+ switch (cipher->algorithm_auth) {
+ case SSL_aECDSA:
+ return "ECDHE_ECDSA";
+ case SSL_aRSA:
+ return "ECDHE_RSA";
+ case SSL_aPSK:
+ return "ECDHE_PSK";
+ default:
+ assert(0);
+ return "UNKNOWN";
+ }
+
+ case SSL_kPSK:
+ assert(cipher->algorithm_auth == SSL_aPSK);
+ return "PSK";
+
+ default:
+ assert(0);
+ return "UNKNOWN";
+ }
+}
+
+static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
+ switch (cipher->algorithm_enc) {
+ case SSL_3DES:
+ return "3DES_EDE_CBC";
+ case SSL_RC4:
+ return "RC4";
+ case SSL_AES128:
+ return "AES_128_CBC";
+ case SSL_AES256:
+ return "AES_256_CBC";
+ case SSL_AES128GCM:
+ return "AES_128_GCM";
+ case SSL_AES256GCM:
+ return "AES_256_GCM";
+ case SSL_CHACHA20POLY1305:
+ return "CHACHA20_POLY1305";
+ break;
+ default:
+ assert(0);
+ return "UNKNOWN";
+ }
+}
+
+static const char *ssl_cipher_get_prf_name(const SSL_CIPHER *cipher) {
+ if ((cipher->algorithm2 & TLS1_PRF) == TLS1_PRF) {
+ /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
+ * only ever MD5 or SHA-1. */
+ switch (cipher->algorithm_mac) {
+ case SSL_MD5:
+ return "MD5";
+ case SSL_SHA1:
+ return "SHA";
+ default:
+ assert(0);
+ return "UNKNOWN";
+ }
+ } else if (cipher->algorithm2 & TLS1_PRF_SHA256) {
+ return "SHA256";
+ } else if (cipher->algorithm2 & TLS1_PRF_SHA384) {
+ return "SHA384";
+ } else {
+ assert(0);
+ return "UNKNOWN";
+ }
+}
+
+char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) {
+ if (cipher == NULL) {
+ return NULL;
+ }
+
+ const char *kx_name = SSL_CIPHER_get_kx_name(cipher);
+ const char *enc_name = ssl_cipher_get_enc_name(cipher);
+ const char *prf_name = ssl_cipher_get_prf_name(cipher);
+
+ /* The final name is TLS_{kx_name}_WITH_{enc_name}_{prf_name}. */
+ size_t len = 4 + strlen(kx_name) + 6 + strlen(enc_name) + 1 +
+ strlen(prf_name) + 1;
+ char *ret = OPENSSL_malloc(len);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (BUF_strlcpy(ret, "TLS_", len) >= len ||
+ BUF_strlcat(ret, kx_name, len) >= len ||
+ BUF_strlcat(ret, "_WITH_", len) >= len ||
+ BUF_strlcat(ret, enc_name, len) >= len ||
+ BUF_strlcat(ret, "_", len) >= len ||
+ BUF_strlcat(ret, prf_name, len) >= len) {
+ assert(0);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ assert(strlen(ret) + 1 == len);
+ return ret;
+}
+
+int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) {
+ if (cipher == NULL) {
+ return 0;
+ }
+
+ if (out_alg_bits != NULL) {
+ *out_alg_bits = cipher->alg_bits;
+ }
+ return cipher->strength_bits;
+}
+
const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
int len) {
const char *ver;
@@ -1172,190 +1330,18 @@
return buf;
}
-int SSL_CIPHER_is_AES(const SSL_CIPHER *c) {
- return (c->algorithm_enc & SSL_AES) != 0;
+const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) {
+ return "TLSv1/SSLv3";
}
-int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *c) {
- return (c->algorithm_mac & SSL_MD5) != 0;
-}
-
-int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *c) {
- return (c->algorithm_mac & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
-}
-
-int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c) {
- return (c->algorithm_enc & SSL_CHACHA20POLY1305) != 0;
-}
-
-const char *SSL_CIPHER_get_version(const SSL_CIPHER *c) {
- int i;
-
- if (c == NULL) {
- return "(NONE)";
- }
-
- i = (int)(c->id >> 24L);
- if (i == 3) {
- return "TLSv1/SSLv3";
- } else if (i == 2) {
- return "SSLv2";
- } else {
- return "unknown";
- }
-}
-
-/* return the actual cipher being used */
-const char *SSL_CIPHER_get_name(const SSL_CIPHER *c) {
- if (c != NULL) {
- return c->name;
- }
-
- return "(NONE)";
-}
-
-const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) {
- if (cipher == NULL) {
- return "";
- }
-
- switch (cipher->algorithm_mkey) {
- case SSL_kRSA:
- return "RSA";
-
- case SSL_kDHE:
- switch (cipher->algorithm_auth) {
- case SSL_aRSA:
- return "DHE_RSA";
- default:
- assert(0);
- return "UNKNOWN";
- }
-
- case SSL_kECDHE:
- switch (cipher->algorithm_auth) {
- case SSL_aECDSA:
- return "ECDHE_ECDSA";
- case SSL_aRSA:
- return "ECDHE_RSA";
- case SSL_aPSK:
- return "ECDHE_PSK";
- default:
- assert(0);
- return "UNKNOWN";
- }
-
- case SSL_kPSK:
- assert(cipher->algorithm_auth == SSL_aPSK);
- return "PSK";
-
- default:
- assert(0);
- return "UNKNOWN";
- }
-}
-
-static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
- switch (cipher->algorithm_enc) {
- case SSL_3DES:
- return "3DES_EDE_CBC";
- case SSL_RC4:
- return "RC4";
- case SSL_AES128:
- return "AES_128_CBC";
- case SSL_AES256:
- return "AES_256_CBC";
- case SSL_AES128GCM:
- return "AES_128_GCM";
- case SSL_AES256GCM:
- return "AES_256_GCM";
- case SSL_CHACHA20POLY1305:
- return "CHACHA20_POLY1305";
- break;
- default:
- assert(0);
- return "UNKNOWN";
- }
-}
-
-static const char *ssl_cipher_get_prf_name(const SSL_CIPHER *cipher) {
- if ((cipher->algorithm2 & TLS1_PRF) == TLS1_PRF) {
- /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
- * only ever MD5 or SHA-1. */
- switch (cipher->algorithm_mac) {
- case SSL_MD5:
- return "MD5";
- case SSL_SHA1:
- return "SHA";
- default:
- assert(0);
- return "UNKNOWN";
- }
- } else if (cipher->algorithm2 & TLS1_PRF_SHA256) {
- return "SHA256";
- } else if (cipher->algorithm2 & TLS1_PRF_SHA384) {
- return "SHA384";
- } else {
- assert(0);
- return "UNKNOWN";
- }
-}
-
-char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) {
- if (cipher == NULL) {
- return NULL;
- }
-
- const char *kx_name = SSL_CIPHER_get_kx_name(cipher);
- const char *enc_name = ssl_cipher_get_enc_name(cipher);
- const char *prf_name = ssl_cipher_get_prf_name(cipher);
-
- /* The final name is TLS_{kx_name}_WITH_{enc_name}_{prf_name}. */
- size_t len = 4 + strlen(kx_name) + 6 + strlen(enc_name) + 1 +
- strlen(prf_name) + 1;
- char *ret = OPENSSL_malloc(len);
- if (ret == NULL) {
- return NULL;
- }
- if (BUF_strlcpy(ret, "TLS_", len) >= len ||
- BUF_strlcat(ret, kx_name, len) >= len ||
- BUF_strlcat(ret, "_WITH_", len) >= len ||
- BUF_strlcat(ret, enc_name, len) >= len ||
- BUF_strlcat(ret, "_", len) >= len ||
- BUF_strlcat(ret, prf_name, len) >= len) {
- assert(0);
- OPENSSL_free(ret);
- return NULL;
- }
- assert(strlen(ret) + 1 == len);
- return ret;
-}
-
-/* number of bits for symmetric cipher */
-int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) {
- int ret = 0;
-
- if (c != NULL) {
- if (alg_bits != NULL) {
- *alg_bits = c->alg_bits;
- }
- ret = c->strength_bits;
- }
-
- return ret;
-}
-
-uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c) { return c->id; }
-
void *SSL_COMP_get_compression_methods(void) { return NULL; }
int SSL_COMP_add_compression_method(int id, void *cm) { return 1; }
const char *SSL_COMP_get_name(const void *comp) { return NULL; }
-/* For a cipher return the index corresponding to the certificate type */
-int ssl_cipher_get_cert_index(const SSL_CIPHER *c) {
- uint32_t alg_a = c->algorithm_auth;
+int ssl_cipher_get_cert_index(const SSL_CIPHER *cipher) {
+ uint32_t alg_a = cipher->algorithm_auth;
if (alg_a & SSL_aECDSA) {
return SSL_PKEY_ECC;
@@ -1366,9 +1352,6 @@
return -1;
}
-/* ssl_cipher_has_server_public_key returns 1 if |cipher| involves a server
- * public key in the key exchange, sent in a server Certificate message.
- * Otherwise it returns 0. */
int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher) {
/* PSK-authenticated ciphers do not use a public key, except for
* RSA_PSK. */
@@ -1381,12 +1364,6 @@
return 1;
}
-/* ssl_cipher_requires_server_key_exchange returns 1 if |cipher| requires a
- * ServerKeyExchange message. Otherwise it returns 0.
- *
- * Unlike ssl_cipher_has_server_public_key, some ciphers take optional
- * ServerKeyExchanges. PSK and RSA_PSK only use the ServerKeyExchange to
- * communicate a psk_identity_hint, so it is optional. */
int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
/* Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. */
if (cipher->algorithm_mkey & SSL_kDHE || cipher->algorithm_mkey & SSL_kECDHE) {
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 230424e..ee260ea 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1298,7 +1298,7 @@
STACK_OF(SSL_CIPHER) *sk;
sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
- &ctx->cipher_list_by_id, str, ctx->cert);
+ &ctx->cipher_list_by_id, str);
/* ssl_create_cipher_list may return an empty stack if it was unable to find
* a cipher matching the given rule string (for example if the rule string
* specifies a cipher which has been disabled). This is not an error as far
@@ -1317,8 +1317,7 @@
int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
STACK_OF(SSL_CIPHER) *sk;
- sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls11, NULL, str,
- ctx->cert);
+ sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls11, NULL, str);
if (sk == NULL) {
return 0;
} else if (sk_SSL_CIPHER_num(sk) == 0) {
@@ -1335,7 +1334,7 @@
STACK_OF(SSL_CIPHER) *sk;
sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
- &s->cipher_list_by_id, str, s->cert);
+ &s->cipher_list_by_id, str);
/* see comment in SSL_CTX_set_cipher_list */
if (sk == NULL) {
@@ -1815,8 +1814,7 @@
}
ssl_create_cipher_list(ret->method, &ret->cipher_list,
- &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST,
- ret->cert);
+ &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST);
if (ret->cipher_list == NULL ||
sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_LIBRARY_HAS_NO_CIPHERS);
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 8521de5..1d23815 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -244,7 +244,7 @@
/* Count number of digests and partition |secret| evenly. */
count = 0;
- for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
+ for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) {
if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) {
count++;
}
@@ -259,7 +259,7 @@
}
S1 = secret;
memset(out, 0, out_len);
- for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
+ for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) {
if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) {
/* If |count| is 2 and |secret_len| is odd, |secret| is partitioned into
* two halves with an overlapping byte. */
@@ -759,7 +759,7 @@
EVP_MD_CTX_init(&ctx);
- for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
+ for (i = 0; ssl_get_handshake_digest(&mask, &md, i); i++) {
size_t hash_size;
unsigned int digest_len;
EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];