mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-27 11:44:02 +00:00
Utility to pack public key, version, algorithm into a single file in VbPublicKey format
Review URL: http://codereview.chromium.org/2762009
This commit is contained in:
@@ -21,13 +21,14 @@ INCLUDES += \
|
|||||||
LIB_SRCS = \
|
LIB_SRCS = \
|
||||||
./lib/host_common.c \
|
./lib/host_common.c \
|
||||||
./lib/host_key.c \
|
./lib/host_key.c \
|
||||||
|
./lib/host_misc.c \
|
||||||
./lib/host_signature.c
|
./lib/host_signature.c
|
||||||
|
|
||||||
LIB_OBJS = $(LIB_SRCS:%.c=%.o)
|
LIB_OBJS = $(LIB_SRCS:%.c=%.o)
|
||||||
|
|
||||||
test : $(LIBNAME)
|
test : $(LIBNAME)
|
||||||
$(CC) $(CFLAGS) $(INCLUDES) -o $(TESTDIR)/a.out $(TESTDIR)/main.c \
|
$(CC) $(CFLAGS) $(INCLUDES) -o $(TESTDIR)/a.out $(TESTDIR)/main.c \
|
||||||
$(LIBNAME) $(FWLIB) $(TOP)/misclibs/file_keys.o -lcrypto
|
$(LIBNAME) $(FWLIB) -lcrypto
|
||||||
|
|
||||||
$(LIBNAME) : $(LIB_OBJS) $(STUB_OBJS)
|
$(LIBNAME) : $(LIB_OBJS) $(STUB_OBJS)
|
||||||
rm -f $@
|
rm -f $@
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "cryptolib.h"
|
#include "cryptolib.h"
|
||||||
#include "host_key.h"
|
#include "host_key.h"
|
||||||
|
#include "host_misc.h"
|
||||||
#include "host_signature.h"
|
#include "host_signature.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "vboot_struct.h"
|
#include "vboot_struct.h"
|
||||||
@@ -46,6 +47,7 @@ VbKernelPreambleHeader* CreateKernelPreamble(
|
|||||||
uint64_t bootloader_address,
|
uint64_t bootloader_address,
|
||||||
uint64_t bootloader_size,
|
uint64_t bootloader_size,
|
||||||
const VbSignature* body_signature,
|
const VbSignature* body_signature,
|
||||||
|
uint64_t desired_size,
|
||||||
const VbPrivateKey* signing_key);
|
const VbPrivateKey* signing_key);
|
||||||
|
|
||||||
#endif /* VBOOT_REFERENCE_HOST_COMMON_H_ */
|
#endif /* VBOOT_REFERENCE_HOST_COMMON_H_ */
|
||||||
|
|||||||
@@ -48,12 +48,23 @@ VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,
|
|||||||
int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src);
|
int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src);
|
||||||
|
|
||||||
|
|
||||||
/* Read a public key from a file. Caller owns the returned pointer,
|
/* Read a public key from a .vbpubk file. Caller owns the returned
|
||||||
* and must free it with Free().
|
* pointer, and must free it with Free().
|
||||||
*
|
*
|
||||||
* Returns NULL if error. */
|
* Returns NULL if error. */
|
||||||
/* TODO: should really store public keys in files as VbPublicKey */
|
VbPublicKey* PublicKeyRead(const char* filename);
|
||||||
VbPublicKey* PublicKeyRead(const char* filename, uint64_t algorithm,
|
|
||||||
|
|
||||||
|
/* Read a public key from a .keyb file. Caller owns the returned
|
||||||
|
* pointer, and must free it with Free().
|
||||||
|
*
|
||||||
|
* Returns NULL if error. */
|
||||||
|
VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm,
|
||||||
uint64_t version);
|
uint64_t version);
|
||||||
|
|
||||||
|
|
||||||
|
/* Write a public key to a file in .vbpubk format. */
|
||||||
|
int PublicKeyWrite(const char* filename, const VbPublicKey* key);
|
||||||
|
|
||||||
|
|
||||||
#endif /* VBOOT_REFERENCE_HOST_KEY_H_ */
|
#endif /* VBOOT_REFERENCE_HOST_KEY_H_ */
|
||||||
|
|||||||
25
host/include/host_misc.h
Normal file
25
host/include/host_misc.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*
|
||||||
|
* Host-side misc functions for verified boot.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VBOOT_REFERENCE_HOST_MISC_H_
|
||||||
|
#define VBOOT_REFERENCE_HOST_MISC_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "host_misc.h"
|
||||||
|
#include "utility.h"
|
||||||
|
#include "vboot_struct.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Read data from [filename]. Store the size of returned data in [size].
|
||||||
|
*
|
||||||
|
* Returns the data buffer, which the caller must Free(), or NULL if
|
||||||
|
* error. */
|
||||||
|
uint8_t* ReadFile(const char* filename, uint64_t* size);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VBOOT_REFERENCE_HOST_MISC_H_ */
|
||||||
@@ -7,18 +7,6 @@
|
|||||||
|
|
||||||
/* TODO: change all 'return 0', 'return 1' into meaningful return codes */
|
/* TODO: change all 'return 0', 'return 1' into meaningful return codes */
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define OPENSSL_NO_SHA
|
|
||||||
#include <openssl/engine.h>
|
|
||||||
#include <openssl/pem.h>
|
|
||||||
#include <openssl/rsa.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "file_keys.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "host_common.h"
|
#include "host_common.h"
|
||||||
|
|
||||||
#include "cryptolib.h"
|
#include "cryptolib.h"
|
||||||
@@ -141,6 +129,7 @@ VbKernelPreambleHeader* CreateKernelPreamble(
|
|||||||
uint64_t bootloader_address,
|
uint64_t bootloader_address,
|
||||||
uint64_t bootloader_size,
|
uint64_t bootloader_size,
|
||||||
const VbSignature* body_signature,
|
const VbSignature* body_signature,
|
||||||
|
uint64_t desired_size,
|
||||||
const VbPrivateKey* signing_key) {
|
const VbPrivateKey* signing_key) {
|
||||||
|
|
||||||
VbKernelPreambleHeader* h;
|
VbKernelPreambleHeader* h;
|
||||||
@@ -151,6 +140,10 @@ VbKernelPreambleHeader* CreateKernelPreamble(
|
|||||||
uint8_t* block_sig_dest;
|
uint8_t* block_sig_dest;
|
||||||
VbSignature *sigtmp;
|
VbSignature *sigtmp;
|
||||||
|
|
||||||
|
/* If the block size is smaller than the desired size, pad it */
|
||||||
|
if (block_size < desired_size)
|
||||||
|
block_size = desired_size;
|
||||||
|
|
||||||
/* Allocate key block */
|
/* Allocate key block */
|
||||||
h = (VbKernelPreambleHeader*)Malloc(block_size);
|
h = (VbKernelPreambleHeader*)Malloc(block_size);
|
||||||
if (!h)
|
if (!h)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "host_key.h"
|
#include "host_key.h"
|
||||||
|
|
||||||
#include "cryptolib.h"
|
#include "cryptolib.h"
|
||||||
#include "file_keys.h"
|
#include "host_misc.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "vboot_common.h"
|
#include "vboot_common.h"
|
||||||
|
|
||||||
@@ -80,6 +80,7 @@ void PublicKeyInit(VbPublicKey* key, uint8_t* key_data, uint64_t key_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Allocate a new public key with space for a [key_size] byte key. */
|
||||||
VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,
|
VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,
|
||||||
uint64_t version) {
|
uint64_t version) {
|
||||||
VbPublicKey* key = (VbPublicKey*)Malloc(sizeof(VbPublicKey) + key_size);
|
VbPublicKey* key = (VbPublicKey*)Malloc(sizeof(VbPublicKey) + key_size);
|
||||||
@@ -94,6 +95,9 @@ VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy a public key from [src] to [dest].
|
||||||
|
*
|
||||||
|
* Returns zero if success, non-zero if error. */
|
||||||
int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src) {
|
int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src) {
|
||||||
if (dest->key_size < src->key_size)
|
if (dest->key_size < src->key_size)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -106,28 +110,31 @@ int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VbPublicKey* PublicKeyRead(const char* filename, uint64_t algorithm,
|
VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm,
|
||||||
uint64_t version) {
|
uint64_t version) {
|
||||||
|
|
||||||
VbPublicKey* key;
|
VbPublicKey* key;
|
||||||
uint8_t* key_data;
|
uint8_t* key_data;
|
||||||
uint64_t key_size;
|
uint64_t key_size;
|
||||||
|
|
||||||
if (algorithm >= kNumAlgorithms) {
|
if (algorithm >= kNumAlgorithms) {
|
||||||
debug("PublicKeyRead() called with invalid algorithm!\n");
|
debug("PublicKeyReadKeyb() called with invalid algorithm!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (version > 0xFFFF) {
|
if (version > 0xFFFF) {
|
||||||
/* Currently, TPM only supports 16-bit version */
|
/* Currently, TPM only supports 16-bit version */
|
||||||
debug("PublicKeyRead() called with invalid version!\n");
|
debug("PublicKeyReadKeyb() called with invalid version!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_data = BufferFromFile(filename, &key_size);
|
key_data = ReadFile(filename, &key_size);
|
||||||
if (!key_data)
|
if (!key_data)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* TODO: sanity-check key length based on algorithm */
|
if (RSAProcessedKeySize(algorithm) != key_size) {
|
||||||
|
debug("PublicKeyReadKeyb() wrong key size for algorithm\n");
|
||||||
|
Free(key_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
key = PublicKeyAlloc(key_size, algorithm, version);
|
key = PublicKeyAlloc(key_size, algorithm, version);
|
||||||
if (!key) {
|
if (!key) {
|
||||||
@@ -139,3 +146,78 @@ VbPublicKey* PublicKeyRead(const char* filename, uint64_t algorithm,
|
|||||||
Free(key_data);
|
Free(key_data);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VbPublicKey* PublicKeyRead(const char* filename) {
|
||||||
|
VbPublicKey* key;
|
||||||
|
uint64_t file_size;
|
||||||
|
|
||||||
|
key = (VbPublicKey*)ReadFile(filename, &file_size);
|
||||||
|
if (!key)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Sanity-check key data */
|
||||||
|
if (0 != VerifyPublicKeyInside(key, file_size, key)) {
|
||||||
|
debug("PublicKeyRead() not a VbPublicKey\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (key->algorithm >= kNumAlgorithms) {
|
||||||
|
debug("PublicKeyRead() invalid algorithm\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (key->key_version > 0xFFFF) {
|
||||||
|
debug("PublicKeyRead() invalid version\n");
|
||||||
|
break; /* Currently, TPM only supports 16-bit version */
|
||||||
|
}
|
||||||
|
if (RSAProcessedKeySize(key->algorithm) != key->key_size) {
|
||||||
|
debug("PublicKeyRead() wrong key size for algorithm\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success */
|
||||||
|
return key;
|
||||||
|
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
/* Error */
|
||||||
|
Free(key);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PublicKeyWrite(const char* filename, const VbPublicKey* key) {
|
||||||
|
VbPublicKey* kcopy = NULL;
|
||||||
|
FILE* f = NULL;
|
||||||
|
int rv = 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
f = fopen(filename, "wb");
|
||||||
|
if (!f) {
|
||||||
|
debug("PublicKeyWrite() unable to open file %s\n", filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the key, so its data is contiguous with the header */
|
||||||
|
kcopy = PublicKeyAlloc(key->key_size, 0, 0);
|
||||||
|
if (!kcopy || 0 != PublicKeyCopy(kcopy, key))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (1 != fwrite(kcopy, kcopy->key_offset + kcopy->key_size, 1, f))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Success */
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
if (kcopy)
|
||||||
|
Free(kcopy);
|
||||||
|
if (f)
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (0 != rv)
|
||||||
|
unlink(filename); /* Delete any partial file */
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|||||||
49
host/lib/host_misc.c
Normal file
49
host/lib/host_misc.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*
|
||||||
|
* Host functions for verified boot.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TODO: change all 'return 0', 'return 1' into meaningful return codes */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "host_common.h"
|
||||||
|
|
||||||
|
#include "cryptolib.h"
|
||||||
|
#include "utility.h"
|
||||||
|
#include "vboot_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t* ReadFile(const char* filename, uint64_t* size) {
|
||||||
|
FILE* f;
|
||||||
|
uint8_t* buf;
|
||||||
|
|
||||||
|
f = fopen(filename, "rb");
|
||||||
|
if (!f) {
|
||||||
|
debug("Unable to open file %s\n", filename);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
*size = ftell(f);
|
||||||
|
rewind(f);
|
||||||
|
|
||||||
|
buf = Malloc(*size);
|
||||||
|
if (!buf) {
|
||||||
|
fclose(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(1 != fread(buf, *size, 1, f)) {
|
||||||
|
debug("Unable to read from file %s\n", filename);
|
||||||
|
fclose(f);
|
||||||
|
Free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
@@ -10,7 +10,12 @@ int main(void)
|
|||||||
PublicKeyInit(0, 0, 0);
|
PublicKeyInit(0, 0, 0);
|
||||||
PublicKeyAlloc(0, 0, 0);
|
PublicKeyAlloc(0, 0, 0);
|
||||||
PublicKeyCopy(0, 0);
|
PublicKeyCopy(0, 0);
|
||||||
PublicKeyRead(0, 0, 0);
|
PublicKeyRead(0);
|
||||||
|
PublicKeyReadKeyb(0, 0, 0);
|
||||||
|
PublicKeyWrite(0, 0);
|
||||||
|
|
||||||
|
/* host_misc.h */
|
||||||
|
ReadFile(0, 0);
|
||||||
|
|
||||||
/* host_signature.h */
|
/* host_signature.h */
|
||||||
SignatureInit(0, 0, 0, 0);
|
SignatureInit(0, 0, 0, 0);
|
||||||
@@ -22,7 +27,7 @@ int main(void)
|
|||||||
/* host_common.h */
|
/* host_common.h */
|
||||||
CreateKeyBlock(0, 0, 0);
|
CreateKeyBlock(0, 0, 0);
|
||||||
CreateFirmwarePreamble(0, 0, 0, 0);
|
CreateFirmwarePreamble(0, 0, 0, 0);
|
||||||
CreateKernelPreamble(0, 0, 0, 0, 0, 0);
|
CreateKernelPreamble(0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ static void VerifyKernelPreambleTest(const VbPublicKey* public_key,
|
|||||||
|
|
||||||
rsa = PublicKeyToRSA(public_key);
|
rsa = PublicKeyToRSA(public_key);
|
||||||
hdr = CreateKernelPreamble(0x1234, 0x100000, 0x300000, 0x4000, body_sig,
|
hdr = CreateKernelPreamble(0x1234, 0x100000, 0x300000, 0x4000, body_sig,
|
||||||
private_key);
|
0, private_key);
|
||||||
TEST_NEQ(hdr && rsa, 0, "VerifyKernelPreamble2() prerequisites");
|
TEST_NEQ(hdr && rsa, 0, "VerifyKernelPreamble2() prerequisites");
|
||||||
if (!hdr)
|
if (!hdr)
|
||||||
return;
|
return;
|
||||||
@@ -100,8 +100,10 @@ static void VerifyKernelPreambleTest(const VbPublicKey* public_key,
|
|||||||
|
|
||||||
TEST_EQ(VerifyKernelPreamble2(hdr, hsize, rsa), 0,
|
TEST_EQ(VerifyKernelPreamble2(hdr, hsize, rsa), 0,
|
||||||
"VerifyKernelPreamble2() ok using key");
|
"VerifyKernelPreamble2() ok using key");
|
||||||
TEST_NEQ(VerifyKernelPreamble2(hdr, hsize-1, rsa), 0,
|
TEST_NEQ(VerifyKernelPreamble2(hdr, hsize - 1, rsa), 0,
|
||||||
"VerifyKernelPreamble2() size");
|
"VerifyKernelPreamble2() size--");
|
||||||
|
TEST_EQ(VerifyKernelPreamble2(hdr, hsize + 1, rsa), 0,
|
||||||
|
"VerifyKernelPreamble2() size++");
|
||||||
|
|
||||||
/* Care about major version but not minor */
|
/* Care about major version but not minor */
|
||||||
Memcpy(h, hdr, hsize);
|
Memcpy(h, hdr, hsize);
|
||||||
@@ -191,7 +193,7 @@ int main(int argc, char* argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public_key = PublicKeyRead(argv[3], key_algorithm, 1);
|
public_key = PublicKeyReadKeyb(argv[3], key_algorithm, 1);
|
||||||
if (!public_key) {
|
if (!public_key) {
|
||||||
fprintf(stderr, "Error reading public_key");
|
fprintf(stderr, "Error reading public_key");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ static void VerifyKeyBlockTest(const VbPublicKey* public_key,
|
|||||||
TEST_EQ(VerifyKeyBlock(hdr, hsize, public_key), 0,
|
TEST_EQ(VerifyKeyBlock(hdr, hsize, public_key), 0,
|
||||||
"VerifyKeyBlock() ok using key");
|
"VerifyKeyBlock() ok using key");
|
||||||
|
|
||||||
TEST_NEQ(VerifyKeyBlock(hdr, hsize-1, NULL), 0, "VerifyKeyBlock() size");
|
TEST_NEQ(VerifyKeyBlock(hdr, hsize - 1, NULL), 0, "VerifyKeyBlock() size--");
|
||||||
|
TEST_EQ(VerifyKeyBlock(hdr, hsize + 1, NULL), 0, "VerifyKeyBlock() size++");
|
||||||
|
|
||||||
Memcpy(h, hdr, hsize);
|
Memcpy(h, hdr, hsize);
|
||||||
h->magic[0] &= 0x12;
|
h->magic[0] &= 0x12;
|
||||||
@@ -164,8 +165,10 @@ static void VerifyFirmwarePreambleTest(const VbPublicKey* public_key,
|
|||||||
|
|
||||||
TEST_EQ(VerifyFirmwarePreamble2(hdr, hsize, rsa), 0,
|
TEST_EQ(VerifyFirmwarePreamble2(hdr, hsize, rsa), 0,
|
||||||
"VerifyFirmwarePreamble2() ok using key");
|
"VerifyFirmwarePreamble2() ok using key");
|
||||||
TEST_NEQ(VerifyFirmwarePreamble2(hdr, hsize-1, rsa), 0,
|
TEST_NEQ(VerifyFirmwarePreamble2(hdr, hsize - 1, rsa), 0,
|
||||||
"VerifyFirmwarePreamble2() size");
|
"VerifyFirmwarePreamble2() size--");
|
||||||
|
TEST_EQ(VerifyFirmwarePreamble2(hdr, hsize + 1, rsa), 0,
|
||||||
|
"VerifyFirmwarePreamble2() size++");
|
||||||
|
|
||||||
/* Care about major version but not minor */
|
/* Care about major version but not minor */
|
||||||
Memcpy(h, hdr, hsize);
|
Memcpy(h, hdr, hsize);
|
||||||
@@ -268,13 +271,13 @@ int main(int argc, char* argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
signing_public_key = PublicKeyRead(argv[4], signing_key_algorithm, 1);
|
signing_public_key = PublicKeyReadKeyb(argv[4], signing_key_algorithm, 1);
|
||||||
if (!signing_public_key) {
|
if (!signing_public_key) {
|
||||||
fprintf(stderr, "Error reading signing_public_key");
|
fprintf(stderr, "Error reading signing_public_key");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_public_key = PublicKeyRead(argv[6], data_key_algorithm, 1);
|
data_public_key = PublicKeyReadKeyb(argv[6], data_key_algorithm, 1);
|
||||||
if (!data_public_key) {
|
if (!data_public_key) {
|
||||||
fprintf(stderr, "Error reading data_public_key");
|
fprintf(stderr, "Error reading data_public_key");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ LIBS = $(TOP)/misclibs/file_keys.o \
|
|||||||
$(TOP)/misclibs/signature_digest.o \
|
$(TOP)/misclibs/signature_digest.o \
|
||||||
$(TOP)/vfirmware/firmware_image.o \
|
$(TOP)/vfirmware/firmware_image.o \
|
||||||
$(TOP)/vkernel/kernel_image.o \
|
$(TOP)/vkernel/kernel_image.o \
|
||||||
$(FWLIB) \
|
$(HOSTLIB) \
|
||||||
$(HOSTLIB)
|
$(FWLIB)
|
||||||
SUBDIRS = cgpt
|
SUBDIRS = cgpt
|
||||||
|
|
||||||
DESTDIR ?= /opt/bin
|
DESTDIR ?= /opt/bin
|
||||||
@@ -32,6 +32,7 @@ TARGET_BINS = dumpRSAPublicKey \
|
|||||||
kernel_utility \
|
kernel_utility \
|
||||||
load_kernel_test \
|
load_kernel_test \
|
||||||
signature_digest_utility \
|
signature_digest_utility \
|
||||||
|
vbutil_key \
|
||||||
verify_data
|
verify_data
|
||||||
|
|
||||||
all: $(TARGET_BINS) subdirs
|
all: $(TARGET_BINS) subdirs
|
||||||
@@ -66,6 +67,9 @@ load_kernel_test: load_kernel_test.c $(LIBS)
|
|||||||
signature_digest_utility: signature_digest_utility.c $(LIBS)
|
signature_digest_utility: signature_digest_utility.c $(LIBS)
|
||||||
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
|
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
|
||||||
|
|
||||||
|
vbutil_key: vbutil_key.c $(LIBS)
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
|
||||||
|
|
||||||
verify_data: verify_data.c $(LIBS)
|
verify_data: verify_data.c $(LIBS)
|
||||||
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
|
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "load_kernel_fw.h"
|
#include "load_kernel_fw.h"
|
||||||
#include "boot_device.h"
|
#include "boot_device.h"
|
||||||
|
#include "host_common.h"
|
||||||
#include "rollback_index.h"
|
#include "rollback_index.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
@@ -95,25 +96,12 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
/* Read header signing key blob */
|
/* Read header signing key blob */
|
||||||
{
|
{
|
||||||
FILE* f;
|
uint64_t key_size;
|
||||||
int key_size;
|
lkp.header_sign_key_blob = ReadFile(keyfile_name, &key_size);
|
||||||
printf("Reading key from: %s\n", keyfile_name);
|
if (!lkp.header_sign_key_blob)
|
||||||
f = fopen(keyfile_name, "rb");
|
fprintf(stderr, "Unable to read key file %s\n", keyfile_name);
|
||||||
if (!f) {
|
|
||||||
fprintf(stderr, "Unable to open key file %s\n", keyfile_name);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
key_size = ftell(f);
|
|
||||||
rewind(f);
|
|
||||||
lkp.header_sign_key_blob = Malloc(key_size);
|
|
||||||
printf("Reading %d bytes of key\n", key_size);
|
|
||||||
if (fread(lkp.header_sign_key_blob, key_size, 1, f) != 1) {
|
|
||||||
fprintf(stderr, "Unable to read key data\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get image size */
|
/* Get image size */
|
||||||
printf("Reading from image: %s\n", image_name);
|
printf("Reading from image: %s\n", image_name);
|
||||||
|
|||||||
175
utility/vbutil_key.c
Normal file
175
utility/vbutil_key.c
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
#include <getopt.h>
|
||||||
|
#include <inttypes.h> /* For PRIu64 */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "cryptolib.h"
|
||||||
|
#include "host_common.h"
|
||||||
|
#include "vboot_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Command line options */
|
||||||
|
enum {
|
||||||
|
OPT_IN = 1000,
|
||||||
|
OPT_OUT,
|
||||||
|
OPT_KEY_VERSION,
|
||||||
|
OPT_ALGORITHM,
|
||||||
|
OPT_MODE_PACK,
|
||||||
|
OPT_MODE_UNPACK,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct option long_opts[] = {
|
||||||
|
{"in", 1, 0, OPT_IN },
|
||||||
|
{"out", 1, 0, OPT_OUT },
|
||||||
|
{"version", 1, 0, OPT_KEY_VERSION },
|
||||||
|
{"algorithm", 1, 0, OPT_ALGORITHM },
|
||||||
|
{"pack", 0, 0, OPT_MODE_PACK },
|
||||||
|
{"unpack", 0, 0, OPT_MODE_UNPACK },
|
||||||
|
{NULL, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Print help and return error */
|
||||||
|
static int PrintHelp(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
puts("vbutil_key - Verified boot key utility\n"
|
||||||
|
"\n"
|
||||||
|
"Usage: vbutil_key <--pack|--unpack> [OPTIONS]\n"
|
||||||
|
"\n"
|
||||||
|
"For '--pack', required OPTIONS are:\n"
|
||||||
|
" --in <infile> Input key in .keyb format\n"
|
||||||
|
" --out <outfile> Output file for .vbpubk format\n"
|
||||||
|
" --version <number> Key version number\n"
|
||||||
|
" --algorithm <algoid> Signing algorithm for key, one of:");
|
||||||
|
|
||||||
|
for (i = 0; i < kNumAlgorithms; i++)
|
||||||
|
printf(" %d (%s)\n", i, algo_strings[i]);
|
||||||
|
|
||||||
|
puts("\n"
|
||||||
|
"For '--unpack', required OPTIONS are:\n"
|
||||||
|
" --in <infile> Input key in .vbpubk format\n"
|
||||||
|
"Optional OPTIONS are:\n"
|
||||||
|
" --out <outfile> Output file for .keyb format\n"
|
||||||
|
"");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Pack a .keyb file into a .vbpubk */
|
||||||
|
static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
|
||||||
|
uint64_t version) {
|
||||||
|
VbPublicKey* key;
|
||||||
|
|
||||||
|
if (!infile || !outfile) {
|
||||||
|
fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = PublicKeyReadKeyb(infile, algorithm, version);
|
||||||
|
if (!key) {
|
||||||
|
fprintf(stderr, "vbutil_key: Error reading key.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != PublicKeyWrite(outfile, key)) {
|
||||||
|
fprintf(stderr, "vbutil_key: Error writing key.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Free(key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Unpack a .vbpubk */
|
||||||
|
static int Unpack(const char *infile, const char *outfile) {
|
||||||
|
VbPublicKey* key;
|
||||||
|
|
||||||
|
if (!infile) {
|
||||||
|
fprintf(stderr, "vbutil_key: Must specify --in\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = PublicKeyRead(infile);
|
||||||
|
if (!key) {
|
||||||
|
fprintf(stderr, "vbutil_key: Error reading key.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Key file: %s\n", infile);
|
||||||
|
printf("Algorithm: %" PRIu64 " %s\n", key->algorithm,
|
||||||
|
(key->algorithm < kNumAlgorithms ?
|
||||||
|
algo_strings[key->algorithm] : "(invalid)"));
|
||||||
|
printf("Version: %" PRIu64 "\n", key->key_version);
|
||||||
|
|
||||||
|
/* TODO: write key data, if any */
|
||||||
|
|
||||||
|
Free(key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
char *infile = NULL;
|
||||||
|
char *outfile = NULL;
|
||||||
|
int mode = 0;
|
||||||
|
int parse_error = 0;
|
||||||
|
uint64_t version = 1;
|
||||||
|
uint64_t algorithm = kNumAlgorithms;
|
||||||
|
char* e;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
|
||||||
|
switch (i) {
|
||||||
|
case '?':
|
||||||
|
/* Unhandled option */
|
||||||
|
printf("Unknown option\n");
|
||||||
|
parse_error = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPT_IN:
|
||||||
|
infile = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPT_OUT:
|
||||||
|
outfile = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPT_KEY_VERSION:
|
||||||
|
version = strtoul(optarg, &e, 0);
|
||||||
|
if (!*optarg || (e && *e)) {
|
||||||
|
printf("Invalid --version\n");
|
||||||
|
parse_error = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPT_ALGORITHM:
|
||||||
|
algorithm = strtoul(optarg, &e, 0);
|
||||||
|
if (!*optarg || (e && *e)) {
|
||||||
|
printf("Invalid --algorithm\n");
|
||||||
|
parse_error = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPT_MODE_PACK:
|
||||||
|
case OPT_MODE_UNPACK:
|
||||||
|
mode = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_error)
|
||||||
|
return PrintHelp();
|
||||||
|
|
||||||
|
switch(mode) {
|
||||||
|
case OPT_MODE_PACK:
|
||||||
|
return Pack(infile, outfile, algorithm, version);
|
||||||
|
case OPT_MODE_UNPACK:
|
||||||
|
return Unpack(infile, outfile);
|
||||||
|
default:
|
||||||
|
printf("Must specify a mode.\n");
|
||||||
|
return PrintHelp();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ typedef struct VbPublicKey {
|
|||||||
typedef struct VbSignature {
|
typedef struct VbSignature {
|
||||||
uint64_t sig_offset; /* Offset of signature data from start of this
|
uint64_t sig_offset; /* Offset of signature data from start of this
|
||||||
* struct */
|
* struct */
|
||||||
uint64_t sig_size; /* Size of signature data from start of this struct */
|
uint64_t sig_size; /* Size of signature data in bytes */
|
||||||
uint64_t data_size; /* Size of the data block which was signed in bytes */
|
uint64_t data_size; /* Size of the data block which was signed in bytes */
|
||||||
} VbSignature;
|
} VbSignature;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user