Skip padding for content keys differently

(This is a merge of http://go/wvgerrit/151891.)

A previous patch changed how we skip padding when extracting keys from
key containers in license.cpp. Unfortunately, this broke generic
signing when an ODK core message is not in use:

1) "Content" keys for signing are 32 bytes long, but content keys were
   assumed to be 16 bytes long.
2) When an ODK core message IS in use, the result of the extraction in
   license.cpp is ignored.

The only way to know the correct length of a content key container in
License Protocol 2.1 is to leverage the knowledge that it will always be
padded by exactly 16 bytes. This will have to change if we ever
implement support for License Protocol 2.2, as all key containers are
unpadded in that version.

Bug: 231439638
Bug: 114159862
Test: oemcrypto_dynamic_v15
Change-Id: I1d6c24b3a922247b970fd1517c6f23aded570adf
This commit is contained in:
John "Juce" Bruce
2022-05-16 18:32:00 -07:00
parent 46f2e5bcc5
commit a7cded376e
2 changed files with 25 additions and 7 deletions

View File

@@ -20,6 +20,8 @@ static const size_t ENTITLEMENT_KEY_SIZE = 32;
static const size_t KEYBOX_KEY_DATA_SIZE = 72;
static const size_t SRM_REQUIREMENT_SIZE = 12;
static const size_t LICENSE_PROTOCOL_2_1_PADDING = 16;
// Initial estimate of certificate size. Code that
// uses this estimate should be able to adapt to a larger or smaller size.
static const size_t CERTIFICATE_DATA_SIZE = 4 * 1024;

View File

@@ -59,6 +59,10 @@ std::vector<CryptoKey> ExtractEntitlementKeys(const License& license) {
case License_KeyContainer::ENTITLEMENT: {
// We always take the first ENTITLEMENT_KEY_SIZE bytes and ignore the
// rest in order to ignore any padding.
//
// TODO(b/232464183): When we switch to License Protocol 2.2, there will
// no longer be padding on these keys, so this
// removal code can be removed at the same time.
if (license.key(i).key().size() < ENTITLEMENT_KEY_SIZE) {
LOGE(
"Skipping key %s because it is too small. Expected: %zu vs. "
@@ -117,17 +121,29 @@ std::vector<CryptoKey> ExtractContentKeys(const License& license) {
case License_KeyContainer::CONTENT:
case License_KeyContainer::OPERATOR_SESSION: {
key.set_key_id(license.key(i).id());
// We always take the first CONTENT_KEY_SIZE bytes and ignore the rest
// in order to ignore any padding.
if (license.key(i).key().size() < CONTENT_KEY_SIZE) {
// KeyContainers have a fixed 16 bytes of padding in License Protocol
// 2.1. Note that OPERATION_SESSION keys may be CONTENT_KEY_SIZE or
// MAC_KEY_SIZE, so we cannot assume the key size here.
//
// TODO(b/232464183): When we switch to License Protocol 2.2, there will
// no longer be padding on these keys, so this
// removal code must be removed at the same time.
if (license.key(i).key().size() !=
CONTENT_KEY_SIZE + LICENSE_PROTOCOL_2_1_PADDING &&
license.key(i).key().size() !=
MAC_KEY_SIZE + LICENSE_PROTOCOL_2_1_PADDING) {
LOGE(
"Skipping key %s because it is too small. Expected: %zu vs. "
"Actual: %zu",
license.key(i).id().c_str(), CONTENT_KEY_SIZE,
"Skipping key %s because it is an unexpected size. Expected: %zu "
"or %zu, Actual: %zu",
license.key(i).id().c_str(),
CONTENT_KEY_SIZE + LICENSE_PROTOCOL_2_1_PADDING,
MAC_KEY_SIZE + LICENSE_PROTOCOL_2_1_PADDING,
license.key(i).key().size());
continue;
}
key.set_key_data(license.key(i).key().substr(0, CONTENT_KEY_SIZE));
const size_t length =
license.key(i).key().size() - LICENSE_PROTOCOL_2_1_PADDING;
key.set_key_data(license.key(i).key().substr(0, length));
key.set_key_data_iv(license.key(i).iv());
if (license.key(i).has_key_control()) {
key.set_key_control(license.key(i).key_control().key_control_block());