Switch to using .vbprivk for signing everything now.

This makes it much simpler to keep track of what we're doing.

vbutil_key can now wrap both .keyb and .pem keys. It figures out which is
which by trying both and just using the one that works.

vbutil_keyblock and vbutil_kernel now use .vbprivk files for signing.

replace debug() with VBDEBUG(()) in host-side sources, too.

rename PrivateKeyRead to PrivateKeyReadPem

Add real PrivateKeyRead and PrivateKeyWrite for .vbprivk files.

Review URL: http://codereview.chromium.org/2871033
This commit is contained in:
Bill Richardson
2010-07-01 10:22:06 -07:00
parent a08b5c9d03
commit abf0550458
20 changed files with 288 additions and 174 deletions

View File

@@ -1 +1 @@
char* VbootVersion = "VBOOv=75ccdf11";
char* VbootVersion = "VBOOv=74ad1cd7";

View File

@@ -30,6 +30,16 @@ VbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm);
/* Free a private key. */
void PrivateKeyFree(VbPrivateKey* key);
/* Write a private key to a file in .vbprivk format. */
int PrivateKeyWrite(const char* filename, const VbPrivateKey* key);
/* Read a privake key from a .vbprivk file. Caller owns the returned
* pointer, and must free it with PrivateKeyFree().
*
* Returns NULL if error. */
VbPrivateKey* PrivateKeyRead(const char* filename);
/* Allocate a new public key with space for a [key_size] byte key. */
VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,

View File

@@ -25,12 +25,12 @@ uint8_t* BufferFromFile(const char* input_file, uint64_t* len) {
uint8_t* buf = NULL;
if ((fd = open(input_file, O_RDONLY)) == -1) {
debug("Couldn't open file %s\n", input_file);
VBDEBUG(("Couldn't open file %s\n", input_file));
return NULL;
}
if (-1 == fstat(fd, &stat_fd)) {
debug("Couldn't stat file %s\n", input_file);
VBDEBUG(("Couldn't stat file %s\n", input_file));
return NULL;
}
*len = stat_fd.st_size;
@@ -42,7 +42,7 @@ uint8_t* BufferFromFile(const char* input_file, uint64_t* len) {
}
if (*len != read(fd, buf, *len)) {
debug("Couldn't read file %s into a buffer\n", input_file);
VBDEBUG(("Couldn't read file %s into a buffer\n", input_file));
return NULL;
}
@@ -67,7 +67,7 @@ uint8_t* DigestFile(char* input_file, int sig_algorithm) {
DigestContext ctx;
if( (input_fd = open(input_file, O_RDONLY)) == -1 ) {
debug("Couldn't open %s\n", input_file);
VBDEBUG(("Couldn't open %s\n", input_file));
return NULL;
}
DigestInit(&ctx, sig_algorithm);
@@ -104,13 +104,13 @@ uint8_t* SignatureFile(const char* input_file, const char* key_file,
cmd_out = popen(cmd, "r");
Free(cmd);
if (!cmd_out) {
debug("Couldn't execute: %s\n", cmd);
VBDEBUG(("Couldn't execute: %s\n", cmd));
return NULL;
}
signature = (uint8_t*) Malloc(signature_size);
if (fread(signature, signature_size, 1, cmd_out) != 1) {
debug("Couldn't read signature.\n");
VBDEBUG(("Couldn't read signature.\n"));
pclose(cmd_out);
Free(signature);
return NULL;

View File

@@ -11,6 +11,7 @@
#include <openssl/engine.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <stdio.h>
#include <stdlib.h>
@@ -31,21 +32,21 @@ VbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm) {
FILE* f;
if (algorithm >= kNumAlgorithms) {
debug("%s() called with invalid algorithm!\n", __FUNCTION__);
VBDEBUG(("%s() called with invalid algorithm!\n", __FUNCTION__));
return NULL;
}
/* Read private key */
f = fopen(filename, "r");
if (!f) {
debug("%s(): Couldn't open key file: %s\n", __FUNCTION__, filename);
VBDEBUG(("%s(): Couldn't open key file: %s\n", __FUNCTION__, filename));
return NULL;
}
rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
fclose(f);
if (!rsa_key) {
debug("%s(): Couldn't read private key from file: %s\n", __FUNCTION__,
filename);
VBDEBUG(("%s(): Couldn't read private key from file: %s\n", __FUNCTION__,
filename));
return NULL;
}
@@ -72,6 +73,83 @@ void PrivateKeyFree(VbPrivateKey* key) {
}
/* Write a private key to a file in .vbprivk format. */
int PrivateKeyWrite(const char* filename, const VbPrivateKey* key) {
uint8_t *outbuf = 0;
int buflen;
FILE *f;
buflen = i2d_RSAPrivateKey(key->rsa_private_key, &outbuf);
if (buflen <= 0) {
error("Unable to write private key buffer\n");
return 1;
}
f = fopen(filename, "wb");
if (!f) {
error("Unable to open file %s\n", filename);
Free(outbuf);
return 1;
}
if (1 != fwrite(&key->algorithm, sizeof(key->algorithm), 1, f)) {
error("Unable to write to file %s\n", filename);
fclose(f);
Free(outbuf);
unlink(filename); /* Delete any partial file */
}
if (1 != fwrite(outbuf, buflen, 1, f)) {
error("Unable to write to file %s\n", filename);
fclose(f);
unlink(filename); /* Delete any partial file */
Free(outbuf);
}
fclose(f);
Free(outbuf);
return 0;
}
VbPrivateKey* PrivateKeyRead(const char* filename) {
VbPrivateKey *key;
uint64_t filelen = 0;
uint8_t *buffer;
const unsigned char *start;
buffer = ReadFile(filename, &filelen);
if (!buffer) {
error("unable to read from file %s\n", filename);
return 0;
}
key = (VbPrivateKey*)Malloc(sizeof(VbPrivateKey));
if (!key) {
error("Unable to allocate VbPrivateKey\n");
Free(buffer);
return 0;
}
key->algorithm = *(typeof(key->algorithm) *)buffer;
start = buffer + sizeof(key->algorithm);
key->rsa_private_key = d2i_RSAPrivateKey(0, &start,
filelen - sizeof(key->algorithm));
if (!key->rsa_private_key) {
error("Unable to parse RSA private key\n");
Free(buffer);
Free(key);
return 0;
}
Free(buffer);
return key;
}
/* Allocate a new public key with space for a [key_size] byte key. */
VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,
uint64_t version) {
@@ -94,12 +172,12 @@ VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm,
uint64_t key_size;
if (algorithm >= kNumAlgorithms) {
debug("PublicKeyReadKeyb() called with invalid algorithm!\n");
VBDEBUG(("PublicKeyReadKeyb() called with invalid algorithm!\n"));
return NULL;
}
if (version > 0xFFFF) {
/* Currently, TPM only supports 16-bit version */
debug("PublicKeyReadKeyb() called with invalid version!\n");
VBDEBUG(("PublicKeyReadKeyb() called with invalid version!\n"));
return NULL;
}
@@ -108,7 +186,7 @@ VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm,
return NULL;
if (RSAProcessedKeySize(algorithm) != key_size) {
debug("PublicKeyReadKeyb() wrong key size for algorithm\n");
VBDEBUG(("PublicKeyReadKeyb() wrong key size for algorithm\n"));
Free(key_data);
return NULL;
}
@@ -136,19 +214,19 @@ VbPublicKey* PublicKeyRead(const char* filename) {
do {
/* Sanity-check key data */
if (0 != VerifyPublicKeyInside(key, file_size, key)) {
debug("PublicKeyRead() not a VbPublicKey\n");
VBDEBUG(("PublicKeyRead() not a VbPublicKey\n"));
break;
}
if (key->algorithm >= kNumAlgorithms) {
debug("PublicKeyRead() invalid algorithm\n");
VBDEBUG(("PublicKeyRead() invalid algorithm\n"));
break;
}
if (key->key_version > 0xFFFF) {
debug("PublicKeyRead() invalid version\n");
VBDEBUG(("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");
VBDEBUG(("PublicKeyRead() wrong key size for algorithm\n"));
break;
}

View File

@@ -78,14 +78,14 @@ VbKeyBlockHeader* KeyBlockRead(const char* filename) {
block = (VbKeyBlockHeader*)ReadFile(filename, &file_size);
if (!block) {
debug("Error reading key block file: %s\n", filename);
VBDEBUG(("Error reading key block file: %s\n", filename));
return NULL;
}
/* Verify the hash of the key block, since we can do that without
* the public signing key. */
if (0 != KeyBlockVerify(block, file_size, NULL)) {
debug("Invalid key block file: filename\n", filename);
VBDEBUG(("Invalid key block file: filename\n", filename));
Free(block);
return NULL;
}
@@ -98,7 +98,7 @@ VbKeyBlockHeader* KeyBlockRead(const char* filename) {
int KeyBlockWrite(const char* filename, const VbKeyBlockHeader* key_block) {
if (0 != WriteFile(filename, key_block, key_block->key_block_size)) {
debug("KeyBlockWrite() error writing key block\n");
VBDEBUG(("KeyBlockWrite() error writing key block\n"));
return 1;
}

View File

@@ -24,7 +24,7 @@ uint8_t* ReadFile(const char* filename, uint64_t* size) {
f = fopen(filename, "rb");
if (!f) {
debug("Unable to open file %s\n", filename);
VBDEBUG(("Unable to open file %s\n", filename));
return NULL;
}
@@ -39,7 +39,7 @@ uint8_t* ReadFile(const char* filename, uint64_t* size) {
}
if(1 != fread(buf, *size, 1, f)) {
debug("Unable to read from file %s\n", filename);
VBDEBUG(("Unable to read from file %s\n", filename));
fclose(f);
Free(buf);
return NULL;
@@ -53,12 +53,12 @@ uint8_t* ReadFile(const char* filename, uint64_t* size) {
int WriteFile(const char* filename, const void *data, uint64_t size) {
FILE *f = fopen(filename, "wb");
if (!f) {
debug("Unable to open file %s\n", filename);
VBDEBUG(("Unable to open file %s\n", filename));
return 1;
}
if (1 != fwrite(data, size, 1, f)) {
debug("Unable to write to file %s\n", filename);
VBDEBUG(("Unable to write to file %s\n", filename));
fclose(f);
unlink(filename); /* Delete any partial file */
}

View File

@@ -125,7 +125,7 @@ VbSignature* CalculateSignature(const uint8_t* data, uint64_t size,
Free(signature_digest);
if (-1 == rv) {
debug("SignatureBuf(): RSA_private_encrypt() failed.\n");
VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n"));
Free(sig);
return NULL;
}

View File

@@ -31,7 +31,7 @@ uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len, int algorithm) {
uint8_t* digest = NULL;
if (algorithm >= kNumAlgorithms) {
debug("SignatureDigest() called with invalid algorithm!\n");
VBDEBUG(("SignatureDigest() called with invalid algorithm!\n"));
} else if ((digest = DigestBuf(buf, len, algorithm))) {
info_digest = PrependDigestInfo(algorithm, digest);
}
@@ -49,22 +49,22 @@ uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
digestinfo_size_map[algorithm]);
key_fp = fopen(key_file, "r");
if (!key_fp) {
debug("SignatureBuf(): Couldn't open key file: %s\n", key_file);
VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n", key_file));
Free(signature_digest);
return NULL;
}
if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
signature = (uint8_t*) Malloc(siglen_map[algorithm]);
else
debug("SignatureBuf(): Couldn't read private key from file: %s\n",
key_file);
VBDEBUG(("SignatureBuf(): Couldn't read private key from file: %s\n",
key_file));
if (signature) {
if (-1 == RSA_private_encrypt(signature_digest_len, /* Input length. */
signature_digest, /* Input data. */
signature, /* Output signature. */
key, /* Key to use. */
RSA_PKCS1_PADDING)) /* Padding to use. */
debug("SignatureBuf(): RSA_private_encrypt() failed.\n");
VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n"));
}
fclose(key_fp);
if (key)

View File

@@ -33,7 +33,7 @@ int BigFirmwareTest(void) {
RSAPublicKey* root_key = RSAPublicKeyFromFile(kRootKeyPublicFile);
uint8_t* root_key_blob = BufferFromFile(kRootKeyPublicFile, &len);
uint8_t* firmware_sign_key_buf= BufferFromFile(kFirmwareKeyPublicFile, &len);
debug("Generating Big FirmwareImage...");
VBDEBUG(("Generating Big FirmwareImage..."));
FirmwareImage* image =
GenerateTestFirmwareImage(0, /* RSA1024/SHA1 */
firmware_sign_key_buf,
@@ -47,7 +47,7 @@ int BigFirmwareTest(void) {
error_code = 1;
goto cleanup;
}
debug("Done.\n");
VBDEBUG(("Done.\n"));
TEST_EQ(VerifyFirmwareImage(root_key, image),
VERIFY_FIRMWARE_SUCCESS,
"Big FirmwareImage Verification");

View File

@@ -33,7 +33,7 @@ int BigKernelTest() {
RSAPublicKey* firmware_key = RSAPublicKeyFromFile(kFirmwareKeyPublicFile);
uint8_t* firmware_key_blob = BufferFromFile(kFirmwareKeyPublicFile, &len);
uint8_t* kernel_sign_key_buf = BufferFromFile(kKernelKeyPublicFile, &len);
debug("Generating Big KernelImage...");
VBDEBUG(("Generating Big KernelImage..."));
KernelImage* image =
GenerateTestKernelImage(3, /* RSA2048/SHA1 */
0, /* RSA1024/SHA1 */
@@ -48,7 +48,7 @@ int BigKernelTest() {
error_code = 1;
goto cleanup;
}
debug("Done.\n");
VBDEBUG(("Done.\n"));
TEST_EQ(VerifyKernelImage(firmware_key, image, 0),
VERIFY_KERNEL_SUCCESS,
"Big KernelImage Verification");

View File

@@ -61,7 +61,7 @@ int SpeedTestAlgorithm(int algorithm) {
snprintf(file_name, FILE_NAME_SIZE, "testkeys/key_rsa%d.keyb", key_size);
firmware_sign_key = BufferFromFile(file_name, &len);
if (!firmware_sign_key) {
debug("Couldn't read pre-processed firmware signing key.\n");
VBDEBUG(("Couldn't read pre-processed firmware signing key.\n"));
error_code = 1;
goto cleanup;
}
@@ -79,7 +79,7 @@ int SpeedTestAlgorithm(int algorithm) {
"testkeys/key_rsa8192.pem",
firmware_sign_key_file);
if (!firmware_blobs[i]) {
debug("Couldn't generate test firmware images.\n");
VBDEBUG(("Couldn't generate test firmware images.\n"));
error_code = 1;
goto cleanup;
}
@@ -88,7 +88,7 @@ int SpeedTestAlgorithm(int algorithm) {
/* Get pre-processed key used for verification. */
root_key_blob = BufferFromFile("testkeys/key_rsa8192.keyb", &len);
if (!root_key_blob) {
debug("Couldn't read pre-processed rootkey.\n");
VBDEBUG(("Couldn't read pre-processed rootkey.\n"));
error_code = 1;
goto cleanup;
}
@@ -101,7 +101,7 @@ int SpeedTestAlgorithm(int algorithm) {
VerifyFirmware(root_key_blob,
verification_blobs[i],
firmware_blobs[i]))
debug("Warning: Firmware Verification Failed.\n");
VBDEBUG(("Warning: Firmware Verification Failed.\n"));
}
StopTimer(&ct);
msecs = (float) GetDurationMsecs(&ct) / NUM_OPERATIONS;

View File

@@ -61,7 +61,7 @@ void VerifyKernelDriverTest(void) {
* the full blown kernel boot logic. Updates to the kernel attributes
* in the paritition table are not tested.
*/
debug("Kernel A boot priority(15) > Kernel B boot priority(1)\n");
VBDEBUG(("Kernel A boot priority(15) > Kernel B boot priority(1)\n"));
TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
&valid_kernelA, &valid_kernelB,
DEV_MODE_DISABLED),
@@ -87,8 +87,8 @@ void VerifyKernelDriverTest(void) {
"(Corrupt Kernel A (current version)\n"
" Corrupt Kernel B (current version) runs Recovery):");
debug("\nSwapping boot priorities...\n"
"Kernel B boot priority(15) > Kernel A boot priority(1)\n");
VBDEBUG(("\nSwapping boot priorities...\n"
"Kernel B boot priority(15) > Kernel A boot priority(1)\n"));
valid_kernelA.boot_priority = corrupt_kernelA.boot_priority = 1;
valid_kernelB.boot_priority = corrupt_kernelB.boot_priority = 15;
TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
@@ -116,8 +116,8 @@ void VerifyKernelDriverTest(void) {
"(Corrupt Kernel A (current version)\n"
" Corrupt Kernel B (current version) runs Recovery):");
debug("\nUpdating stored version information. Obsoleting "
"exiting kernel images.\n");
VBDEBUG(("\nUpdating stored version information. Obsoleting "
"exiting kernel images.\n"));
g_kernel_key_version = 2;
g_kernel_version = 2;
TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
@@ -127,8 +127,8 @@ void VerifyKernelDriverTest(void) {
"(Valid Kernel A (old version)\n"
" Valid Kernel B (old version) runs Recovery):");
debug("\nGenerating updated Kernel A blob with "
"new version.\n");
VBDEBUG(("\nGenerating updated Kernel A blob with "
"new version.\n"));
Free(valid_kernelA.kernel_blob);
valid_kernelA.kernel_blob = GenerateRollbackTestKernelBlob(3, 3, 0);
TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,

View File

@@ -73,7 +73,7 @@ int SpeedTestAlgorithm(int firmware_sign_algorithm,
kernel_key_size);
kernel_sign_key = BufferFromFile(file_name, &len);
if (!kernel_sign_key) {
debug("Couldn't read pre-processed public kernel signing key.\n");
VBDEBUG(("Couldn't read pre-processed public kernel signing key.\n"));
error_code = 1;
goto cleanup;
}
@@ -89,7 +89,7 @@ int SpeedTestAlgorithm(int firmware_sign_algorithm,
firmware_sign_key_file,
kernel_sign_key_file);
if (!kernel_blobs[i]) {
debug("Couldn't generate test firmware images.\n");
VBDEBUG(("Couldn't generate test firmware images.\n"));
error_code = 1;
goto cleanup;
}
@@ -100,7 +100,7 @@ int SpeedTestAlgorithm(int firmware_sign_algorithm,
firmware_key_size);
firmware_key_blob = BufferFromFile(file_name, &len);
if (!firmware_key_blob) {
debug("Couldn't read pre-processed firmware public key.\n");
VBDEBUG(("Couldn't read pre-processed firmware public key.\n"));
error_code = 1;
goto cleanup;
}
@@ -111,7 +111,7 @@ int SpeedTestAlgorithm(int firmware_sign_algorithm,
for (j = 0; j < NUM_OPERATIONS; ++j) {
if (VERIFY_KERNEL_SUCCESS !=
VerifyKernel(firmware_key_blob, kernel_blobs[i], 0))
debug("Warning: Kernel Verification Failed.\n");
VBDEBUG(("Warning: Kernel Verification Failed.\n"));
}
StopTimer(&ct);
msecs = (float) GetDurationMsecs(&ct) / NUM_OPERATIONS;

View File

@@ -20,7 +20,7 @@ __pragma(warning (disable: 4100))
uint32_t SetupTPM(int mode, int developer_flag) {
#ifndef NDEBUG
debug("Rollback Index Library Mock: TPM initialized.\n");
VBDEBUG(("Rollback Index Library Mock: TPM initialized.\n"));
#endif
return TPM_SUCCESS;
}
@@ -51,21 +51,21 @@ uint32_t WriteStoredVersions(int type, uint16_t key_version, uint16_t version) {
break;
}
#ifndef NDEBUG
debug("Rollback Index Library Mock: Stored Versions written.\n");
VBDEBUG(("Rollback Index Library Mock: Stored Versions written.\n"));
#endif
return TPM_SUCCESS;
}
uint32_t LockFirmwareVersions(void) {
#ifndef NDEBUG
debug("Rollback Index Library Mock: Firmware Versions Locked.\n");
VBDEBUG(("Rollback Index Library Mock: Firmware Versions Locked.\n"));
#endif
return TPM_SUCCESS;
}
uint32_t LockKernelVersionsByLockingPP(void) {
#ifndef NDEBUG
debug("Rollback Index Library Mock: Kernel Versions Locked.\n");
VBDEBUG(("Rollback Index Library Mock: Kernel Versions Locked.\n"));
#endif
return TPM_SUCCESS;
}

View File

@@ -36,7 +36,7 @@ int SpeedTestAlgorithm(int algorithm) {
snprintf(file_name, FILE_NAME_SIZE, "testkeys/key_rsa%d.keyb", key_size);
key = RSAPublicKeyFromFile(file_name);
if (!key) {
debug("Couldn't read RSA Public key from file: %s\n", file_name);
VBDEBUG(("Couldn't read RSA Public key from file: %s\n", file_name));
error_code = 1;
goto failure;
}
@@ -46,7 +46,7 @@ int SpeedTestAlgorithm(int algorithm) {
sha_strings[algorithm]);
digest = BufferFromFile(file_name, &digest_len);
if (!digest) {
debug("Couldn't read digest file.\n");
VBDEBUG(("Couldn't read digest file.\n"));
error_code = 1;
goto failure;
}
@@ -56,7 +56,7 @@ int SpeedTestAlgorithm(int algorithm) {
key_size, sha_strings[algorithm]);
signature = BufferFromFile(file_name, &sig_len);
if (!signature) {
debug("Couldn't read signature file.\n");
VBDEBUG(("Couldn't read signature file.\n"));
error_code = 1;
goto failure;
}
@@ -64,7 +64,7 @@ int SpeedTestAlgorithm(int algorithm) {
StartTimer(&ct);
for (i = 0; i < NUM_OPERATIONS; i++) {
if (!RSAVerify(key, signature, sig_len, algorithm, digest))
debug("Warning: Signature Check Failed.\n");
VBDEBUG(("Warning: Signature Check Failed.\n"));
}
StopTimer(&ct);

View File

@@ -19,9 +19,9 @@ function test_vbutil_key {
do
echo -e "For signing key ${COL_YELLOW}RSA-$keylen/$hashalgo${COL_STOP}:"
# Pack the key
${UTIL_DIR}/vbutil_key --pack \
--in ${TESTKEY_DIR}/key_rsa${keylen}.keyb \
--out ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk \
${UTIL_DIR}/vbutil_key \
--pack ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk \
--key ${TESTKEY_DIR}/key_rsa${keylen}.keyb \
--version 1 \
--algorithm $algorithmcounter
if [ $? -ne 0 ]
@@ -31,8 +31,8 @@ function test_vbutil_key {
# Unpack the key
# TODO: should verify we get the same key back out?
${UTIL_DIR}/vbutil_key --unpack \
--in ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk
${UTIL_DIR}/vbutil_key \
--unpack ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk
if [ $? -ne 0 ]
then
return_code=255
@@ -68,12 +68,22 @@ ${datahashalgo}${COL_STOP}"
keyblockfile+="${data_algorithmcounter}.keyblock"
rm -f ${keyblockfile}
# Wrap
${UTIL_DIR}/vbutil_key \
--pack ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbprivk \
--key ${TESTKEY_DIR}/key_rsa${signing_keylen}.pem \
--algorithm $signing_algorithmcounter
if [ $? -ne 0 ]
then
return_code=255
fi
# Pack
${UTIL_DIR}/vbutil_keyblock --pack ${keyblockfile} \
--datapubkey \
${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk \
--signprivate ${TESTKEY_DIR}/key_rsa${signing_keylen}.pem \
--algorithm $signing_algorithmcounter
${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk \
--signprivate \
${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbprivk
if [ $? -ne 0 ]
then
return_code=255

View File

@@ -75,7 +75,7 @@ static void* MapFile(const char *filename, size_t *size) {
f = fopen(filename, "rb");
if (!f) {
debug("Unable to open file %s\n", filename);
VBDEBUG(("Unable to open file %s\n", filename));
return NULL;
}

View File

@@ -460,7 +460,7 @@ static int Pack(const char* outfile, const char* keyblock_file,
return 1;
}
signing_key = PrivateKeyReadPem(signprivate, key_block->data_key.algorithm);
signing_key = PrivateKeyRead(signprivate);
if (!signing_key) {
error("Error reading signing key.\n");
return 1;

View File

@@ -7,8 +7,10 @@
#include <getopt.h>
#include <inttypes.h> /* For PRIu64 */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cryptolib.h"
#include "host_common.h"
@@ -17,8 +19,7 @@
/* Command line options */
enum {
OPT_IN = 1000,
OPT_OUT,
OPT_INKEY = 1000,
OPT_KEY_VERSION,
OPT_ALGORITHM,
OPT_MODE_PACK,
@@ -26,94 +27,116 @@ enum {
};
static struct option long_opts[] = {
{"in", 1, 0, OPT_IN },
{"out", 1, 0, OPT_OUT },
{"key", 1, 0, OPT_INKEY },
{"version", 1, 0, OPT_KEY_VERSION },
{"algorithm", 1, 0, OPT_ALGORITHM },
{"pack", 0, 0, OPT_MODE_PACK },
{"unpack", 0, 0, OPT_MODE_UNPACK },
{"pack", 1, 0, OPT_MODE_PACK },
{"unpack", 1, 0, OPT_MODE_UNPACK },
{NULL, 0, 0, 0}
};
/* Print help and return error */
static int PrintHelp(void) {
static int PrintHelp(char *progname) {
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:");
fprintf(stderr,
"This program wraps RSA keys with verified boot headers\n");
fprintf(stderr,
"\n"
"Usage: %s --pack <outfile> [PARAMETERS]\n"
"\n"
" Required parameters:\n"
" --key <infile> RSA key file (.keyb or .pem)\n"
" --version <number> Key version number "
"(required for .keyb, ignored for .pem)\n"
" --algorithm <number> Signing algorithm to use with key:\n",
progname);
for (i = 0; i < kNumAlgorithms; i++)
printf(" %d (%s)\n", i, algo_strings[i]);
for (i = 0; i < kNumAlgorithms; i++) {
fprintf(stderr,
" %d = (%s)\n",
i, algo_strings[i]);
}
fprintf(stderr,
"\nOR\n\n"
"Usage: %s --unpack <infile>\n"
"\n",
progname);
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 */
/* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */
static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
uint64_t version) {
VbPublicKey* key;
VbPublicKey* pubkey;
VbPrivateKey* privkey;
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 ((pubkey = PublicKeyReadKeyb(infile, algorithm, version))) {
if (0 != PublicKeyWrite(outfile, pubkey)) {
fprintf(stderr, "vbutil_key: Error writing key.\n");
return 1;
}
Free(pubkey);
return 0;
}
if (0 != PublicKeyWrite(outfile, key)) {
fprintf(stderr, "vbutil_key: Error writing key.\n");
return 1;
}
if ((privkey = PrivateKeyReadPem(infile, algorithm))) {
if (0 != PrivateKeyWrite(outfile, privkey)) {
fprintf(stderr, "vbutil_key: Error writing key.\n");
return 1;
}
Free(privkey);
return 0;
}
Free(key);
return 0;
error("Unable to parse either .keyb or .pem from %s\n", infile);
return 1;
}
/* Unpack a .vbpubk */
/* Unpack a .vbpubk or .vbprivk */
static int Unpack(const char *infile, const char *outfile) {
VbPublicKey* key;
VbPublicKey* pubkey;
VbPrivateKey* privkey;
if (!infile) {
fprintf(stderr, "vbutil_key: Must specify --in\n");
fprintf(stderr, "Need file to unpack\n");
return 1;
}
key = PublicKeyRead(infile);
if (!key) {
fprintf(stderr, "vbutil_key: Error reading key.\n");
return 1;
if ((pubkey = PublicKeyRead(infile))) {
printf("Public Key file: %s\n", infile);
printf("Algorithm: %" PRIu64 " %s\n", pubkey->algorithm,
(pubkey->algorithm < kNumAlgorithms ?
algo_strings[pubkey->algorithm] : "(invalid)"));
printf("Key Version: %" PRIu64 "\n", pubkey->key_version);
Free(pubkey);
return 0;
}
if ((privkey = PrivateKeyRead(infile))) {
printf("Private Key file: %s\n", infile);
printf("Algorithm: %" PRIu64 " %s\n", privkey->algorithm,
(privkey->algorithm < kNumAlgorithms ?
algo_strings[privkey->algorithm] : "(invalid)"));
Free(privkey);
return 0;
}
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;
error("Unable to parse either .vbpubk or vbprivk from %s\n", infile);
return 1;
}
@@ -128,26 +151,28 @@ int main(int argc, char* argv[]) {
char* e;
int i;
char *progname = strrchr(argv[0], '/');
if (progname)
progname++;
else
progname = argv[0];
while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
switch (i) {
case '?':
/* Unhandled option */
printf("Unknown option\n");
error("Unknown option\n");
parse_error = 1;
break;
case OPT_IN:
case OPT_INKEY:
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");
error("Invalid --version\n");
parse_error = 1;
}
break;
@@ -155,20 +180,25 @@ int main(int argc, char* argv[]) {
case OPT_ALGORITHM:
algorithm = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {
printf("Invalid --algorithm\n");
error("Invalid --algorithm\n");
parse_error = 1;
}
break;
case OPT_MODE_PACK:
mode = i;
outfile = optarg;
break;
case OPT_MODE_UNPACK:
mode = i;
infile = optarg;
break;
}
}
if (parse_error)
return PrintHelp();
return PrintHelp(progname);
switch(mode) {
case OPT_MODE_PACK:
@@ -177,6 +207,6 @@ int main(int argc, char* argv[]) {
return Unpack(infile, outfile);
default:
printf("Must specify a mode.\n");
return PrintHelp();
return PrintHelp(progname);
}
}

View File

@@ -9,6 +9,7 @@
#include <inttypes.h> /* For PRIu64 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cryptolib.h"
#include "host_common.h"
@@ -22,7 +23,6 @@ enum {
OPT_DATAPUBKEY,
OPT_SIGNPUBKEY,
OPT_SIGNPRIVATE,
OPT_ALGORITHM,
OPT_FLAGS,
};
@@ -32,45 +32,38 @@ static struct option long_opts[] = {
{"datapubkey", 1, 0, OPT_DATAPUBKEY },
{"signpubkey", 1, 0, OPT_SIGNPUBKEY },
{"signprivate", 1, 0, OPT_SIGNPRIVATE },
{"algorithm", 1, 0, OPT_ALGORITHM },
{"flags", 1, 0, OPT_FLAGS },
{NULL, 0, 0, 0}
};
/* Print help and return error */
static int PrintHelp(void) {
int i;
puts("vbutil_keyblock - Verified boot key block utility\n"
"\n"
"Usage: vbutil_keyblock <--pack|--unpack> <file> [OPTIONS]\n"
"\n"
"For '--pack <file>', required OPTIONS are:\n"
" --datapubkey <file> Data public key in .vbpubk format\n"
" --signprivate <file> Signing private key in .pem format\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"
"Optional OPTIONS are:\n"
" --flags <number> Flags\n"
"\n"
"For '--unpack <file>', required OPTIONS are:\n"
" --signpubkey <file> Signing public key in .vbpubk format\n"
"Optional OPTIONS are:\n"
" --datapubkey <file> Data public key output file\n"
"");
static int PrintHelp(char *progname) {
fprintf(stderr,
"Verified boot key block utility\n"
"\n"
"Usage: %s <--pack|--unpack> <file> [OPTIONS]\n"
"\n"
"For '--pack <file>', required OPTIONS are:\n"
" --datapubkey <file> Data public key in .vbpubk format\n"
" --signprivate <file>"
" Signing private key in .vbprivk format\n"
"\n"
"Optional OPTIONS are:\n"
" --flags <number> Flags\n"
"\n"
"For '--unpack <file>', required OPTIONS are:\n"
" --signpubkey <file> Signing public key in .vbpubk format\n"
"Optional OPTIONS are:\n"
" --datapubkey <file> Data public key output file\n",
progname);
return 1;
}
/* Pack a .keyblock */
static int Pack(const char* outfile, const char* datapubkey,
const char* signprivate, uint64_t algorithm,
uint64_t flags) {
const char* signprivate, uint64_t flags) {
VbPublicKey* data_key;
VbPrivateKey* signing_key;
VbKeyBlockHeader* block;
@@ -83,17 +76,13 @@ static int Pack(const char* outfile, const char* datapubkey,
fprintf(stderr, "vbutil_keyblock: Must specify all keys\n");
return 1;
}
if (algorithm >= kNumAlgorithms) {
fprintf(stderr, "Invalid algorithm\n");
return 1;
}
data_key = PublicKeyRead(datapubkey);
if (!data_key) {
fprintf(stderr, "vbutil_keyblock: Error reading data key.\n");
return 1;
}
signing_key = PrivateKeyReadPem(signprivate, algorithm);
signing_key = PrivateKeyRead(signprivate);
if (!signing_key) {
fprintf(stderr, "vbutil_keyblock: Error reading signing key.\n");
return 1;
@@ -168,12 +157,17 @@ int main(int argc, char* argv[]) {
char* signpubkey = NULL;
char* signprivate = NULL;
uint64_t flags = 0;
uint64_t algorithm = kNumAlgorithms;
int mode = 0;
int parse_error = 0;
char* e;
int i;
char *progname = strrchr(argv[0], '/');
if (progname)
progname++;
else
progname = argv[0];
while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
switch (i) {
case '?':
@@ -200,14 +194,6 @@ int main(int argc, char* argv[]) {
signprivate = optarg;
break;
case OPT_ALGORITHM:
algorithm = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {
printf("Invalid --algorithm\n");
parse_error = 1;
}
break;
case OPT_FLAGS:
flags = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {
@@ -219,15 +205,15 @@ int main(int argc, char* argv[]) {
}
if (parse_error)
return PrintHelp();
return PrintHelp(progname);
switch(mode) {
case OPT_MODE_PACK:
return Pack(filename, datapubkey, signprivate, algorithm, flags);
return Pack(filename, datapubkey, signprivate, flags);
case OPT_MODE_UNPACK:
return Unpack(filename, datapubkey, signpubkey);
default:
printf("Must specify a mode.\n");
return PrintHelp();
return PrintHelp(progname);
}
}