Commit c0d531ae authored by Franziskus Kiefer's avatar Franziskus Kiefer

Bug 1393329 - zero-check x25519 result, r=bbeurdouche,ttaubert

Differential Revision: https://nss-review.dev.mozaws.net/D420

--HG--
extra : rebase_source : 5c4a01a93f77fddd97eda020eb4ca0c9913a81f5
extra : amend_source : 99b726d7bd786929cf381341c4f9f4fb7e6b5eb3
extra : histedit_source : 372265c4adfafc61c4391228ed809f9c8388cfeb%2Cb6f7f74c7a60d0f5c9a4cca124b45660aa6f1bc0
parent 5b68640f
......@@ -10,6 +10,8 @@ CPPSRCS = \
util_utf8_unittest.cc \
util_b64_unittest.cc \
util_pkcs11uri_unittest.cc \
util_aligned_malloc_unittest.cc \
util_memcmpzero_unittest.cc \
$(NULL)
INCLUDES += \
......
......@@ -15,6 +15,7 @@
'util_b64_unittest.cc',
'util_pkcs11uri_unittest.cc',
'util_aligned_malloc_unittest.cc',
'util_memcmpzero_unittest.cc',
'<(DEPTH)/gtests/common/gtests.cc',
],
'dependencies': [
......
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "scoped_ptrs_util.h"
namespace nss_test {
class MemcmpZeroTest : public ::testing::Test {
protected:
unsigned int test_memcmp_zero(const std::vector<uint8_t> &mem) {
return NSS_SecureMemcmpZero(mem.data(), mem.size());
};
};
TEST_F(MemcmpZeroTest, TestMemcmpZeroTrue) {
unsigned int rv = test_memcmp_zero(std::vector<uint8_t>(37, 0));
EXPECT_EQ(0U, rv);
}
TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse5) {
std::vector<uint8_t> vec(37, 0);
vec[5] = 1;
unsigned int rv = test_memcmp_zero(vec);
EXPECT_NE(0U, rv);
}
TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse37) {
std::vector<uint8_t> vec(37, 0);
vec[vec.size() - 1] = 0xFF;
unsigned int rv = test_memcmp_zero(vec);
EXPECT_NE(0U, rv);
}
TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse0) {
std::vector<uint8_t> vec(37, 0);
vec[0] = 1;
unsigned int rv = test_memcmp_zero(vec);
EXPECT_NE(0U, rv);
}
} // namespace nss_test
......@@ -115,5 +115,9 @@ ec_Curve25519_pt_mul(SECItem *X, SECItem *k, SECItem *P)
px = P->data;
}
return ec_Curve25519_mul(X->data, k->data, px);
SECStatus rv = ec_Curve25519_mul(X->data, k->data, px);
if (NSS_SecureMemcmpZero(X->data, X->len) == 0) {
return SECFailure;
}
return rv;
}
......@@ -179,6 +179,7 @@ STUB_DECLARE(void, SECITEM_FreeItem_Util, (SECItem * zap, PRBool freeit));
STUB_DECLARE(void, SECITEM_ZfreeItem_Util, (SECItem * zap, PRBool freeit));
STUB_DECLARE(SECOidTag, SECOID_FindOIDTag_Util, (const SECItem *oid));
STUB_DECLARE(int, NSS_SecureMemcmp, (const void *a, const void *b, size_t n));
STUB_DECLARE(unsigned int, NSS_SecureMemcmpZero, (const void *mem, size_t n));
#define PORT_ZNew_stub(type) (type *)PORT_ZAlloc_stub(sizeof(type))
#define PORT_New_stub(type) (type *)PORT_Alloc_stub(sizeof(type))
......@@ -643,6 +644,13 @@ NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n)
abort();
}
extern unsigned int
NSS_SecureMemcmpZero_stub(const void *mem, size_t n)
{
STUB_SAFE_CALL2(NSS_SecureMemcmpZero, mem, n);
abort();
}
#ifdef FREEBL_NO_WEAK
static const char *nsprLibName = SHLIB_PREFIX "nspr4." SHLIB_SUFFIX;
......@@ -695,6 +703,7 @@ freebl_InitNSSUtil(void *lib)
STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util);
STUB_FETCH_FUNCTION(SECOID_FindOIDTag_Util);
STUB_FETCH_FUNCTION(NSS_SecureMemcmp);
STUB_FETCH_FUNCTION(NSS_SecureMemcmpZero);
return SECSuccess;
}
......
......@@ -40,6 +40,7 @@
#define SECITEM_ZfreeItem SECITEM_ZfreeItem_stub
#define SECOID_FindOIDTag SECOID_FindOIDTag_stub
#define NSS_SecureMemcmp NSS_SecureMemcmp_stub
#define NSS_SecureMemcmpZero NSS_SecureMemcmpZero_stub
#define PR_Assert PR_Assert_stub
#define PR_Access PR_Access_stub
......
......@@ -311,6 +311,7 @@ PK11URI_GetQueryAttribute;
;+ global:
PORT_ZAllocAligned_Util;
PORT_ZAllocAlignedOffset_Util;
NSS_SecureMemcmpZero;
;+ local:
;+ *;
;+};
......@@ -780,3 +780,18 @@ NSS_SecureMemcmp(const void *ia, const void *ib, size_t n)
return r;
}
/*
* Perform a constant-time check if a memory region is all 0. The return value
* is 0 if the memory region is all zero.
*/
unsigned int
NSS_SecureMemcmpZero(const void *mem, size_t n)
{
PRUint8 zero = 0;
int i;
for (i = 0; i < n; ++i) {
zero |= *(PRUint8 *)((uintptr_t)mem + i);
}
return zero;
}
......@@ -252,6 +252,7 @@ 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);
extern unsigned int NSS_SecureMemcmpZero(const void *mem, size_t n);
/*
* Load a shared library called "newShLibName" in the same directory as
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment