126 lines
5.3 KiB
Markdown
126 lines
5.3 KiB
Markdown
# OEMCrypto Unit Tests
|
|
|
|
## Basic Functionality Tests
|
|
|
|
Most unit tests in this category verify that the basic functionality of opening
|
|
sessions, initializing and terminating the system, and reporting status work
|
|
correctly.
|
|
|
|
## Decrypt Tests
|
|
|
|
The decrypt tests verify that encrypted data is correctly decrypted with the
|
|
desired key. These tests cover a large variety of patterns, sample sizes, and
|
|
subsample sizes.
|
|
|
|
## Secure Buffers
|
|
|
|
If OEMCrypto implements the function `OEMCrypto_AllocateSecureBuffer`, then all
|
|
of the decrypt tests will also run with the output buffer being a secure
|
|
buffer. If the function `OEMCrypto_SupportsDecryptHash` returns
|
|
`OEMCrypto_CRC_Clear_Buffer`, then the secure buffer decryption will be verified
|
|
with the CRC32 hash of the input data.
|
|
|
|
## Usage Table Tests
|
|
|
|
Usage table tests verify that the usage table is correctly procesed. The usage
|
|
table is used to control reloading keys for offline playback, and for reporting
|
|
secure stops for online playback.
|
|
|
|
## Duration Tests
|
|
|
|
Duration tests verify that license durations are enforced correctly. Most of
|
|
this functionality can be met by keeping an accurate system time, and calling
|
|
the ODK functions as described in the document "License Duration and Renewal".
|
|
|
|
## OEMCrypto Memory Unit Tests
|
|
|
|
### Objective
|
|
|
|
* Add OEMCrypto buffer overflow unit tests (indirect way of fuzzing) to verify
|
|
OEMCrypto API behavior when the parameters passed to the API are out of
|
|
range or not reasonable. The API can return an error code, but shouldn't
|
|
crash.
|
|
|
|
* A lot of OEMCrypto APIs take buffers and their length as inputs to the APIs
|
|
and we have added unit tests with buffers of varying lengths (small
|
|
to huge) to verify API behavior which is an indirect and simplest way of
|
|
fuzz testing to detect buffer overflows.
|
|
|
|
* Add the tests for OEMCrypto APIs with prefix `OEMCryptoMemory` in the
|
|
following format. Huge length is set at 100 MB as of now.
|
|
|
|
```cpp
|
|
for (size_t length=small_length; length<huge_length; length=length * 2) {
|
|
Create buffer of size length.
|
|
Call api expecting it not to crash or segfault.
|
|
}
|
|
```
|
|
|
|
* Add tests for OEMCrypto APIs with out of range values for length and offsets
|
|
of OEMCryptoSubstring struct. This length and offset fields are used to read
|
|
values from an input buffer in most of the APIs. This can cause buffer
|
|
overflows if the length and offset fields are not validated against the
|
|
input buffer.
|
|
|
|
### Background
|
|
|
|
* Security is the top priority for Widevine. We came up with a simple approach
|
|
to catch most common issues with widevine's implementations. A simplest
|
|
approach is to add OEMCrypto unit tests to verify OEMCrypto API behavior
|
|
when the parameters are out of range, meaning for an unreasonable length
|
|
which can cause buffer overflows. Most of the implementation either does not
|
|
validate input length parameters or copies data to secure buffers out of TA
|
|
space causing memory corruptions, buffer overflows. Partners who implement
|
|
OEMCrypto implementations will run OEMCrypto unit tests as part of the
|
|
process.
|
|
|
|
* We have added unit tests with parameters that can cause buffer overflows if
|
|
the parameters are not validated. This way partners can catch issues
|
|
earlier in the process when they run OEMCrypto unit tests. All the unit
|
|
tests with prefix `OEMCryptoMemory` are added to test the above scenario.
|
|
|
|
### What to expect from these tests
|
|
|
|
* `OEMCryptoMemory*` tests are designed to fail if the API doesn't have
|
|
enough validations around input buffer lengths, parameters or the
|
|
OEMCryptoSubstring struct. If the API doesn't have validations which might
|
|
lead to a crash, the test fails with a segfault or an appropriate crash
|
|
message based on the API implementation.
|
|
|
|
* Find out for what buffer length, the API is crashing and then debugging the
|
|
test against the OEMCrypto implementation should be able to provide
|
|
information about the error.
|
|
|
|
* Another way to debug would be to compile the tests with sanitizer flags,
|
|
which will be able to provide detailed information about the crash.
|
|
|
|
* Partners are expected to fix issues with the API so that the tests don't
|
|
fail.
|
|
|
|
* As these tests run for varying lengths from small to huge buffer lengths,
|
|
some of the tests might take longer to run(~3 minutes).
|
|
|
|
* `OEMCryptoMemoryInstallKeyboxForHugeKeyboxBuffer*` tests which tries to
|
|
call install keybox API with varying buffer lengths. This test by default
|
|
is not compiled as it overwrites the keybox on the device. Uncomment,
|
|
compile and run the tests only if you have ability to recover the keybox
|
|
on device where the test is ran.
|
|
|
|
## Filtering out tests
|
|
|
|
The source code will check for functionality of OEMCrypto and filter out tests
|
|
that are not required. For example, if a device uses a keybox, then Provisioning
|
|
3.0 tests are skipped, and vice versa.
|
|
|
|
If you wish to skip slow tests because you only want to verify basic
|
|
functionality, then you can set the environment variable `GTEST_FILTER`,
|
|
as documented
|
|
[here](https://github.com/google/googletest/blob/master/docs/advanced.md#running-a-subset-of-the-tests).
|
|
|
|
For example, to skip the duration tests, buffer overflow tests and long running
|
|
stress tests, you would set
|
|
|
|
```
|
|
GTEST_FILTER="*-*Duration*:*TimingTest*:*Memory*:*Huge*:*NonceFlood*:*ManyUsageEntries*:*Defrag*"
|
|
```
|