Prevent Nonce Flood

From the Widevine CDM repository:
https://widevine-internal-review.googlesource.com/#/c/9182/

This CL adds a test to verify that at most 20 nonces may be created in
one second.  This should prevent the replay attack that an
appplication could do by generating large quantities of nonces until
it finds a repeat.

I've also updated the Level 3 and reference implementations.

This feature is required for OEMCrypto version 9.

Change-Id: Ia86323133810fcbbd79d7bb27bd5a004d7c87314
This commit is contained in:
Fred Gylys-Colwell
2014-03-15 14:44:05 -07:00
parent 71e9cacfe2
commit fec3e87167
2 changed files with 72 additions and 3 deletions

View File

@@ -16,6 +16,7 @@
#include <openssl/sha.h>
#include <stdint.h>
#include <sys/types.h>
#include <time.h>
#include <algorithm>
#include <map>
#include <string>
@@ -905,9 +906,17 @@ class Session {
}
}
void GenerateNonce(uint32_t* nonce) {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GenerateNonce(session_id(), nonce));
void GenerateNonce(uint32_t* nonce, int* error_counter = NULL) {
if (OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(session_id(), nonce)) {
return;
}
if (error_counter) {
(*error_counter)++;
} else {
sleep(1); // wait a second, then try again.
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GenerateNonce(session_id(), nonce));
}
}
void FillDefaultContext(vector<uint8_t>* mac_context,
@@ -1729,6 +1738,49 @@ TEST_F(OEMCryptoClientTest, GenerateTwoNonces) {
testTearDown();
}
TEST_F(OEMCryptoClientTest, PreventNonceFlood) {
Session& s = createSession("ONE");
testSetUp();
s.open();
int error_counter = 0;
uint32_t nonce;
// More than 20 nonces should generate an error.
// To allow for some slop, we actually test for more than 40.
for (int i = 0; i < 60; i++) {
s.GenerateNonce(&nonce, &error_counter);
}
ASSERT_LE(20, error_counter);
error_counter = 0;
sleep(2); // After a pause, we should be able to regenerate nonces.
s.GenerateNonce(&nonce, &error_counter);
ASSERT_EQ(0, error_counter);
s.close();
testTearDown();
}
// Prevent a nonce flood even if each nonce is in a different session.
TEST_F(OEMCryptoClientTest, PreventNonceFlood2) {
Session& s = createSession("ONE");
testSetUp();
int error_counter = 0;
uint32_t nonce;
// More than 20 nonces should generate an error.
// To allow for some slop, we actually test for more than 40.
for (int i = 0; i < 60; i++) {
s.open();
s.GenerateNonce(&nonce, &error_counter);
s.close();
}
ASSERT_LE(20, error_counter);
error_counter = 0;
sleep(2); // After a pause, we should be able to regenerate nonces.
s.open();
s.GenerateNonce(&nonce, &error_counter);
s.close();
ASSERT_EQ(0, error_counter);
testTearDown();
}
TEST_F(OEMCryptoClientTest, GenerateDerivedKeys) {
Session& s = createSession("ONE");
testSetUp();