mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
This CL builds upon earlier firmware and kernel changes (see CLs
related to the same bug, chromium-os:12522).
ARM firmware now simulates both Nvram storage and VDAT buffer, the
structures the x86 version uses extensively to communicate back and
forth between firmware/kernel/userland.
So, to make crossystem work on arm, all what's needed is to provide
architecture specific interface to Nvram and VDAT simulation, and
architecture specific processing for variables which are accessed on
ARM platforms in a different way.
The few discrepancies and platform specifics which had to be addressed
for ARM specifically are as follows:
- the Nvram contents are cached in the shared memory and available for
reading as part of /sys/kernel/debug/chromeos_arm. When writing
Nvram, the same file needs to be written, but only the 16 bytes
(representing the Nvram contents) are aacepted.
- the VDAT buffer also comes from the shared memory (as part of the
same sysfs file)
- when crossystem starts, it needs to read in this shared memory
contents, a` weak' function VbArchInit() is being added such that it
is provided on ARM platforms only, on x86 an empty stub is called.
- current developer/recovery request/ro firmware switch states are
retrieved through GPIO drivers. The GPIO numbers are defined in the
file, the GPIO driver is supposed to be configured before
crsossystem can operate.
- the BINF values are supplied through an array within shared memory,
it would be easy to refactor both x86 and ARM use the same code to
process BINF values, but with this submission the code is duplicated
to minimize x86 impact.
- the following crossystem variables do not have ARM equivalents,
thier values are reported as '(error)':
recoverysw_ec_boot
savedmem_base
savedmem_size
BUG=chromium-os:12522
TEST=manual:
. bring up a kaen system
. execute the following script to enable the appropriate GPIOSs:
for gpio in 56 59 168; do echo $gpio > /sys/class/gpio/export; done
. run `crossystem' and observe reasonable output values
. to verify that it reads GPIOs properly, try
echo $(./crossystem recoverysw_cur)
with the miniservo 'GOOG_REC' button pressed and released, observe
different readings (note that the state of the button is reversed,
the released button is reported as '1')
. to verify the write capabilities, note that the nvram contents can
be accessed using the following shell commands
echo 3 > /proc/sys/vm/drop_caches
2>/dev/null dd if=/dev/mmcblk0 of=/tmp/blk bs=16 count=1 && \
od -t x1 /tmp/blk | head -1
(the first command cause the device cache dropped, and the second
command accesses the device contents.
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
localhost var # echo $(./crossystem fwb_tries)
10
localhost var # echo 3 > /proc/sys/vm/drop_caches
localhost var # 2>/dev/null dd if=/dev/mmcblk0 of=/tmp/blk bs=16 count=1 && od -t x1 /tmp/blk | head -1
0000000 60 0a 00 be 00 00 00 00 00 00 00 02 00 00 00 a2
localhost var # ./crossystem fwb_tries=9
localhost var # echo $(./crossystem fwb_tries)
9
localhost var # echo 3 > /proc/sys/vm/drop_caches
localhost var # 2>/dev/null dd if=/dev/mmcblk0 of=/tmp/blk bs=16 count=1 && od -t x1 /tmp/blk | head -1
0000000 60 09 00 be 00 00 00 00 00 00 00 02 00 00 00 8a
localhost var #
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Change-Id: Ie4c6ff44441d98a42b1057953208fdb90c08f46d
Reviewed-on: http://gerrit.chromium.org/gerrit/113
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Tested-by: Vadim Bendebury <vbendeb@chromium.org>
130 lines
4.6 KiB
C
130 lines
4.6 KiB
C
/* Copyright (c) 2011 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.
|
|
*
|
|
* Common functions between firmware and kernel verified boot.
|
|
*/
|
|
|
|
#ifndef VBOOT_REFERENCE_VBOOT_COMMON_H_
|
|
#define VBOOT_REFERENCE_VBOOT_COMMON_H_
|
|
|
|
#include "cryptolib.h"
|
|
#include "vboot_struct.h"
|
|
|
|
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
|
|
|
|
/* Error Codes for all common functions. */
|
|
enum {
|
|
VBOOT_SUCCESS = 0,
|
|
VBOOT_KEY_BLOCK_INVALID, /* Key block internal structure is
|
|
* invalid, or not a key block */
|
|
VBOOT_KEY_BLOCK_SIGNATURE, /* Key block signature check failed */
|
|
VBOOT_KEY_BLOCK_HASH, /* Key block hash check failed */
|
|
VBOOT_PUBLIC_KEY_INVALID, /* Invalid public key passed to a
|
|
* signature verficiation function. */
|
|
VBOOT_PREAMBLE_INVALID, /* Preamble internal structure is
|
|
* invalid */
|
|
VBOOT_PREAMBLE_SIGNATURE, /* Preamble signature check failed */
|
|
VBOOT_SHARED_DATA_INVALID, /* Shared data is invalid. */
|
|
VBOOT_ERROR_MAX,
|
|
};
|
|
extern char* kVbootErrors[VBOOT_ERROR_MAX];
|
|
|
|
|
|
/* Return offset of ptr from base. */
|
|
uint64_t OffsetOf(const void* base, const void* ptr);
|
|
|
|
|
|
/* Helper functions to get data pointed to by a public key or signature. */
|
|
uint8_t* GetPublicKeyData(VbPublicKey* key);
|
|
const uint8_t* GetPublicKeyDataC(const VbPublicKey* key);
|
|
uint8_t* GetSignatureData(VbSignature* sig);
|
|
const uint8_t* GetSignatureDataC(const VbSignature* sig);
|
|
|
|
|
|
/* Helper functions to verify the data pointed to by a subfield is inside
|
|
* the parent data. Returns 0 if inside, 1 if error. */
|
|
int VerifyMemberInside(const void* parent, uint64_t parent_size,
|
|
const void* member, uint64_t member_size,
|
|
uint64_t member_data_offset,
|
|
uint64_t member_data_size);
|
|
|
|
int VerifyPublicKeyInside(const void* parent, uint64_t parent_size,
|
|
const VbPublicKey* key);
|
|
|
|
int VerifySignatureInside(const void* parent, uint64_t parent_size,
|
|
const VbSignature* sig);
|
|
|
|
|
|
/* Initialize a public key to refer to [key_data]. */
|
|
void PublicKeyInit(VbPublicKey* key, uint8_t* key_data, uint64_t key_size);
|
|
|
|
|
|
/* Copy a public key from [src] to [dest].
|
|
*
|
|
* Returns 0 if success, non-zero if error. */
|
|
int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src);
|
|
|
|
|
|
/* Converts a public key to RsaPublicKey format. The returned key must
|
|
* be freed using RSAPublicKeyFree().
|
|
*
|
|
* Returns NULL if error. */
|
|
RSAPublicKey* PublicKeyToRSA(const VbPublicKey* key);
|
|
|
|
|
|
/* Verifies [data] matches signature [sig] using [key]. [size] is the size
|
|
* of the data buffer; the amount of data to be validated is contained in
|
|
* sig->data_size. */
|
|
int VerifyData(const uint8_t* data, uint64_t size, 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 hash_only is non-zero, uses only the block checksum
|
|
* to verify the key block. Header fields are also checked for
|
|
* sanity. Does not verify key index or key block flags. */
|
|
int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
|
|
const VbPublicKey *key, int hash_only);
|
|
|
|
|
|
/* Checks the sanity of a firmware preamble of size [size] bytes,
|
|
* using public key [key].
|
|
*
|
|
* Returns VBOOT_SUCCESS if successful. */
|
|
int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader* preamble,
|
|
uint64_t size, const RSAPublicKey* key);
|
|
|
|
|
|
/* Checks the sanity of a kernel preamble of size [size] bytes,
|
|
* using public key [key].
|
|
*
|
|
* Returns VBOOT_SUCCESS if successful. */
|
|
int VerifyKernelPreamble(const VbKernelPreambleHeader* preamble,
|
|
uint64_t size, const RSAPublicKey* key);
|
|
|
|
|
|
/* Initialize a verified boot shared data structure.
|
|
*
|
|
* Returns 0 if success, non-zero if error. */
|
|
int VbSharedDataInit(VbSharedDataHeader* header, uint64_t size);
|
|
|
|
/* Reserve [size] bytes of the shared data area. Returns the offset of the
|
|
* reserved data from the start of the shared data buffer, or 0 if error. */
|
|
uint64_t VbSharedDataReserve(VbSharedDataHeader* header, uint64_t size);
|
|
|
|
/* Copy the kernel subkey into the shared data.
|
|
*
|
|
* Returns 0 if success, non-zero if error. */
|
|
int VbSharedDataSetKernelKey(VbSharedDataHeader* header,
|
|
const VbPublicKey* src);
|
|
|
|
|
|
#endif /* VBOOT_REFERENCE_VBOOT_COMMON_H_ */
|