Update OPK v18 documentation

Merge from Widevine repo of http://go/wvgerrit/169050

- Update changelog
- Update copy parter files script to include linux port
- Update opk_partner_test script (used to make sure everything works out
  of the box) with third party dependencies, refactored downloads into
  a public setup.sh script
- Remove WTPI_BUILD_INFO from OPK makefiles and gyp files, since it is
  no longer needed
- Remove FILES.md since it is out of date and ree-sources.mk and
  tee-sources.mk satisfy the same purpose
- Add debug flag in comments for OP-TEE and Linux ports. As a hint for
  how to enable debug in OPK
- Remove oemcrypto_build_info.h since it is no longer needed. Move the
  XSTR macro it contained to oemcrypto_api_macros.h
- Add provisioning method macro to OPTEE and Linux build files to hint
  at how to build Prov 2 and Prov 4 using the same build files but
  different build-time values.

Merged from https://widevine-internal-review.googlesource.com/166219

Bug: 275264353
Test: luci tests
Change-Id: I220e3296f631d895a7c4504454635fe396efc0a4
This commit is contained in:
Matt Feddersen
2023-03-27 19:40:37 -07:00
committed by Fred Gylys-Colwell
parent c579a79462
commit dbd5bd2a4d
2 changed files with 223 additions and 0 deletions

View File

@@ -2,6 +2,167 @@
[TOC]
## [Version 18.1][v18.1]
OEMCrypto V18.0 consisted of header files only. This release includes tests and
OPK. There have been minor API changes since v18.0, so the version number has
been bumped to 18.1
In general, new v18 OEMCrypto features have been implemented in the OPK; since
those have been covered already in the published v18 headers, they will not be
discussed in detail here.
This OPK release includes OEMCrypto v18 changes outlined in the document "WV
Modular DRM Version 18.1 Delta". In addition, quite a few OPK-specific changes
have been added since the last release. Major changes are described in more
detail below in individual sections, followed by a consolidated list of minor
changes.
### REE-side hooks
In oemcrypto/opk/serialization/ree/GEN_oemcrypto_api.c, new ifdef checks have
been added in OEMCrypto_Initialize, OEMCrypto_Terminate, OEMCrypto_DecryptCENC,
and OEMCrypto_LoadLicense. Depending on the macros, liboemcrypto can be compiled
with hooks that execute before, after, or instead of the listed OEMCrypto
functions (or some combination of the three). If a hook macro is defined, the
default behavior is to call that hook function instead of calling into the TEE
-- to do both, at least one more macro must be defined. For more detail, see
GEN_oemcrypto_api.c directly.
For example, defining the macro `OPK_PRE_HOOK_OEMCRYPTO_DECRYPTCENC` will
execute `OPK_PreHook_OEMCrypto_DecryptCENC()` instead of calling into the TEE.
The same arguments will be passed to this function, which needs a custom
implementation. One use case for this is custom decryption hardware that is
accessible from the REE and can accept opaque decryption key handles intended
for the TEE. The above macro can be used to execute the hook function instead of
calling the TEE, and the hook function can pass the key handle and encrypted
content to the decrypt hardware directly, bypassing the TEE.
Another example is in `OEMCrypto_Initialize()`. Defining the macro
`OPK_PRE_HOOK_OEMCRYPTO_INITIALIZE` will execute a call to
`OPK_Prehook_OEMCrypto_Initialize()` instead of calling into the TEE. Defining
another macro `OPK_HOOK_AND_USE_TA_OEMCRYPTO_INITIALIZE` will include the call
to the TEE after the pre-hook. The implementer is free to define custom REE-side
initialization logic, and continue to let the TA finish its initialization as
well.
One more use case: `OEMCrypto_LoadLicense()`. Some implementers have requested
the ability to call a custom function after LoadLicense() returns in order to
parse the license response and control output restrictions accordingly from the
REE (HDCP, watermarking, etc). To do this, define
`OPK_POST_HOOK_OEMCRYPTO_LOAD_LICENSE` and
`OPK_HOOK_AND_USE_TA_OEMCRYPTO_LOAD_LICENSE` at build time and provide
a function implementation for `OPK_Posthook_OEMCrypto_LoadLicense()`. The post
hook function will execute after `OEMCrypto_LoadLicense()` comes back from the
TEE and will use the same function arguments.
If no macros are defined, there is no change to GEN_oemcrypto_api.c and all
OEMCrypto calls will be forwarded to the TEE without hooks.
### Configuration macros
Previously, a platform-specific port needed to define hard coded values in the
implementation of `wtpi_config_interface.h`, as well as macro definitions in
`wtpi_config_macros.h`. These values defined which features were available in
the build, but they were difficult to modify for a new build, and it was often
unclear what configuration values were enabled for a particular build.
These have been replaced with a single header file consisting of only macro
definitions. For a full list of these configuration macros with default values,
see oemcrypto/opk/oemcrypto_ta/wtpi_reference/config/default.h.
Each platform-specific port needs to provide configuration values in a file
called `opk_config.h`. The OPK code looks for this file at compilation time. To
provide flexibility at build time, these macro definitions should be `#ifndef`
checked. This way, macros can be defined in the cflags to override the default
values if desired (eg build a version that only changes the provisioning method
by setting the `OPK_CONFIG_PROVISIONING_METHOD` macro in the cflags). The OP-TEE,
Trusty, and Linux reference ports all have `opk_config.h` files that can be used
as examples.
As part of the OEMCrypto v18 changes, OEMCrypto_BuildInformation() now outputs
JSON-formatted text. If the OPK is built in debug mode, the build information
will also include all of the configuration macro values as a new JSON field.
The intent is to improve the debugging experience by providing as much
configuration information as possible. With the changes to
OEMCrypto_BuildInformation(), the `WTPI_BUILD_INFO` macro is no longer required.
### OP-TEE port changes
- Add implementations for provisioning 4.0 WTPI functions. This requires the
third party library open-dice.
- Pre-allocate crypto handles for DecryptCENC. Since this is
a performance-sensitive path, allocate once up front instead of per
DecryptCENC call.
- Reduce compiler warnings.
- Add support for RSA CAST receiver signing.
- Add QEMUv8 target.
- Move der_parse and related files into the wtpi_impl directory.
- Bugfix: Randomly generated ECC key in v17.1 sometimes was smaller than the
expected keysize. Fixed to include leading zeroes if needed.
- Bugfix: WPTI_GenerateRandomCertificateKeyPair() was implemented incorrectly.
It did not return the correct minimum size, used the wrong mbedtls key type,
and did not free allocated resources. Fixed all three issues.
### Trusty port changes
In v17.1, the Trusty port did not compile against the OPK. This has been fixed
in v18, with the code moved one directory deeper to a folder named `reference`.
Implementers looking to create a port based on this reference code are
encouraged to copy the `reference` folder and modify it, instead of modifying
the existing code directly.
The Trusty port still requires a full download of AOSP Trusty, and must be built
into the Trusty kernel as a user module. In the future we plan to support
standalone TA builds that can be compiled or sideloaded into Trusty OS.
At this time, there is still no easy way to test builds of the Trusty port
without hardware. QEMU support is planned for a future release.
### Linux testing port
A new folder has been created under `oemcrypto/opk/ports` for an implementation
that can run on Linux. Please note that this is a testing-only insecure
implementation, as all code executes in the REE.
The oemcrypto_unittests and wtpi_unittests applications are the same. The "TA"
is a Linux application that spins a while loop until it receives a message, then
executes that call. The transport interface between liboemcrypto and this fake
TA uses Linux shmem APIs to pass messages back and forth.
Again, this is not to be used in any kind of production release. The fake TA is
only intended as an easier way to test the REE-TEE code path without a trusted
OS.
### Other changes
- Provisioning 4 WTPI functions moved to wtpi_provisioning_4_interface.h. Some
new functions added such as WTPI_GetSignedCsrPayload()
- Provisioning 4 WTPI tests improved to test correctness of BCC and CoseSign1
payloads, but requires new third party library COSE-C to do so.
- WTPI unit tests can be skipped based on configuration values. Currently
provisioning 4 WTPI functions are skipped if the configured provisioning
method is different.
- Calling an OEMCrypto function with shared buffer arguments could fail if the
underlying buffer was larger than the available shared memory. This would
occur before reaching the TEE in the serialization code, and would return the
default OEMCrypto_ERROR_UNKNOWN_FAILURE error. Now it returns
OEMCrypto_ERROR_BUFFER_TOO_LARGE.
- Fixed a memory leak in the asymmetric key table management code, where key
handles were not freed at session termination.
- Fixed a bug in the serialization code, where `uint8_t iv[16]` parameters were
not passed correctly through to the TEE, eg in AES operations. A NULL input
would always show up as a valid pointer to the TEE. This is now fixed and NULL
inputs show up as NULL in the TEE.
### Known bugs
- In the OP-TEE port, WTPI unit tests that use randomly generated ECC keys
occasionally (1/100) fail. The exact cause is unknown, but it appears to be
due to an edge case in the implementation of
WPTI_GenerateRandomCertificateKeyPair().
## [Version 17.1][v17.1]
This release contains a major change to the build process for the OP-TEE port,

View File

@@ -304,3 +304,65 @@ OEMCryptoResult _oecc120(OEMCrypto_SESSION session, const uint8_t* message,
// OEMCrypto_GetOEMKeyToken defined in v17.2
OEMCryptoResult _oecc130(OEMCrypto_SESSION key_session, uint8_t* key_token,
size_t* key_token_length);
// OEMCrypto_SetMaxAPIVersion defined in v18.1
OEMCryptoResult _oecc132(uint32_t max_version);
// OEMCrypto_GetKeyHandle defined in v18.1
OEMCryptoResult _oecc133(OEMCrypto_SESSION session,
const uint8_t* content_key_id,
size_t content_key_id_length,
OEMCryptoCipherMode cipher_mode, uint8_t* key_handle,
size_t* key_handle_length);
// OEMCrypto_DecryptCENC defined in v18.1
OEMCryptoResult _oecc134(
const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SampleDescription* samples, // an array of samples.
size_t samples_length, // the number of samples.
const OEMCrypto_CENCEncryptPatternDesc* pattern);
// OEMCrypto_Generic_Encrypt defined in v18.1
OEMCryptoResult _oecc135(const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SharedMemory* in_buffer,
size_t in_buffer_length, const uint8_t* iv,
OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* out_buffer);
// OEMCrypto_Generic_Decrypt defined in v18.1
OEMCryptoResult _oecc136(const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SharedMemory* in_buffer,
size_t in_buffer_length, const uint8_t* iv,
OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* out_buffer);
// OEMCrypto_Generic_Sign defined in v18.1
OEMCryptoResult _oecc137(const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SharedMemory* buffer,
size_t buffer_length, OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* signature,
size_t* signature_length);
// OEMCrypto_Generic_Verify defined in v18.1
OEMCryptoResult _oecc138(const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SharedMemory* buffer,
size_t buffer_length, OEMCrypto_Algorithm algorithm,
const OEMCrypto_SharedMemory* signature,
size_t signature_length);
// OEMCrypto_GetSignatureHashAlgorithm defined in v18.1
OEMCryptoResult _oecc139(OEMCrypto_SESSION session,
OEMCrypto_SignatureHashAlgorithm* algorithm);
// OEMCrypto_GetDeviceInformation defined in v18.1
OEMCryptoResult _oecc131(uint8_t* device_info, size_t* device_info_length);
// OEMCrypto_GetDeviceSignedCsrPayload defined in v18.1
OEMCryptoResult _oecc141(const uint8_t* challenge, size_t challenge_length,
const uint8_t* encoded_device_info,
size_t encoded_device_info_length,
uint8_t* signed_csr_payload,
size_t* signed_csr_payload_length);
// OEMCrypto_EnterTestMode defined in v18.1
OEMCryptoResult _oecc140(void);