Bug 522580: Add the NSS_SecureMemcmp function that performs a constant-time
compare of two memory regions, and use it in libSSL for comparing secret data. The patch is contributed by Adam Langley <agl@chromium.org> of Google. r=wtc,nelson. Modified Files: lib/ssl/ssl3con.c lib/ssl/sslcon.c lib/ssl/sslgathr.c lib/util/nssutil.def lib/util/secport.c lib/util/secport.h git-svn-id: svn://10.0.0.236/trunk@258699 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: ssl3con.c,v 1.116 2009-03-04 21:57:18 nelson%bolyard.com Exp $ */
|
||||
/* $Id: ssl3con.c,v 1.117 2009-10-16 17:45:35 wtc%google.com Exp $ */
|
||||
|
||||
#include "cert.h"
|
||||
#include "ssl.h"
|
||||
@@ -7723,7 +7723,7 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
|
||||
rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer,
|
||||
hashes, &tlsFinished);
|
||||
if (rv != SECSuccess ||
|
||||
0 != PORT_Memcmp(&tlsFinished, b, length)) {
|
||||
0 != NSS_SecureMemcmp(&tlsFinished, b, length)) {
|
||||
(void)SSL3_SendAlert(ss, alert_fatal, decrypt_error);
|
||||
PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
return SECFailure;
|
||||
@@ -7735,7 +7735,7 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (0 != PORT_Memcmp(hashes, b, length)) {
|
||||
if (0 != NSS_SecureMemcmp(hashes, b, length)) {
|
||||
(void)ssl3_HandshakeFailure(ss);
|
||||
PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
return SECFailure;
|
||||
@@ -8286,7 +8286,8 @@ const ssl3BulkCipherDef *cipher_def;
|
||||
|
||||
/* Check the MAC */
|
||||
if (hashBytes != (unsigned)crSpec->mac_size || padIsBad ||
|
||||
PORT_Memcmp(databuf->buf + databuf->len, hash, crSpec->mac_size) != 0) {
|
||||
NSS_SecureMemcmp(databuf->buf + databuf->len, hash,
|
||||
crSpec->mac_size) != 0) {
|
||||
/* must not hold spec lock when calling SSL3_SendAlert. */
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: sslcon.c,v 1.36 2009-03-04 21:57:18 nelson%bolyard.com Exp $ */
|
||||
/* $Id: sslcon.c,v 1.37 2009-10-16 17:45:35 wtc%google.com Exp $ */
|
||||
|
||||
#include "nssrenam.h"
|
||||
#include "cert.h"
|
||||
@@ -2731,7 +2731,8 @@ ssl2_HandleVerifyMessage(sslSocket *ss)
|
||||
DUMP_MSG(29, (ss, data, ss->gs.recordLen));
|
||||
if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
|
||||
(data[0] != SSL_MT_SERVER_VERIFY) ||
|
||||
PORT_Memcmp(data+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES)) {
|
||||
NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge,
|
||||
SSL_CHALLENGE_BYTES)) {
|
||||
/* Bad server */
|
||||
PORT_SetError(SSL_ERROR_BAD_SERVER);
|
||||
goto loser;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: sslgathr.c,v 1.9 2007-07-06 03:16:54 julien.pierre.bugs%sun.com Exp $ */
|
||||
/* $Id: sslgathr.c,v 1.10 2009-10-16 17:45:35 wtc%google.com Exp $ */
|
||||
#include "cert.h"
|
||||
#include "ssl.h"
|
||||
#include "sslimpl.h"
|
||||
@@ -309,7 +309,7 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
||||
|
||||
ssl_ReleaseSpecReadLock(ss); /******************************/
|
||||
|
||||
if (PORT_Memcmp(mac, pBuf, macLen) != 0) {
|
||||
if (NSS_SecureMemcmp(mac, pBuf, macLen) != 0) {
|
||||
/* MAC's didn't match... */
|
||||
SSL_DBG(("%d: SSL[%d]: mac check failed, seq=%d",
|
||||
SSL_GETPID(), ss->fd, ss->sec.rcvSequence));
|
||||
|
||||
@@ -241,3 +241,9 @@ UTIL_SetForkState;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+NSSUTIL_3.12.5 { # NSS Utilities 3.12.5 release
|
||||
;+ global:
|
||||
NSS_SecureMemcmp;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
*
|
||||
* NOTE - These are not public interfaces
|
||||
*
|
||||
* $Id: secport.c,v 1.24 2009-07-30 23:28:21 nelson%bolyard.com Exp $
|
||||
* $Id: secport.c,v 1.25 2009-10-16 17:45:36 wtc%google.com Exp $
|
||||
*/
|
||||
|
||||
#include "seccomon.h"
|
||||
@@ -667,3 +667,21 @@ NSS_PutEnv(const char * envVarName, const char * envValue)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a constant-time compare of two memory regions. The return value is
|
||||
* 0 if the memory regions are equal and non-zero otherwise.
|
||||
*/
|
||||
int
|
||||
NSS_SecureMemcmp(const void *ia, const void *ib, size_t n)
|
||||
{
|
||||
const unsigned char *a = (const unsigned char*) ia;
|
||||
const unsigned char *b = (const unsigned char*) ib;
|
||||
size_t i;
|
||||
unsigned char r = 0;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
r |= *a++ ^ *b++;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
/*
|
||||
* secport.h - portability interfaces for security libraries
|
||||
*
|
||||
* $Id: secport.h,v 1.21 2009-04-08 01:07:00 julien.pierre.boogz%sun.com Exp $
|
||||
* $Id: secport.h,v 1.22 2009-10-16 17:45:36 wtc%google.com Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SECPORT_H_
|
||||
@@ -240,6 +240,8 @@ sec_port_iso88591_utf8_conversion_function
|
||||
|
||||
extern int NSS_PutEnv(const char * envVarName, const char * envValue);
|
||||
|
||||
extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _SECPORT_H_ */
|
||||
|
||||
Reference in New Issue
Block a user