| diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c | 
 | --- a/nss/lib/ssl/ssl3con.c	2014-01-17 18:46:51.999581198 -0800 | 
 | +++ b/nss/lib/ssl/ssl3con.c	2014-01-17 18:47:05.509804656 -0800 | 
 | @@ -3473,6 +3473,9 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffe | 
 |      case certificate_unknown: 	error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT; | 
 |  			        					  break; | 
 |      case illegal_parameter: 	error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break; | 
 | +    case inappropriate_fallback: | 
 | +        error = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT; | 
 | +        break; | 
 |   | 
 |      /* All alerts below are TLS only. */ | 
 |      case unknown_ca: 		error = SSL_ERROR_UNKNOWN_CA_ALERT;       break; | 
 | @@ -4986,6 +4989,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBo | 
 |      int              num_suites; | 
 |      int              actual_count = 0; | 
 |      PRBool           isTLS = PR_FALSE; | 
 | +    PRBool           requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE; | 
 |      PRInt32          total_exten_len = 0; | 
 |      unsigned         paddingExtensionLen; | 
 |      unsigned         numCompressionMethods; | 
 | @@ -5128,6 +5132,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBo | 
 |      } | 
 |   | 
 |      if (sid) { | 
 | +	requestingResume = PR_TRUE; | 
 |  	SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); | 
 |   | 
 |  	PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID, | 
 | @@ -5246,8 +5251,15 @@ ssl3_SendClientHello(sslSocket *ss, PRBo | 
 |      	if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } | 
 |      	return SECFailure;	/* count_cipher_suites has set error code. */ | 
 |      } | 
 | + | 
 | +    fallbackSCSV = ss->opt.enableFallbackSCSV && (!requestingResume || | 
 | +						  ss->version < sid->version); | 
 | +    /* make room for SCSV */ | 
 |      if (ss->ssl3.hs.sendingSCSV) { | 
 | -	++num_suites;   /* make room for SCSV */ | 
 | +	++num_suites; | 
 | +    } | 
 | +    if (fallbackSCSV) { | 
 | +	++num_suites; | 
 |      } | 
 |   | 
 |      /* count compression methods */ | 
 | @@ -5389,11 +5389,21 @@ ssl3_SendClientHello(sslSocket *ss, PRBo | 
 | 	    if (rv != SECSuccess) { | 
 | 		if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); } | 
 | 		return rv;	/* err set by ssl3_AppendHandshake* */ | 
 | 	    } | 
 | 	} | 
 |     } | 
 |  | 
 | +    if (fallbackSCSV) { | 
 | +	rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV, | 
 | +					sizeof(ssl3CipherSuite)); | 
 | +	if (rv != SECSuccess) { | 
 | +	    if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } | 
 | +	    return rv;	/* err set by ssl3_AppendHandshake* */ | 
 | +	} | 
 | +	actual_count++; | 
 | +    } | 
 | + | 
 |     /* if cards were removed or inserted between count_cipher_suites and | 
 |      * generating our list, detect the error here rather than send it off to | 
 |      * the server.. */ | 
 |     if (actual_count != num_suites) { | 
 | @@ -8084,6 +8105,19 @@ ssl3_HandleClientHello(sslSocket *ss, SS | 
 |  	goto loser;		/* malformed */ | 
 |      } | 
 |   | 
 | +    /* If the ClientHello version is less than our maximum version, check for a | 
 | +     * TLS_FALLBACK_SCSV and reject the connection if found. */ | 
 | +    if (ss->vrange.max > ss->clientHelloVersion) { | 
 | +	for (i = 0; i + 1 < suites.len; i += 2) { | 
 | +	    PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1]; | 
 | +	    if (suite_i != TLS_FALLBACK_SCSV) | 
 | +		continue; | 
 | +	    desc = inappropriate_fallback; | 
 | +	    errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT; | 
 | +	    goto alert_loser; | 
 | +	} | 
 | +    } | 
 | + | 
 |      /* grab the list of compression methods. */ | 
 |      rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length); | 
 |      if (rv != SECSuccess) { | 
 | diff -pu a/nss/lib/ssl/ssl3prot.h b/nss/lib/ssl/ssl3prot.h | 
 | --- a/nss/lib/ssl/ssl3prot.h	2014-01-17 17:59:03.242109996 -0800 | 
 | +++ b/nss/lib/ssl/ssl3prot.h	2014-01-17 18:47:05.509804656 -0800 | 
 | @@ -98,6 +98,7 @@ typedef enum { | 
 |      protocol_version        = 70, | 
 |      insufficient_security   = 71, | 
 |      internal_error          = 80, | 
 | +    inappropriate_fallback  = 86,	/* could also be sent for SSLv3 */ | 
 |      user_canceled           = 90, | 
 |      no_renegotiation        = 100, | 
 |   | 
 | diff -pu a/nss/lib/ssl/sslerr.h b/nss/lib/ssl/sslerr.h | 
 | --- a/nss/lib/ssl/sslerr.h	2014-01-17 17:59:03.242109996 -0800 | 
 | +++ b/nss/lib/ssl/sslerr.h	2014-01-17 18:47:05.509804656 -0800 | 
 | @@ -196,6 +196,7 @@ SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM | 
 |  SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 129), | 
 |  SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 130), | 
 |  SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 131), | 
 | +SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 132), | 
 |   | 
 |  SSL_ERROR_END_OF_LIST	/* let the c compiler determine the value of this. */ | 
 |  } SSLErrorCodes; | 
 | diff -pu a/nss/lib/ssl/SSLerrs.h b/nss/lib/ssl/SSLerrs.h | 
 | --- a/nss/lib/ssl/SSLerrs.h	2014-01-17 17:59:03.242109996 -0800 | 
 | +++ b/nss/lib/ssl/SSLerrs.h	2014-01-17 18:47:05.509804656 -0800 | 
 | @@ -421,3 +421,8 @@ ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (S | 
 |   | 
 |  ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 131), | 
 |  "The application could not get a TLS Channel ID.") | 
 | + | 
 | +ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 132), | 
 | +"The connection was using a lesser TLS version as a result of a previous" | 
 | +" handshake failure, but the server indicated that it should not have been" | 
 | +" needed.") | 
 | diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h | 
 | --- a/nss/lib/ssl/ssl.h	2014-01-17 18:46:51.999581198 -0800 | 
 | +++ b/nss/lib/ssl/ssl.h	2014-01-17 18:48:54.971613341 -0800 | 
 | @@ -183,6 +183,8 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF | 
 |   | 
 |  /* Request Signed Certificate Timestamps via TLS extension (client) */ | 
 |  #define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 27 | 
 | +#define SSL_ENABLE_FALLBACK_SCSV       28 /* Send fallback SCSV in | 
 | +                                           * handshakes. */ | 
 |   | 
 |  #ifdef SSL_DEPRECATED_FUNCTION  | 
 |  /* Old deprecated function names */ | 
 | diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h | 
 | --- a/nss/lib/ssl/sslimpl.h	2014-01-17 18:46:51.999581198 -0800 | 
 | +++ b/nss/lib/ssl/sslimpl.h	2014-01-17 18:51:17.963962287 -0800 | 
 | @@ -338,6 +338,7 @@ typedef struct sslOptionsStr { | 
 |      unsigned int enableNPN              : 1;  /* 26 */ | 
 |      unsigned int enableALPN             : 1;  /* 27 */ | 
 |      unsigned int enableSignedCertTimestamps : 1;  /* 28 */ | 
 | +    unsigned int enableFallbackSCSV     : 1;  /* 29 */ | 
 |  } sslOptions; | 
 |   | 
 |  typedef enum { sslHandshakingUndetermined = 0, | 
 | diff -pu a/nss/lib/ssl/sslproto.h b/nss/lib/ssl/sslproto.h | 
 | --- a/nss/lib/ssl/sslproto.h	2014-01-17 18:10:16.793281867 -0800 | 
 | +++ b/nss/lib/ssl/sslproto.h	2014-01-17 18:47:05.509804656 -0800 | 
 | @@ -172,6 +172,11 @@ | 
 |   */ | 
 |  #define TLS_EMPTY_RENEGOTIATION_INFO_SCSV	0x00FF | 
 |   | 
 | +/* TLS_FALLBACK_SCSV is a signaling cipher suite value that indicates that a | 
 | + * handshake is the result of TLS version fallback. This value is not IANA | 
 | + * assigned. */ | 
 | +#define TLS_FALLBACK_SCSV			0x5600 | 
 | + | 
 |  /* Cipher Suite Values starting with 0xC000 are defined in informational | 
 |   * RFCs. | 
 |   */ | 
 | diff -pu a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c | 
 | --- a/nss/lib/ssl/sslsock.c	2014-01-17 18:46:52.009581364 -0800 | 
 | +++ b/nss/lib/ssl/sslsock.c	2014-01-17 18:59:17.931852364 -0800 | 
 | @@ -88,7 +88,8 @@ static sslOptions ssl_defaults = { | 
 |      PR_FALSE,   /* enableOCSPStapling */ | 
 |      PR_TRUE,    /* enableNPN          */ | 
 |      PR_FALSE,   /* enableALPN         */ | 
 | -    PR_FALSE    /* enableSignedCertTimestamps */ | 
 | +    PR_FALSE,   /* enableSignedCertTimestamps */ | 
 | +    PR_FALSE    /* enableFallbackSCSV */ | 
 |  }; | 
 |   | 
 |  /* | 
 | @@ -792,6 +793,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh | 
 |  	ss->opt.enableSignedCertTimestamps = on; | 
 |  	break; | 
 |   | 
 | +      case SSL_ENABLE_FALLBACK_SCSV: | 
 | +       ss->opt.enableFallbackSCSV = on; | 
 | +       break; | 
 | + | 
 |        default: | 
 |  	PORT_SetError(SEC_ERROR_INVALID_ARGS); | 
 |  	rv = SECFailure; | 
 | @@ -867,6 +872,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh | 
 |      case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: | 
 |  	on = ss->opt.enableSignedCertTimestamps; | 
 |  	break; | 
 | +    case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break; | 
 |   | 
 |      default: | 
 |  	PORT_SetError(SEC_ERROR_INVALID_ARGS); | 
 | @@ -933,6 +939,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBo | 
 |      case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: | 
 |  	on = ssl_defaults.enableSignedCertTimestamps; | 
 |  	break; | 
 | +    case SSL_ENABLE_FALLBACK_SCSV: | 
 | +	on = ssl_defaults.enableFallbackSCSV; | 
 | +	break; | 
 |   | 
 |      default: | 
 |  	PORT_SetError(SEC_ERROR_INVALID_ARGS); | 
 | @@ -1112,6 +1121,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo | 
 |  	ssl_defaults.enableSignedCertTimestamps = on; | 
 |  	break; | 
 |   | 
 | +      case SSL_ENABLE_FALLBACK_SCSV: | 
 | +       ssl_defaults.enableFallbackSCSV = on; | 
 | +       break; | 
 | + | 
 |        default: | 
 |  	PORT_SetError(SEC_ERROR_INVALID_ARGS); | 
 |  	return SECFailure; |