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:
wtc%google.com
2009-10-16 17:45:36 +00:00
parent b69b25ac84
commit e8653a0f01
6 changed files with 38 additions and 10 deletions

View File

@@ -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);

View File

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

View File

@@ -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));

View File

@@ -241,3 +241,9 @@ UTIL_SetForkState;
;+ local:
;+ *;
;+};
;+NSSUTIL_3.12.5 { # NSS Utilities 3.12.5 release
;+ global:
NSS_SecureMemcmp;
;+ local:
;+ *;
;+};

View File

@@ -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;
}

View File

@@ -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_ */