Bug 1690111 - Improve nsIRandomGenerator APIs. r=mccr8,necko-reviewers,kershaw

Differential Revision: https://phabricator.services.mozilla.com/D185067
This commit is contained in:
Peter Van der Beken 2023-09-20 09:41:58 +00:00
parent 41381dd760
commit 08dd6a2c2b
8 changed files with 46 additions and 42 deletions

View File

@ -78,17 +78,13 @@ void Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
return;
}
uint8_t* buf;
nsresult rv = randomGenerator->GenerateRandomBytes(dataLen, &buf);
if (NS_FAILED(rv) || !buf) {
nsresult rv =
randomGenerator->GenerateRandomBytesInto(aArray.Data(), dataLen);
if (NS_FAILED(rv)) {
aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
return;
}
// Copy random bytes to ABV.
memcpy(aArray.Data(), buf, dataLen);
free(buf);
aRetval.set(view);
}

View File

@ -331,8 +331,7 @@ nsresult InternalResponse::GeneratePaddingInfo() {
MOZ_DIAGNOSTIC_ASSERT(randomGenerator);
uint8_t* buffer;
rv = randomGenerator->GenerateRandomBytes(sizeof(randomNumber), &buffer);
rv = randomGenerator->GenerateRandomBytesInto(randomNumber);
if (NS_WARN_IF(NS_FAILED(rv))) {
Maybe<uint64_t> maybeRandomNum = RandomUint64();
if (maybeRandomNum.isSome()) {
@ -342,9 +341,6 @@ nsresult InternalResponse::GeneratePaddingInfo() {
return rv;
}
memcpy(&randomNumber, buffer, sizeof(randomNumber));
free(buffer);
mPaddingInfo.emplace(randomNumber % kMaxRandomNumber);
return rv;

View File

@ -546,16 +546,11 @@ void ReportingHeader::GetEndpointForReportInternal(
uint32_t randomNumber = 0;
uint8_t* buffer;
nsresult rv =
randomGenerator->GenerateRandomBytes(sizeof(randomNumber), &buffer);
nsresult rv = randomGenerator->GenerateRandomBytesInto(randomNumber);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
memcpy(&randomNumber, buffer, sizeof(randomNumber));
free(buffer);
totalWeight = randomNumber % totalWeight;
const auto [begin, end] = aGroup.mEndpoints.NonObservingRange();

View File

@ -4,6 +4,10 @@
#include "nsISupports.idl"
%{C++
#include <type_traits>
%}
/**
* Interface used to generate random data.
*
@ -21,4 +25,22 @@ interface nsIRandomGenerator : nsISupports {
*/
void generateRandomBytes(in unsigned long aLength,
[retval, array, size_is(aLength)] out octet aBuffer);
/**
* Fills aBuffer with random bytes.
*
* @param aBuffer
* A buffer to fill with random bytes.
* @param aLength
* Length of aBuffer.
*/
void generateRandomBytesInto([array, size_is(aLength)] in octet aBuffer,
in unsigned long aLength);
%{C++
template<typename T>
std::enable_if_t<!std::is_pointer_v<T>, nsresult> GenerateRandomBytesInto(T& aResult) {
return GenerateRandomBytesInto(reinterpret_cast<uint8_t*>(&aResult), sizeof(T));
}
%}
};

View File

@ -2134,10 +2134,8 @@ void WebSocketChannel::PrimeNewOutgoingMessage() {
if (!mIsServerSide) {
// Perform the sending mask. Never use a zero mask
do {
uint8_t* buffer;
static_assert(4 == sizeof(mask), "Size of the mask should be equal to 4");
nsresult rv =
mRandomGenerator->GenerateRandomBytes(sizeof(mask), &buffer);
nsresult rv = mRandomGenerator->GenerateRandomBytesInto(mask);
if (NS_FAILED(rv)) {
LOG(
("WebSocketChannel::PrimeNewOutgoingMessage(): "
@ -2146,8 +2144,6 @@ void WebSocketChannel::PrimeNewOutgoingMessage() {
AbortSession(rv);
return;
}
memcpy(&mask, buffer, sizeof(mask));
free(buffer);
} while (!mask);
NetworkEndian::writeUint32(payload - sizeof(uint32_t), mask);
}

View File

@ -9,6 +9,7 @@
#include "pk11pub.h"
#include "prerror.h"
#include "secerr.h"
#include "mozilla/UniquePtrExtensions.h"
NS_IMPL_ISUPPORTS(nsRandomGenerator, nsIRandomGenerator)
@ -17,20 +18,24 @@ nsRandomGenerator::GenerateRandomBytes(uint32_t aLength, uint8_t** aBuffer) {
NS_ENSURE_ARG_POINTER(aBuffer);
*aBuffer = nullptr;
mozilla::UniqueFreePtr<uint8_t> buf(
static_cast<uint8_t*>(moz_xmalloc(aLength)));
nsresult rv = GenerateRandomBytesInto(buf.get(), aLength);
NS_ENSURE_SUCCESS(rv, rv);
*aBuffer = buf.release();
return NS_OK;
}
NS_IMETHODIMP
nsRandomGenerator::GenerateRandomBytesInto(uint8_t* aBuffer, uint32_t aLength) {
NS_ENSURE_ARG_POINTER(aBuffer);
mozilla::UniquePK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
return NS_ERROR_FAILURE;
}
auto buf = static_cast<uint8_t*>(moz_xmalloc(aLength));
SECStatus srv = PK11_GenerateRandomOnSlot(slot.get(), buf, aLength);
if (srv != SECSuccess) {
free(buf);
return NS_ERROR_FAILURE;
}
*aBuffer = buf;
return NS_OK;
SECStatus srv = PK11_GenerateRandomOnSlot(slot.get(), aBuffer, aLength);
return srv == SECSuccess ? NS_OK : NS_ERROR_FAILURE;
}

View File

@ -21,17 +21,11 @@ int64_t RelativeTimeline::GetRandomTimelineSeed() {
return mRandomTimelineSeed;
}
uint8_t* buffer = nullptr;
rv = randomGenerator->GenerateRandomBytes(sizeof(mRandomTimelineSeed),
&buffer);
rv = randomGenerator->GenerateRandomBytesInto(mRandomTimelineSeed);
if (NS_WARN_IF(NS_FAILED(rv))) {
mRandomTimelineSeed = rand();
return mRandomTimelineSeed;
}
memcpy(&mRandomTimelineSeed, buffer, sizeof(mRandomTimelineSeed));
MOZ_ASSERT(buffer);
free(buffer);
}
return mRandomTimelineSeed;
}

View File

@ -464,7 +464,7 @@ nsresult nsRFPService::RandomMidpoint(long long aClampedTimeUSec,
}
if (MOZ_UNLIKELY(!sSecretMidpointSeed.compareExchange(nullptr, temp))) {
// Some other thread initted this first, never mind!
delete[] temp;
free(temp);
}
}