Files
odkitee/oemcrypto_ta/oemcrypto_nonce_table.c
2020-07-24 12:03:58 -07:00

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