82 lines
2.3 KiB
C
82 lines
2.3 KiB
C
/* Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
|
source code may only be used and distributed under the Widevine Master
|
|
License Agreement. */
|
|
|
|
#include "oemcrypto_nonce_table.h"
|
|
|
|
#include "stddef.h"
|
|
|
|
#include "assert_interface.h"
|
|
|
|
void AddNonce(NonceTable* nonce_table, uint32_t nonce) {
|
|
ASSERT(nonce_table != NULL, "nonce_table is NULL");
|
|
int new_slot = -1;
|
|
int oldest_slot = -1;
|
|
|
|
/* Flush any nonce_table->nonces that have been checked but not flushed.
|
|
After flush, nonce_table->nonces will be either valid or invalid. */
|
|
FlushNonces(nonce_table);
|
|
|
|
for (int i = 0; i < NONCE_TABLE_SIZE; i++) {
|
|
/* Increase nonce_table->age of all valid nonce_table->nonces. */
|
|
if (nonce_table->state[i] == NT_STATE_VALID) {
|
|
nonce_table->age[i]++;
|
|
if (oldest_slot == -1) {
|
|
oldest_slot = i;
|
|
} else {
|
|
if (nonce_table->age[i] > nonce_table->age[oldest_slot]) {
|
|
oldest_slot = i;
|
|
}
|
|
}
|
|
} else {
|
|
if (new_slot == -1) {
|
|
nonce_table->age[i] = 0;
|
|
nonce_table->nonces[i] = nonce;
|
|
nonce_table->state[i] = NT_STATE_VALID;
|
|
new_slot = i;
|
|
}
|
|
}
|
|
}
|
|
if (new_slot == -1) {
|
|
/* reuse oldest */
|
|
ASSERT(oldest_slot != -1, "oldest_slot is -1");
|
|
int i = oldest_slot;
|
|
nonce_table->age[i] = 0;
|
|
nonce_table->nonces[i] = nonce;
|
|
nonce_table->state[i] = NT_STATE_VALID;
|
|
}
|
|
}
|
|
|
|
bool CheckNonce(NonceTable* nonce_table, uint32_t nonce) {
|
|
ASSERT(nonce_table != NULL, "nonce_table is NULL");
|
|
for (int i = 0; i < NONCE_TABLE_SIZE; i++) {
|
|
if (nonce_table->state[i] != NT_STATE_INVALID) {
|
|
if (nonce_table->nonces[i] == nonce) {
|
|
nonce_table->state[i] = NT_STATE_FLUSH_PENDING;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool NonceCollision(NonceTable* nonce_table, uint32_t nonce) {
|
|
ASSERT(nonce_table != NULL, "nonce_table is NULL");
|
|
for (int i = 0; i < NONCE_TABLE_SIZE; i++) {
|
|
if (nonce_table->nonces[i] == nonce &&
|
|
nonce_table->state[i] != NT_STATE_INVALID) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void FlushNonces(NonceTable* nonce_table) {
|
|
ASSERT(nonce_table != NULL, "nonce_table is NULL");
|
|
for (int i = 0; i < NONCE_TABLE_SIZE; i++) {
|
|
if (nonce_table->state[i] == NT_STATE_FLUSH_PENDING) {
|
|
nonce_table->state[i] = NT_STATE_INVALID;
|
|
}
|
|
}
|
|
}
|