summaryrefslogtreecommitdiff
path: root/app/openssl/ssl/s3_srvr.c
diff options
context:
space:
mode:
authorParménides GV <parmegv@sdf.org>2014-12-15 16:22:58 +0100
committerParménides GV <parmegv@sdf.org>2014-12-15 16:22:58 +0100
commit18fef7c99aa36b3e5622b3865f36d78d0879e92d (patch)
tree7a04fc87318d5008bbc1f1ac145ebb505bb5238c /app/openssl/ssl/s3_srvr.c
parent56fe0400b8983ce57112ed5a0f993985a87741c0 (diff)
parent33c5958a18599267820f73b151d8161d83f93d88 (diff)
Merge branch 'research/Test-on-Android-5-#6543' into develop
Diffstat (limited to 'app/openssl/ssl/s3_srvr.c')
-rw-r--r--app/openssl/ssl/s3_srvr.c123
1 files changed, 68 insertions, 55 deletions
diff --git a/app/openssl/ssl/s3_srvr.c b/app/openssl/ssl/s3_srvr.c
index f83c9366..a42fc9e3 100644
--- a/app/openssl/ssl/s3_srvr.c
+++ b/app/openssl/ssl/s3_srvr.c
@@ -154,6 +154,7 @@
#include <stdio.h>
#include "ssl_locl.h"
#include "kssl_lcl.h"
+#include "../crypto/constant_time_locl.h"
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include <openssl/objects.h>
@@ -414,11 +415,10 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SW_CERT_B:
/* Check if it is anon DH or anon ECDH, */
/* non-RSA PSK or KRB5 or SRP */
- if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+ if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aKRB5|SSL_aSRP))
/* Among PSK ciphersuites only RSA_PSK uses server certificate */
&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK &&
- !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSA))
- && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
+ !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSA)))
{
ret=ssl3_send_server_certificate(s);
if (ret <= 0) goto end;
@@ -524,7 +524,9 @@ int ssl3_accept(SSL *s)
* (against the specs, but s3_clnt.c accepts this for SSL 3) */
!(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
/* never request cert in Kerberos ciphersuites */
- (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
+ (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) ||
+ /* don't request certificate for SRP auth */
+ (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
/* With normal PSK Certificates and
* Certificate Requests are omitted */
|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
@@ -1905,7 +1907,7 @@ int ssl3_send_server_key_exchange(SSL *s)
n+=2+nr[i];
}
- if (!(alg_a & SSL_aNULL)
+ if (!(alg_a & (SSL_aNULL|SSL_aSRP))
/* Among PSK ciphersuites only RSA uses a certificate */
&& !((alg_a & SSL_aPSK) && !(alg_k & SSL_kRSA)))
{
@@ -2325,6 +2327,10 @@ int ssl3_get_client_key_exchange(SSL *s)
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA)
{
+ unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
+ int decrypt_len;
+ unsigned char decrypt_good, version_good;
+
/* FIX THIS UP EAY EAY EAY EAY */
if (s->s3->tmp.use_rsa_tmp)
{
@@ -2372,54 +2378,61 @@ int ssl3_get_client_key_exchange(SSL *s)
n=i;
}
- i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
-
- al = -1;
-
- if (i != SSL_MAX_MASTER_KEY_LENGTH)
- {
- al=SSL_AD_DECODE_ERROR;
- /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
- }
+ /* We must not leak whether a decryption failure occurs because
+ * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
+ * RFC 2246, section 7.4.7.1). The code follows that advice of
+ * the TLS RFC and generates a random premaster secret for the
+ * case that the decrypt fails. See
+ * https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
- if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
- {
- /* The premaster secret must contain the same version number as the
- * ClientHello to detect version rollback attacks (strangely, the
- * protocol does not offer such protection for DH ciphersuites).
- * However, buggy clients exist that send the negotiated protocol
- * version instead if the server does not support the requested
- * protocol version.
- * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
- if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
- (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
- {
- al=SSL_AD_DECODE_ERROR;
- /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
-
- /* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
- * (http://eprint.iacr.org/2003/052/) exploits the version
- * number check as a "bad version oracle" -- an alert would
- * reveal that the plaintext corresponding to some ciphertext
- * made up by the adversary is properly formatted except
- * that the version number is wrong. To avoid such attacks,
- * we should treat this just like any other decryption error. */
- }
+ /* should be RAND_bytes, but we cannot work around a failure. */
+ if (RAND_pseudo_bytes(rand_premaster_secret,
+ sizeof(rand_premaster_secret)) <= 0)
+ goto err;
+ decrypt_len = RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
+ ERR_clear_error();
+
+ /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH.
+ * decrypt_good will be 0xff if so and zero otherwise. */
+ decrypt_good = constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);
+
+ /* If the version in the decrypted pre-master secret is correct
+ * then version_good will be 0xff, otherwise it'll be zero.
+ * The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
+ * (http://eprint.iacr.org/2003/052/) exploits the version
+ * number check as a "bad version oracle". Thus version checks
+ * are done in constant time and are treated like any other
+ * decryption error. */
+ version_good = constant_time_eq_8(p[0], (unsigned)(s->client_version>>8));
+ version_good &= constant_time_eq_8(p[1], (unsigned)(s->client_version&0xff));
+
+ /* The premaster secret must contain the same version number as
+ * the ClientHello to detect version rollback attacks
+ * (strangely, the protocol does not offer such protection for
+ * DH ciphersuites). However, buggy clients exist that send the
+ * negotiated protocol version instead if the server does not
+ * support the requested protocol version. If
+ * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
+ if (s->options & SSL_OP_TLS_ROLLBACK_BUG)
+ {
+ unsigned char workaround_good;
+ workaround_good = constant_time_eq_8(p[0], (unsigned)(s->version>>8));
+ workaround_good &= constant_time_eq_8(p[1], (unsigned)(s->version&0xff));
+ version_good |= workaround_good;
+ }
+
+ /* Both decryption and version must be good for decrypt_good
+ * to remain non-zero (0xff). */
+ decrypt_good &= version_good;
+
+ /* Now copy rand_premaster_secret over p using
+ * decrypt_good_mask. */
+ for (i = 0; i < (int) sizeof(rand_premaster_secret); i++)
+ {
+ p[i] = constant_time_select_8(decrypt_good, p[i],
+ rand_premaster_secret[i]);
}
- if (al != -1)
- {
- /* Some decryption failure -- use random value instead as countermeasure
- * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
- * (see RFC 2246, section 7.4.7.1). */
- ERR_clear_error();
- i = SSL_MAX_MASTER_KEY_LENGTH;
- p[0] = s->client_version >> 8;
- p[1] = s->client_version & 0xff;
- if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
- goto err;
- }
-
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
@@ -2837,7 +2850,7 @@ int ssl3_get_client_key_exchange(SSL *s)
/* ECDHE PSK ciphersuites from RFC 5489 */
if ((alg_a & SSL_aPSK) && psk_len != 0)
{
- pre_ms_len = 2+psk_len+2+i;
+ pre_ms_len = 2+i+2+psk_len;
pre_ms = OPENSSL_malloc(pre_ms_len);
if (pre_ms == NULL)
{
@@ -2847,11 +2860,11 @@ int ssl3_get_client_key_exchange(SSL *s)
}
memset(pre_ms, 0, pre_ms_len);
t = pre_ms;
- s2n(psk_len, t);
- memcpy(t, psk, psk_len);
- t += psk_len;
s2n(i, t);
memcpy(t, p, i);
+ t += i;
+ s2n(psk_len, t);
+ memcpy(t, psk, psk_len);
s->session->master_key_length = s->method->ssl3_enc \
-> generate_master_secret(s,
s->session->master_key, pre_ms, pre_ms_len);
@@ -3009,7 +3022,7 @@ int ssl3_get_cert_verify(SSL *s)
SSL3_ST_SR_CERT_VRFY_A,
SSL3_ST_SR_CERT_VRFY_B,
-1,
- 516, /* Enough for 4096 bit RSA key with TLS v1.2 */
+ SSL3_RT_MAX_PLAIN_LENGTH,
&ok);
if (!ok) return((int)n);