mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-11 18:35:28 +00:00
Implemented pipelined hash calculation in LoadFirmware()
Review URL: http://codereview.chromium.org/2802002
This commit is contained in:
@@ -45,8 +45,8 @@ static void VerifyDataTest(const VbPublicKey* public_key,
|
||||
const VbPrivateKey* private_key) {
|
||||
|
||||
const uint8_t test_data[] = "This is some test data to sign.";
|
||||
VbSignature *sig;
|
||||
RSAPublicKey *rsa;
|
||||
VbSignature* sig;
|
||||
RSAPublicKey* rsa;
|
||||
|
||||
sig = CalculateSignature(test_data, sizeof(test_data), private_key);
|
||||
rsa = PublicKeyToRSA(public_key);
|
||||
@@ -68,6 +68,32 @@ static void VerifyDataTest(const VbPublicKey* public_key,
|
||||
}
|
||||
|
||||
|
||||
static void VerifyDigestTest(const VbPublicKey* public_key,
|
||||
const VbPrivateKey* private_key) {
|
||||
|
||||
const uint8_t test_data[] = "This is some other test data to sign.";
|
||||
VbSignature* sig;
|
||||
RSAPublicKey* rsa;
|
||||
uint8_t* digest;
|
||||
|
||||
sig = CalculateSignature(test_data, sizeof(test_data), private_key);
|
||||
rsa = PublicKeyToRSA(public_key);
|
||||
digest = DigestBuf(test_data, sizeof(test_data), public_key->algorithm);
|
||||
TEST_NEQ(sig && rsa && digest, 0, "VerifyData() prerequisites");
|
||||
if (!sig || !rsa || !digest)
|
||||
return;
|
||||
|
||||
TEST_EQ(VerifyDigest(digest, sig, rsa), 0, "VerifyDigest() ok");
|
||||
|
||||
GetSignatureData(sig)[0] ^= 0x5A;
|
||||
TEST_EQ(VerifyDigest(digest, sig, rsa), 1, "VerifyDigest() wrong sig");
|
||||
|
||||
RSAPublicKeyFree(rsa);
|
||||
Free(sig);
|
||||
Free(digest);
|
||||
}
|
||||
|
||||
|
||||
static void ReSignKernelPreamble(VbKernelPreambleHeader *h,
|
||||
const VbPrivateKey *key) {
|
||||
VbSignature *sig = CalculateSignature((const uint8_t*)h,
|
||||
@@ -201,6 +227,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
VerifyPublicKeyToRSA(public_key);
|
||||
VerifyDataTest(public_key, private_key);
|
||||
VerifyDigestTest(public_key, private_key);
|
||||
VerifyKernelPreambleTest(public_key, private_key);
|
||||
|
||||
if (public_key)
|
||||
|
||||
@@ -67,6 +67,12 @@ int VerifyData(const uint8_t* data, const VbSignature* sig,
|
||||
const RSAPublicKey* key);
|
||||
|
||||
|
||||
/* Verifies a secure hash digest from DigestBuf() or DigestFinal(),
|
||||
* using [key]. */
|
||||
int VerifyDigest(const uint8_t* digest, const VbSignature *sig,
|
||||
const RSAPublicKey* key);
|
||||
|
||||
|
||||
/* Checks the sanity of a key block of size [size] bytes, using public
|
||||
* key [key]. If [key]==NULL, uses only the block checksum to verify
|
||||
* the key block. Header fields are also checked for sanity. Does not
|
||||
|
||||
@@ -122,6 +122,22 @@ int VerifyData(const uint8_t* data, const VbSignature *sig,
|
||||
}
|
||||
|
||||
|
||||
int VerifyDigest(const uint8_t* digest, const VbSignature *sig,
|
||||
const RSAPublicKey* key) {
|
||||
|
||||
if (sig->sig_size != siglen_map[key->algorithm]) {
|
||||
debug("Wrong signature size for algorithm.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!RSAVerifyBinaryWithDigest_f(NULL, key, digest,
|
||||
GetSignatureDataC(sig), key->algorithm))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
|
||||
const VbPublicKey *key) {
|
||||
|
||||
|
||||
@@ -13,9 +13,23 @@
|
||||
#include "utility.h"
|
||||
#include "vboot_common.h"
|
||||
|
||||
/* Static variables for UpdateFirmwareBodyHash(). It's less than
|
||||
* optimal to have static variables in a library, but in UEFI the
|
||||
* caller is deep inside a different firmware stack and doesn't have a
|
||||
* good way to pass the params struct back to us. */
|
||||
static DigestContext ctx;
|
||||
static uint64_t body_size_accum = 0;
|
||||
static int inside_load_firmware = 0;
|
||||
|
||||
void UpdateFirmwareBodyHash2(uint8_t* data, uint64_t size) {
|
||||
/* TODO: actually update the hash. */
|
||||
|
||||
if (!inside_load_firmware) {
|
||||
debug("UpdateFirmwareBodyHash() called outside LoadFirmware()\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DigestUpdate(&ctx, data, size);
|
||||
body_size_accum += size;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +70,7 @@ int LoadFirmware2(LoadFirmwareParams* params) {
|
||||
uint64_t key_version;
|
||||
uint8_t* body_data;
|
||||
uint64_t body_size;
|
||||
uint8_t* body_digest;
|
||||
|
||||
/* Verify the key block */
|
||||
if (0 == index) {
|
||||
@@ -112,23 +127,29 @@ int LoadFirmware2(LoadFirmwareParams* params) {
|
||||
continue;
|
||||
|
||||
/* Read the firmware data */
|
||||
/* TODO: should set up hash for UpdateFirmwareBodyHash(). */
|
||||
DigestInit(&ctx, data_key->algorithm);
|
||||
body_size_accum = 0;
|
||||
inside_load_firmware = 1;
|
||||
body_data = GetFirmwareBody(index, &body_size);
|
||||
if (!body_data || (body_size != preamble->body_signature.data_size)) {
|
||||
inside_load_firmware = 0;
|
||||
body_digest = DigestFinal(&ctx);
|
||||
if (!body_data || (body_size != preamble->body_signature.data_size) ||
|
||||
(body_size_accum != body_size)) {
|
||||
RSAPublicKeyFree(data_key);
|
||||
Free(body_digest);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Verify firmware data */
|
||||
/* TODO: should use hash from UpdateFirmwareBodyHash() rather than
|
||||
* recalculating it in VerifyData(). */
|
||||
if (0 != VerifyData(body_data, &preamble->body_signature, data_key)) {
|
||||
if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) {
|
||||
RSAPublicKeyFree(data_key);
|
||||
Free(body_digest);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Done with the data key, so can free it now */
|
||||
/* Done with the digest and data key, so can free them now */
|
||||
RSAPublicKeyFree(data_key);
|
||||
Free(body_digest);
|
||||
|
||||
/* If we're still here, the firmware is valid. */
|
||||
/* Save the first good firmware we find; that's the one we'll boot */
|
||||
|
||||
@@ -79,6 +79,7 @@ int main(void)
|
||||
VerifySignatureInside(0, 0, 0);
|
||||
PublicKeyToRSA(0);
|
||||
VerifyData(0, 0, 0);
|
||||
VerifyDigest(0, 0, 0);
|
||||
KeyBlockVerify(0, 0, 0);
|
||||
VerifyFirmwarePreamble2(0, 0, 0);
|
||||
VerifyKernelPreamble2(0, 0, 0);
|
||||
|
||||
Reference in New Issue
Block a user