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];