Files
OpenCellular/include/firmware_image.h
Gaurav Shah f5564fa98c Vboot Reference: Refactor Code.
This CL does the following:
1) It adds a SignatureBuf function which uses the OpenSSL library to generate RSA signature. This is more robust than the previous way of invoking the command line "openssl" utility and capturing its output. No more unnecessary temporary files for signature operations.
2) It adds functions that allow direct manipulation of binary verified Firmware and Kernel Image blobs in memory.
3) It changes the structure field members for FirmwareImage to make it consistent with KernelImage. Now it's clearer which key is used when.
4) Minor bug fixes and slightly improved API for dealing verified boot firmware and kernel images.
5) Renames the RSA_verify function to prevent conflicts with OpenSSL since it's linked into the firmware utility binary.

Review URL: http://codereview.chromium.org/661353
2010-03-02 15:40:01 -08:00

190 lines
6.9 KiB
C

/* 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.
*
* Data structure and API definitions for a verified boot firmware image.
*/
#ifndef VBOOT_REFERENCE_FIRMWARE_IMAGE_H_
#define VBOOT_REFERENCE_FIRMWARE_IMAGE_H_
#include <inttypes.h>
#include "rsa.h"
#include "sha.h"
#define FIRMWARE_MAGIC "CHROMEOS"
#define FIRMWARE_MAGIC_SIZE 8
#define FIRMWARE_PREAMBLE_SIZE 8
/* RSA 8192 and SHA-512. */
#define ROOT_SIGNATURE_ALGORITHM 11
#define ROOT_SIGNATURE_ALGORITHM_STRING "11"
typedef struct FirmwareImage {
uint8_t magic[FIRMWARE_MAGIC_SIZE];
/* Key Header */
uint16_t header_len; /* Length of the header. */
uint16_t firmware_sign_algorithm; /* Signature algorithm used by the signing
* key. */
uint8_t* firmware_sign_key; /* Pre-processed public half of signing key. */
uint16_t firmware_key_version; /* Key Version# for preventing rollbacks. */
uint8_t header_checksum[SHA512_DIGEST_SIZE]; /* SHA-512 hash of the header.*/
uint8_t firmware_key_signature[RSA8192NUMBYTES]; /* Signature of the header
* above. */
/* Firmware Preamble. */
uint16_t firmware_version; /* Firmware Version# for preventing rollbacks.*/
uint32_t firmware_len; /* Length of the rest of the R/W firmware data. */
uint8_t preamble[FIRMWARE_PREAMBLE_SIZE]; /* Remaining preamble data.*/
uint8_t* preamble_signature; /* Signature over the preamble. */
/* The firmware signature comes first as it may allow us to parallelize
* the firmware data fetch and RSA public operation.
*/
uint8_t* firmware_signature; /* Signature on [firmware_data]. */
uint8_t* firmware_data; /* Rest of firmware data */
} FirmwareImage;
/* Allocate and return a new FirmwareImage structure. */
FirmwareImage* FirmwareImageNew(void);
/* Deep free the contents of [fw]. */
void FirmwareImageFree(FirmwareImage* fw);
/* Read firmware data from file named [input_file].
*
* Returns a filled up FirmwareImage structure on success, NULL on error.
*/
FirmwareImage* ReadFirmwareImage(const char* input_file);
/* Get firmware header binary blob from an [image].
*
* Caller owns the returned pointer and must Free() it.
*/
uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image);
/* Get firmware preamble binary blob from an [image].
*
* Caller owns the returned pointer and must Free() it.
*/
uint8_t* GetFirmwarePreambleBlob(const FirmwareImage* image);
/* Get a verified firmware binary blob from an [image] and fill its
* length into blob_len.
*
* Caller owns the returned pointer and must Free() it.
*/
uint8_t* GetFirmwareBlob(const FirmwareImage* image, int* blob_len);
/* Write firmware data from [image] into a file named [input_file].
*
* Return 1 on success, 0 on failure.
*/
int WriteFirmwareImage(const char* input_file,
const FirmwareImage* image);
/* Pretty print the contents of [image]. Only headers and metadata information
* is printed.
*/
void PrintFirmwareImage(const FirmwareImage* image);
/* Error Codes for VerifyFirmware* family of functions. */
#define VERIFY_FIRMWARE_SUCCESS 0
#define VERIFY_FIRMWARE_INVALID_IMAGE 1
#define VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED 2
#define VERIFY_FIRMWARE_INVALID_ALGORITHM 3
#define VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED 4
#define VERIFY_FIRMWARE_SIGNATURE_FAILED 5
#define VERIFY_FIRMWARE_WRONG_MAGIC 6
#define VERIFY_FIRMWARE_MAX 7 /* Generic catch-all. */
extern char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX];
/* Checks for the sanity of the firmware header pointed by [header_blob].
* If [dev_mode] is enabled, also checks the root key signature using the
* pre-processed public root key [root_key_blob].
*
* On success, put signature algorithm in [algorithm], header length
* in [header_len], and return 0.
* Else, return error code on failure.
*/
int VerifyFirmwareHeader(const uint8_t* root_key_blob,
const uint8_t* header_blob,
const int dev_mode,
int* algorithm,
int* header_len);
/* Checks the preamble signature on firmware preamble pointed by
* [preamble_blob] using the signing key [sign_key].
*
* On success, put firmware length into [firmware_len], and return 0.
* Else, return error code on failure.
*/
int VerifyFirmwarePreamble(RSAPublicKey* sign_key,
const uint8_t* preamble_blob,
int algorithm,
int* firmware_len);
/* Checks the signature on the firmware data at location [firmware_data_start].
* The length of the actual firmware data is firmware_len and it is assumed to
* be prepended with the signature whose size depends on the signature_algorithm
* [algorithm].
*
* Return 0 on success, error code on failure.
*/
int VerifyFirmwareData(RSAPublicKey* sign_key,
const uint8_t* firmware_data_start,
int firmware_len,
int algorithm);
/* Performs a chained verify of the firmware blob [firmware_blob]. If
* [dev_mode] is 0 [inactive], then the pre-processed public root key
* [root_key_blob] is used the verify the signature of the signing key,
* else the check is skipped.
*
* Returns 0 on success, error code on failure.
*
* NOTE: The length of the firmware blob is derived from reading the fields
* in the first few bytes of the buffer. This might look risky but in firmware
* land, the start address of the firmware_blob will always be fixed depending
* on the memory map on the particular platform. In addition, the signature on
* length itself is checked early in the verification process for extra safety.
*/
int VerifyFirmware(const uint8_t* root_key_blob,
const uint8_t* firmware_blob,
const int dev_mode);
/* Performs a chained verify of the firmware [image]. If [dev_mode] is
* 0 (inactive), then the [root_key] is used to verify the signature of
* the signing key, else the check is skipped.
*
* Returns 0 on success, error code on failure.
*/
int VerifyFirmwareImage(const RSAPublicKey* root_key,
const FirmwareImage* image,
const int dev_mode);
/* Maps error codes from VerifyFirmware() to error description. */
const char* VerifyFirmwareErrorString(int error);
/* Add a root key signature to the key header to a firmware image [image]
* using the private root key in file [root_key_file].
*
* Return 1 on success, 0 on failure.
*/
int AddFirmwareKeySignature(FirmwareImage* image, const char* root_key_file);
/* Add firmware and preamble signature to a firmware image [image]
* using the private signing key in file [signing_key_file].
*
* Return 1 on success, 0 on failure.
*/
int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file);
#endif /* VBOOT_REFERENCE_FIRMWARE_IMAGE_H_ */