futility: Make rwsig sign command produce EC_RW image
This change makes futility write out a EC_RW image to the filesystem. It also allows the command to run without '--prikey' option. When a private key isn't provided, the command copies the previous signature. This can be used to extract EC_RW without changing the key or the signature. Since data only mode doesn't have a previous signature, the command returns error if '--prikey' isn't specified (as done before). BUG=b:65027647 BRANCH=none TEST=Run futility as follows futility sign --type rwsig ec.RW.flat ec.RW.sig (Missing key error, expected) futility sign --type rwsig ec.bin (EC_RW.bin is produced) futility sign --type rwsig EC_RW.bin futility sign --type rwsig --prikey key.vbprik2 ec.RW.flat ec.RW.sig futility sign --type rwsig --prikey key.vbprik2 ec.bin (EC_RW.bin is produced) futility sign --type rwsig --prikey key.vbprik2 EC_RW.bin make runfutiltests Change-Id: I8c1e0cef147967cfd6d28aa7272b88c03e109e0d Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/647804 Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
parent
f78d505e04
commit
3d25d2b4ba
|
@ -495,12 +495,16 @@ static void print_help_rwsig(int argc, char *argv[])
|
|||
"If INFILE contains an FMAP, RW and signatures offsets are read from\n"
|
||||
"FMAP. These regions must be named EC_RW and SIG_RW respectively.\n"
|
||||
"If a public key is found in the region named KEY_RO, it will be replaced\n"
|
||||
"in the RO image.\n"
|
||||
"in the RO image. This mode also produces EC_RW.bin which is a EC_RW\n"
|
||||
"region image (same as the input file for 'Data + Signature mode').\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"\n"
|
||||
" --prikey FILE.vbprik2 Private key in vb2 format (required)\n"
|
||||
" --version NUM Public key version if we are replacing"
|
||||
" --prikey FILE.vbprik2 Private key in vb2 format. Required\n"
|
||||
" if INFILE is a binary blob. If not\n"
|
||||
" provided, previous signature is copied\n"
|
||||
" and a public key won't be replaced.\n"
|
||||
" --version NUM Public key version if we are replacing\n"
|
||||
" the key in INFILE (default: 1)\n"
|
||||
" --sig_size NUM Offset from the end of INFILE where the\n"
|
||||
" signature blob should be located, if\n"
|
||||
|
@ -972,7 +976,9 @@ static int do_sign(int argc, char *argv[])
|
|||
"hash_alg");
|
||||
break;
|
||||
case FILE_TYPE_RWSIG:
|
||||
errorcnt += no_opt_if(!sign_option.prikey, "prikey");
|
||||
if (sign_option.inout_file_count > 1)
|
||||
/* Signing raw data. No signature pre-exists. */
|
||||
errorcnt += no_opt_if(!sign_option.prikey, "prikey");
|
||||
break;
|
||||
default:
|
||||
/* Anything else we don't care */
|
||||
|
|
|
@ -28,10 +28,12 @@
|
|||
#include "vb21_common.h"
|
||||
#include "host_common.h"
|
||||
#include "host_key2.h"
|
||||
#include "host_misc.h"
|
||||
#include "host_signature2.h"
|
||||
#include "util_misc.h"
|
||||
|
||||
#define SIGNATURE_RSVD_SIZE 1024
|
||||
#define EC_RW_FILENAME "EC_RW.bin"
|
||||
|
||||
static inline void vb2_print_bytes(const void *ptr, uint32_t len)
|
||||
{
|
||||
|
@ -215,14 +217,13 @@ int ft_sign_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
|
|||
int retval = 1;
|
||||
FmapHeader *fmap = NULL;
|
||||
FmapAreaHeader *fmaparea;
|
||||
const struct vb21_signature *old_sig = 0;
|
||||
|
||||
Debug("%s(): name %s\n", __func__, name);
|
||||
Debug("%s(): len 0x%08x (%d)\n", __func__, len, len);
|
||||
|
||||
/* If we don't have a distinct OUTFILE, look for an existing sig */
|
||||
if (sign_option.inout_file_count < 2) {
|
||||
const struct vb21_signature *old_sig;
|
||||
|
||||
fmap = fmap_find(buf, len);
|
||||
|
||||
if (fmap) {
|
||||
|
@ -284,12 +285,26 @@ int ft_sign_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
|
|||
data_size = sign_option.data_size;
|
||||
|
||||
/* Sign the blob */
|
||||
r = vb21_sign_data(&tmp_sig, data, data_size, sign_option.prikey, 0);
|
||||
if (r) {
|
||||
fprintf(stderr,
|
||||
"Unable to sign data (error 0x%08x, if that helps)\n",
|
||||
r);
|
||||
goto done;
|
||||
if (sign_option.prikey) {
|
||||
r = vb21_sign_data(&tmp_sig,
|
||||
data, data_size, sign_option.prikey, 0);
|
||||
if (r) {
|
||||
fprintf(stderr,
|
||||
"Unable to sign data (error 0x%08x)\n", r);
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
Debug("Private key not provided. Copying previous signature\n");
|
||||
if (!old_sig) {
|
||||
/* This isn't necessary because no prikey mode runs only
|
||||
* for fmap input or RW input */
|
||||
fprintf(stderr, "Previous signature not found.\n");
|
||||
goto done;
|
||||
}
|
||||
tmp_sig = calloc(1, old_sig->c.total_size);
|
||||
if (!tmp_sig)
|
||||
goto done;
|
||||
memcpy(tmp_sig, old_sig, old_sig->c.total_size);
|
||||
}
|
||||
|
||||
if (sign_option.inout_file_count < 2) {
|
||||
|
@ -301,6 +316,13 @@ int ft_sign_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
|
|||
}
|
||||
memset(buf + len - sig_size, 0xff, sig_size);
|
||||
memcpy(buf + len - sig_size, tmp_sig, tmp_sig->c.total_size);
|
||||
if (fmap) {
|
||||
Debug("Writing %s (size=%d)\n",
|
||||
EC_RW_FILENAME, fmaparea->area_size);
|
||||
if (vb2_write_file(EC_RW_FILENAME,
|
||||
data, fmaparea->area_size))
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
/* Write the signature to a new file */
|
||||
r = vb21_write_object(sign_option.outfile, tmp_sig);
|
||||
|
@ -311,8 +333,9 @@ int ft_sign_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin)
|
|||
}
|
||||
}
|
||||
|
||||
/* For full images, let's replace the public key in RO. */
|
||||
if (fmap) {
|
||||
/* For full images, let's replace the public key in RO. If prikey is
|
||||
* not provided, skip it. */
|
||||
if (fmap && sign_option.prikey) {
|
||||
uint8_t *new_pubkey;
|
||||
uint8_t *pubkey_buf = 0;
|
||||
|
||||
|
|
Binary file not shown.
|
@ -14,16 +14,20 @@ TESTKEYS=${SRCDIR}/tests/testkeys
|
|||
|
||||
SIGS="1024 2048 2048_exp3 3072_exp3 4096 8192"
|
||||
HASHES="SHA1 SHA256 SHA512"
|
||||
EC_RW="EC_RW.bin"
|
||||
|
||||
set -o pipefail
|
||||
|
||||
infile=${DATADIR}/hammer_dev.bin
|
||||
# Signing without private key should extract EC_RW.bin
|
||||
${FUTILITY} sign --type rwsig --version 2 ${infile}
|
||||
cmp ${EC_RW} ${DATADIR}/${EC_RW}
|
||||
|
||||
for s in $SIGS; do
|
||||
echo -n "$s " 1>&3
|
||||
|
||||
for h in $HASHES; do
|
||||
pemfile=${TESTKEYS}/key_rsa${s}.pem
|
||||
outfile=${TMP}.${s}_${h}.new
|
||||
infile=${DATADIR}/hammer_dev.bin
|
||||
outkeys=${TMP}.${s}_${h}
|
||||
outfile=${TMP}.${s}_${h}.bin
|
||||
|
||||
|
@ -41,8 +45,11 @@ for s in $SIGS; do
|
|||
|
||||
cp ${infile} ${outfile}
|
||||
|
||||
# Sign ec.bin with a new private key
|
||||
${FUTILITY} sign --type rwsig --prikey ${outkeys}.vbprik2 \
|
||||
--version 2 ${outfile}
|
||||
# Check EC_RW.bin is produced
|
||||
[[ -e ${EC_RW} ]]
|
||||
|
||||
${FUTILITY} show --type rwsig --pubkey ${outkeys}.vbpubk2 ${outfile}
|
||||
${FUTILITY} show --type rwsig ${outfile}
|
||||
|
|
Loading…
Reference in New Issue