This patch adds a suite of tests for OEMCrypto that verifying buffer overflow and off-by-one errors. The reference code has also been updated to pass these tests. The ODK library and the OEMCrypto API have not changed since the release of version 16.4.
47 lines
1.6 KiB
C++
47 lines
1.6 KiB
C++
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine License
|
|
// Agreement.
|
|
|
|
#ifndef WVCDM_UTIL_ADVANCE_IV_CTR_H_
|
|
#define WVCDM_UTIL_ADVANCE_IV_CTR_H_
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include "string_conversions.h"
|
|
|
|
namespace wvcdm {
|
|
|
|
// Advance an IV according to ISO-CENC's CTR modes. The lower half of the IV is
|
|
// split off and treated as an unsigned 64-bit integer, then incremented by the
|
|
// number of complete crypto blocks decrypted. The resulting value is then
|
|
// copied back into the IV over the previous lower half.
|
|
inline void AdvanceIvCtr(uint8_t (*subsample_iv)[16], size_t bytes) {
|
|
constexpr size_t kAesBlockSize = 16;
|
|
constexpr size_t kIvSize = kAesBlockSize;
|
|
constexpr size_t kCounterIndex = kIvSize / 2;
|
|
constexpr size_t kCounterSize = kIvSize / 2;
|
|
|
|
uint64_t counter;
|
|
|
|
static_assert(
|
|
sizeof(*subsample_iv) == kIvSize,
|
|
"The subsample_iv field is no longer the length of an AES-128 IV.");
|
|
static_assert(sizeof(counter) == kCounterSize,
|
|
"A uint64_t failed to be half the size of an AES-128 IV.");
|
|
|
|
// Defensive copy because the elements of the array may not be properly
|
|
// aligned
|
|
memcpy(&counter, &(*subsample_iv)[kCounterIndex], kCounterSize);
|
|
|
|
const size_t increment =
|
|
bytes / kAesBlockSize; // The truncation here is intentional
|
|
counter = htonll64(ntohll64(counter) + increment);
|
|
|
|
memcpy(&(*subsample_iv)[kCounterIndex], &counter, kCounterSize);
|
|
}
|
|
|
|
} // namespace wvcdm
|
|
|
|
#endif // WVCDM_UTIL_ADVANCE_IV_CTR_H_
|