Add utility for generating KDF contexts

Starting in v19, OEMCrypto implementers will need to implement KDF generation in OEMCrypto.  To make it easier, this adds a utility to generate them based on the request context.

PiperOrigin-RevId: 572693987
Change-Id: Ife382bf35ceede508499e3677de115ef12999dcc
This commit is contained in:
Jacob Trimble
2023-10-11 14:50:09 -07:00
committed by Robert Shih
parent e85a6b9616
commit 078e1f6555
4 changed files with 272 additions and 1 deletions

View File

@@ -9,6 +9,7 @@
#include <stdio.h>
#include <string.h>
#include "OEMCryptoCENCCommon.h"
#include "odk_message.h"
#include "odk_overflow.h"
#include "odk_serialize.h"
@@ -589,3 +590,69 @@ bool CheckApiVersionAtMost(const ODK_NonceValues* nonce_values,
(nonce_values->api_major_version == major_version &&
nonce_values->api_minor_version <= minor_version);
}
const uint8_t ODK_MacKeyLabelWithZero[] = "AUTHENTICATION";
const size_t ODK_MacKeyLabelWithZeroLength = sizeof(ODK_MacKeyLabelWithZero);
// This is the key size (512) in network byte order.
const uint8_t ODK_MacKeySuffix[] = {0x00, 0x00, 0x02, 0x00};
const size_t ODK_MacKeySuffixLength = sizeof(ODK_MacKeySuffix);
const uint8_t ODK_EncKeyLabelWithZero[] = "ENCRYPTION";
const size_t ODK_EncKeyLabelWithZeroLength = sizeof(ODK_EncKeyLabelWithZero);
// This is the key size (128) in network byte order.
const uint8_t ODK_EncKeySuffix[] = {0x00, 0x00, 0x00, 0x80};
const size_t ODK_EncKeySuffixLength = sizeof(ODK_EncKeySuffix);
OEMCryptoResult ODK_GenerateKeyContexts(const uint8_t* context,
size_t context_length,
uint8_t* mac_key_context,
size_t* mac_key_context_length,
uint8_t* enc_key_context,
size_t* enc_key_context_length) {
size_t real_mac_length;
size_t real_enc_length;
if (odk_add_overflow_ux(
context_length,
ODK_MacKeyLabelWithZeroLength + ODK_MacKeySuffixLength,
&real_mac_length) ||
real_mac_length > 0xffffffff ||
odk_add_overflow_ux(
context_length,
ODK_EncKeyLabelWithZeroLength + ODK_EncKeySuffixLength,
&real_enc_length) ||
real_enc_length > 0xffffffff) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
bool short_buffer = false;
if (mac_key_context_length) {
short_buffer = real_mac_length > *mac_key_context_length;
*mac_key_context_length = real_mac_length;
}
if (enc_key_context_length) {
short_buffer = short_buffer || real_enc_length > *enc_key_context_length;
*enc_key_context_length = real_enc_length;
}
if (short_buffer || !mac_key_context || !enc_key_context) {
return OEMCrypto_ERROR_SHORT_BUFFER;
}
if (!context || !mac_key_context_length || !enc_key_context_length) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
memcpy(mac_key_context, ODK_MacKeyLabelWithZero,
ODK_MacKeyLabelWithZeroLength);
memcpy(mac_key_context + ODK_MacKeyLabelWithZeroLength, context,
context_length);
memcpy(mac_key_context + ODK_MacKeyLabelWithZeroLength + context_length,
ODK_MacKeySuffix, ODK_MacKeySuffixLength);
memcpy(enc_key_context, ODK_EncKeyLabelWithZero,
ODK_EncKeyLabelWithZeroLength);
memcpy(enc_key_context + ODK_EncKeyLabelWithZeroLength, context,
context_length);
memcpy(enc_key_context + ODK_EncKeyLabelWithZeroLength + context_length,
ODK_EncKeySuffix, ODK_EncKeySuffixLength);
return OEMCrypto_SUCCESS;
}