host,test: Remove unneeded vb1 rsa functions

Another in a continued stream of refactoring.  This change removes more
of the vb1 rsa library code and associated tests, in favor of their vb2
equivalents.  This change touches only host-side code and its tests, not
firmware.

BUG=chromium:611535
BRANCH=none
TEST=make runtests; emerge-kevin coreboot depthcharge

Change-Id: I1973bc2f03c60da62232e30bab0fa5fe791b6b34
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/400901
This commit is contained in:
Randall Spangler
2016-10-14 15:37:25 -07:00
committed by chrome-bot
parent 13b109762a
commit 5a9f498182
18 changed files with 131 additions and 1082 deletions

View File

@@ -324,8 +324,6 @@ VBINIT_SRCS = \
# Additional firmware library sources needed by VbSelectFirmware() call # Additional firmware library sources needed by VbSelectFirmware() call
VBSF_SRCS = \ VBSF_SRCS = \
firmware/lib/cryptolib/padding.c \ firmware/lib/cryptolib/padding.c \
firmware/lib/cryptolib/rsa.c \
firmware/lib/cryptolib/rsa_utility.c \
firmware/lib/stateful_util.c \ firmware/lib/stateful_util.c \
firmware/lib/vboot_common.c \ firmware/lib/vboot_common.c \
firmware/lib/region-fw.c \ firmware/lib/region-fw.c \
@@ -724,9 +722,6 @@ TEST_OBJS += ${TESTLIB_OBJS}
TEST_NAMES = \ TEST_NAMES = \
tests/cgptlib_test \ tests/cgptlib_test \
tests/rollback_index3_tests \ tests/rollback_index3_tests \
tests/rsa_padding_test \
tests/rsa_utility_tests \
tests/rsa_verify_benchmark \
tests/sha_benchmark \ tests/sha_benchmark \
tests/stateful_util_tests \ tests/stateful_util_tests \
tests/utility_string_tests \ tests/utility_string_tests \
@@ -1187,6 +1182,7 @@ ${TEST2X_BINS}: LIBS += ${FWLIB2X}
${TEST20_BINS}: ${FWLIB20} ${TEST20_BINS}: ${FWLIB20}
${TEST20_BINS}: LIBS += ${FWLIB20} ${TEST20_BINS}: LIBS += ${FWLIB20}
${TEST20_BINS}: LDLIBS += ${CRYPTO_LIBS}
${TESTBDB_BINS}: ${FWLIB2X} ${UTILBDB} ${TESTBDB_BINS}: ${FWLIB2X} ${UTILBDB}
${TESTBDB_BINS}: INCLUDES += -Ifirmware/bdb ${TESTBDB_BINS}: INCLUDES += -Ifirmware/bdb
@@ -1251,6 +1247,7 @@ CRYPTO_LIBS := $(shell ${PKG_CONFIG} --libs libcrypto)
${BUILD}/utility/dumpRSAPublicKey: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/dumpRSAPublicKey: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/utility/pad_digest_utility: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/pad_digest_utility: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/utility/signature_digest_utility: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/signature_digest_utility: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/utility/verify_data: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/utility/bdb_extend: ${FWLIB2X} ${UTILBDB} ${BUILD}/utility/bdb_extend: ${FWLIB2X} ${UTILBDB}
${BUILD}/utility/bdb_extend.o: INCLUDES += -Ifirmware/bdb ${BUILD}/utility/bdb_extend.o: INCLUDES += -Ifirmware/bdb
@@ -1408,7 +1405,6 @@ runtestscripts: test_setup genfuzztestcases
tests/run_cgpt_tests.sh ${BUILD_RUN}/cgpt/cgpt tests/run_cgpt_tests.sh ${BUILD_RUN}/cgpt/cgpt
tests/run_cgpt_tests.sh ${BUILD_RUN}/cgpt/cgpt -D 358400 tests/run_cgpt_tests.sh ${BUILD_RUN}/cgpt/cgpt -D 358400
tests/run_preamble_tests.sh tests/run_preamble_tests.sh
tests/run_rsa_tests.sh
tests/run_vbutil_kernel_arg_tests.sh tests/run_vbutil_kernel_arg_tests.sh
tests/run_vbutil_tests.sh tests/run_vbutil_tests.sh
tests/vb2_rsa_tests.sh tests/vb2_rsa_tests.sh
@@ -1421,7 +1417,6 @@ ifeq (${TPM2_MODE},)
${RUNTEST} ${BUILD_RUN}/tests/rollback_index2_tests ${RUNTEST} ${BUILD_RUN}/tests/rollback_index2_tests
endif endif
${RUNTEST} ${BUILD_RUN}/tests/rollback_index3_tests ${RUNTEST} ${BUILD_RUN}/tests/rollback_index3_tests
${RUNTEST} ${BUILD_RUN}/tests/rsa_utility_tests
${RUNTEST} ${BUILD_RUN}/tests/stateful_util_tests ${RUNTEST} ${BUILD_RUN}/tests/stateful_util_tests
${RUNTEST} ${BUILD_RUN}/tests/utility_string_tests ${RUNTEST} ${BUILD_RUN}/tests/utility_string_tests
${RUNTEST} ${BUILD_RUN}/tests/utility_tests ${RUNTEST} ${BUILD_RUN}/tests/utility_tests

View File

@@ -22,74 +22,4 @@
#define RSA4096NUMWORDS (RSA4096NUMBYTES / sizeof(uint32_t)) #define RSA4096NUMWORDS (RSA4096NUMBYTES / sizeof(uint32_t))
#define RSA8192NUMWORDS (RSA8192NUMBYTES / sizeof(uint32_t)) #define RSA8192NUMWORDS (RSA8192NUMBYTES / sizeof(uint32_t))
typedef struct RSAPublicKey {
uint32_t len; /* Length of n[] in number of uint32_t */
uint32_t n0inv; /* -1 / n[0] mod 2^32 */
uint32_t* n; /* modulus as little endian array */
uint32_t* rr; /* R^2 as little endian array */
unsigned int algorithm; /* Algorithm to use when verifying with the key */
} RSAPublicKey;
/* Verify a RSA PKCS1.5 signature [sig] of [sig_type] and length [sig_len]
* against an expected [hash] using [key]. Returns 0 on failure, 1 on success.
*/
int RSAVerify(const RSAPublicKey *key,
const uint8_t* sig,
const uint32_t sig_len,
const uint8_t sig_type,
const uint8_t* hash);
/* Perform RSA signature verification on [buf] of length [len] against expected
* signature [sig] using signature algorithm [algorithm]. The public key used
* for verification can either be in the form of a pre-process key blob
* [key_blob] or RSAPublicKey structure [key]. One of [key_blob] or [key] must
* be non-NULL, and the other NULL or the function will fail.
*
* Returns 1 on verification success, 0 on verification failure or invalid
* arguments.
*
* Note: This function is for use in the firmware and assumes all pointers point
* to areas in the memory of the right size.
*
*/
int RSAVerifyBinary_f(const uint8_t* key_blob,
const RSAPublicKey* key,
const uint8_t* buf,
uint64_t len,
const uint8_t* sig,
unsigned int algorithm);
/* Version of RSAVerifyBinary_f() where instead of the raw binary blob
* of data, its digest is passed as the argument. */
int RSAVerifyBinaryWithDigest_f(const uint8_t* key_blob,
const RSAPublicKey* key,
const uint8_t* digest,
const uint8_t* sig,
unsigned int algorithm);
/* ----Some additional utility functions for RSA.---- */
/* Returns the size of a pre-processed RSA public key in
* [out_size] with the algorithm [algorithm].
*
* Returns 1 on success, 0 on failure.
*/
uint64_t RSAProcessedKeySize(uint64_t algorithm, uint64_t* out_size);
/* Allocate a new RSAPublicKey structure and initialize its pointer fields to
* NULL */
RSAPublicKey* RSAPublicKeyNew(void);
/* Deep free the contents of [key]. */
void RSAPublicKeyFree(RSAPublicKey* key);
/* Create a RSAPublic key structure from binary blob [buf] of length
* [len].
*
* Caller owns the returned key and must free it.
*/
RSAPublicKey* RSAPublicKeyFromBuf(const uint8_t* buf, uint64_t len);
#endif /* VBOOT_REFERENCE_RSA_H_ */ #endif /* VBOOT_REFERENCE_RSA_H_ */

View File

@@ -1,188 +0,0 @@
/* 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.
*/
/* Implementation of RSA signature verification which uses a pre-processed
* key for computation. The code extends Android's RSA verification code to
* support multiple RSA key lengths and hash digest algorithms.
*/
#include "sysincludes.h"
#include "2sysincludes.h"
#include "2common.h"
#include "cryptolib.h"
#include "vboot_api.h"
#include "utility.h"
/* a[] -= mod */
static void subM(const RSAPublicKey *key, uint32_t *a) {
int64_t A = 0;
uint32_t i;
for (i = 0; i < key->len; ++i) {
A += (uint64_t)a[i] - key->n[i];
a[i] = (uint32_t)A;
A >>= 32;
}
}
/* return a[] >= mod */
static int geM(const RSAPublicKey *key, uint32_t *a) {
uint32_t i;
for (i = key->len; i;) {
--i;
if (a[i] < key->n[i]) return 0;
if (a[i] > key->n[i]) return 1;
}
return 1; /* equal */
}
/* montgomery c[] += a * b[] / R % mod */
static void montMulAdd(const RSAPublicKey *key,
uint32_t* c,
const uint32_t a,
const uint32_t* b) {
uint64_t A = (uint64_t)a * b[0] + c[0];
uint32_t d0 = (uint32_t)A * key->n0inv;
uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A;
uint32_t i;
for (i = 1; i < key->len; ++i) {
A = (A >> 32) + (uint64_t)a * b[i] + c[i];
B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A;
c[i - 1] = (uint32_t)B;
}
A = (A >> 32) + (B >> 32);
c[i - 1] = (uint32_t)A;
if (A >> 32) {
subM(key, c);
}
}
/* montgomery c[] = a[] * b[] / R % mod */
static void montMul(const RSAPublicKey *key,
uint32_t* c,
uint32_t* a,
uint32_t* b) {
uint32_t i;
for (i = 0; i < key->len; ++i) {
c[i] = 0;
}
for (i = 0; i < key->len; ++i) {
montMulAdd(key, c, a[i], b);
}
}
/* In-place public exponentiation. (65537}
* Input and output big-endian byte array in inout.
*/
static void modpowF4(const RSAPublicKey *key,
uint8_t* inout) {
uint32_t* a = (uint32_t*) VbExMalloc(key->len * sizeof(uint32_t));
uint32_t* aR = (uint32_t*) VbExMalloc(key->len * sizeof(uint32_t));
uint32_t* aaR = (uint32_t*) VbExMalloc(key->len * sizeof(uint32_t));
uint32_t* aaa = aaR; /* Re-use location. */
int i;
/* Convert from big endian byte array to little endian word array. */
for (i = 0; i < (int)key->len; ++i) {
uint32_t tmp =
(inout[((key->len - 1 - i) * 4) + 0] << 24) |
(inout[((key->len - 1 - i) * 4) + 1] << 16) |
(inout[((key->len - 1 - i) * 4) + 2] << 8) |
(inout[((key->len - 1 - i) * 4) + 3] << 0);
a[i] = tmp;
}
montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */
for (i = 0; i < 16; i+=2) {
montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */
montMul(key, aR, aaR, aaR); /* aR = aaR * aaR / R mod M */
}
montMul(key, aaa, aR, a); /* aaa = aR * a / R mod M */
/* Make sure aaa < mod; aaa is at most 1x mod too large. */
if (geM(key, aaa)) {
subM(key, aaa);
}
/* Convert to bigendian byte array */
for (i = (int)key->len - 1; i >= 0; --i) {
uint32_t tmp = aaa[i];
*inout++ = (uint8_t)(tmp >> 24);
*inout++ = (uint8_t)(tmp >> 16);
*inout++ = (uint8_t)(tmp >> 8);
*inout++ = (uint8_t)(tmp >> 0);
}
VbExFree(a);
VbExFree(aR);
VbExFree(aaR);
}
/* Verify a RSA PKCS1.5 signature against an expected hash.
* Returns 0 on failure, 1 on success.
*/
int RSAVerify(const RSAPublicKey *key,
const uint8_t *sig,
const uint32_t sig_len,
const uint8_t sig_type,
const uint8_t *hash) {
uint8_t* buf;
const uint8_t* padding;
int padding_len;
int success = 1;
if (!key || !sig || !hash)
return 0;
if (sig_len != (key->len * sizeof(uint32_t))) {
VBDEBUG(("Signature is of incorrect length!\n"));
return 0;
}
if (sig_type >= kNumAlgorithms) {
VBDEBUG(("Invalid signature type!\n"));
return 0;
}
if (key->len != siglen_map[sig_type] / sizeof(uint32_t)) {
VBDEBUG(("Wrong key passed in!\n"));
return 0;
}
buf = (uint8_t*) VbExMalloc(sig_len);
if (!buf)
return 0;
memcpy(buf, sig, sig_len);
modpowF4(key, buf);
/* Determine padding to use depending on the signature type. */
padding = padding_map[sig_type];
padding_len = padding_size_map[sig_type];
/* Even though there are probably no timing issues here, we use
* vb2_safe_memcmp() just to be on the safe side. */
/* Check pkcs1.5 padding bytes. */
if (vb2_safe_memcmp(buf, padding, padding_len)) {
VBDEBUG(("In RSAVerify(): Padding check failed!\n"));
success = 0;
}
/* Check hash. */
if (vb2_safe_memcmp(buf + padding_len, hash, sig_len - padding_len)) {
VBDEBUG(("In RSAVerify(): Hash check failed!\n"));
success = 0;
}
VbExFree(buf);
return success;
}

View File

@@ -1,162 +0,0 @@
/* Copyright (c) 2012 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.
*
* Implementation of RSA utility functions.
*/
#include "sysincludes.h"
#include "2sysincludes.h"
#include "2common.h"
#include "2sha.h"
#include "cryptolib.h"
#include "stateful_util.h"
#include "utility.h"
#include "vboot_api.h"
uint64_t RSAProcessedKeySize(uint64_t algorithm, uint64_t* out_size) {
int key_len; /* Key length in bytes. (int type matches siglen_map) */
if (algorithm < kNumAlgorithms) {
key_len = siglen_map[algorithm];
/* Total size needed by a RSAPublicKey buffer is =
* 2 * key_len bytes for the n and rr arrays
* + sizeof len + sizeof n0inv.
*/
*out_size = (2 * key_len + sizeof(uint32_t) + sizeof(uint32_t));
return 1;
}
return 0;
}
RSAPublicKey* RSAPublicKeyNew(void) {
RSAPublicKey* key = (RSAPublicKey*) VbExMalloc(sizeof(RSAPublicKey));
key->n = NULL;
key->rr = NULL;
key->len = 0;
key->algorithm = kNumAlgorithms;
return key;
}
void RSAPublicKeyFree(RSAPublicKey* key) {
if (key) {
if (key->n)
VbExFree(key->n);
if (key->rr)
VbExFree(key->rr);
VbExFree(key);
}
}
RSAPublicKey* RSAPublicKeyFromBuf(const uint8_t* buf, uint64_t len) {
RSAPublicKey* key = RSAPublicKeyNew();
MemcpyState st;
uint64_t key_len;
StatefulInit(&st, (void*)buf, len);
StatefulMemcpy(&st, &key->len, sizeof(key->len));
/* key length in bytes (avoiding possible 32-bit rollover) */
key_len = key->len;
key_len *= sizeof(uint32_t);
/* Sanity Check the key length. */
if (RSA1024NUMBYTES != key_len &&
RSA2048NUMBYTES != key_len &&
RSA4096NUMBYTES != key_len &&
RSA8192NUMBYTES != key_len) {
RSAPublicKeyFree(key);
return NULL;
}
key->n = (uint32_t*) VbExMalloc(key_len);
key->rr = (uint32_t*) VbExMalloc(key_len);
StatefulMemcpy(&st, &key->n0inv, sizeof(key->n0inv));
StatefulMemcpy(&st, key->n, key_len);
StatefulMemcpy(&st, key->rr, key_len);
if (st.overrun || st.remaining_len != 0) { /* Underrun or overrun. */
RSAPublicKeyFree(key);
return NULL;
}
return key;
}
int RSAVerifyBinary_f(const uint8_t* key_blob,
const RSAPublicKey* key,
const uint8_t* buf,
uint64_t len,
const uint8_t* sig,
unsigned int algorithm) {
RSAPublicKey* verification_key = NULL;
uint8_t digest[VB2_MAX_DIGEST_SIZE];
uint64_t key_size;
int sig_size;
int success = 0;
if (algorithm >= (unsigned int)kNumAlgorithms)
return 0; /* Invalid algorithm. */
if (!RSAProcessedKeySize(algorithm, &key_size))
return 0;
sig_size = siglen_map[algorithm];
if (key_blob && !key)
verification_key = RSAPublicKeyFromBuf(key_blob, key_size);
else if (!key_blob && key)
verification_key = (RSAPublicKey*) key; /* Supress const warning. */
else
return 0; /* Both can't be NULL or non-NULL. */
/* Ensure we have a valid key. */
if (!verification_key)
return 0;
if (VB2_SUCCESS == vb2_digest_buffer(buf, len, vb2_crypto_to_hash(algorithm),
digest, sizeof(digest))) {
success = RSAVerify(verification_key, sig, (uint32_t)sig_size,
(uint8_t)algorithm, digest);
}
if (!key)
RSAPublicKeyFree(verification_key); /* Only free if we allocated it. */
return success;
}
/* Version of RSAVerifyBinary_f() where instead of the raw binary blob
* of data, its digest is passed as the argument. */
int RSAVerifyBinaryWithDigest_f(const uint8_t* key_blob,
const RSAPublicKey* key,
const uint8_t* digest,
const uint8_t* sig,
unsigned int algorithm) {
RSAPublicKey* verification_key = NULL;
uint64_t key_size;
int sig_size;
int success;
if (algorithm >= (unsigned int)kNumAlgorithms)
return 0; /* Invalid algorithm. */
if (!RSAProcessedKeySize(algorithm, &key_size))
return 0;
sig_size = siglen_map[algorithm];
if (key_blob && !key)
verification_key = RSAPublicKeyFromBuf(key_blob, key_size);
else if (!key_blob && key)
verification_key = (RSAPublicKey*) key; /* Supress const warning. */
else
return 0; /* Both can't be NULL or non-NULL. */
/* Ensure we have a valid key. */
if (!verification_key)
return 0;
success = RSAVerify(verification_key, sig, (uint32_t)sig_size,
(uint8_t)algorithm, digest);
if (!key)
RSAPublicKeyFree(verification_key); /* Only free if we allocated it. */
return success;
}

View File

@@ -22,55 +22,6 @@
#include "host_common.h" #include "host_common.h"
#include "signature_digest.h" #include "signature_digest.h"
uint8_t *BufferFromFile(const char* input_file, uint64_t* len)
{
int fd;
struct stat stat_fd;
uint8_t* buf = NULL;
if ((fd = open(input_file, O_RDONLY)) == -1) {
VBDEBUG(("Couldn't open file %s\n", input_file));
return NULL;
}
if (-1 == fstat(fd, &stat_fd)) {
VBDEBUG(("Couldn't stat file %s\n", input_file));
close(fd);
return NULL;
}
*len = stat_fd.st_size;
buf = (uint8_t *)malloc(*len);
if (!buf) {
VbExError("Couldn't allocate %ld bytes for file %s\n",
*len, input_file);
close(fd);
return NULL;
}
if (*len != read(fd, buf, *len)) {
VBDEBUG(("Couldn't read file %s into a buffer\n", input_file));
free(buf);
close(fd);
return NULL;
}
close(fd);
return buf;
}
RSAPublicKey *RSAPublicKeyFromFile(const char *input_file)
{
uint64_t len;
RSAPublicKey* key = NULL;
uint8_t *buf = BufferFromFile(input_file, &len);
if (buf)
key = RSAPublicKeyFromBuf(buf, len);
free(buf);
return key;
}
int DigestFile(char *input_file, enum vb2_hash_algorithm alg, int DigestFile(char *input_file, enum vb2_hash_algorithm alg,
uint8_t *digest, uint32_t digest_size) uint8_t *digest, uint32_t digest_size)
{ {

View File

@@ -39,21 +39,3 @@ int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size)
/* Success */ /* Success */
return 1; return 1;
} }
/* TODO: the host code just uses this to check the embedded key length in
* uint32_t's. It should get folded into packed_key_looks_ok. */
RSAPublicKey *vb2_packed_key_to_rsa(const struct vb2_packed_key *key)
{
RSAPublicKey *rsa;
if (!packed_key_looks_ok(key, key->key_size))
return NULL;
rsa = RSAPublicKeyFromBuf(vb2_packed_key_data(key), key->key_size);
if (!rsa)
return NULL;
rsa->algorithm = (unsigned int)key->algorithm;
return rsa;
}

View File

@@ -238,9 +238,9 @@ struct vb2_packed_key *vb2_read_packed_keyb(const char *filename,
if (VB2_SUCCESS != vb2_read_file(filename, &key_data, &key_size)) if (VB2_SUCCESS != vb2_read_file(filename, &key_data, &key_size))
return NULL; return NULL;
uint64_t expected_key_size; uint32_t expected_key_size =
if (!RSAProcessedKeySize(algorithm, &expected_key_size) || vb2_packed_key_size(vb2_crypto_to_signature(algorithm));
expected_key_size != key_size) { if (!expected_key_size || expected_key_size != key_size) {
fprintf(stderr, "%s() - wrong key size %u for algorithm %u\n", fprintf(stderr, "%s() - wrong key size %u for algorithm %u\n",
__func__, key_size, algorithm); __func__, key_size, algorithm);
free(key_data); free(key_data);

View File

@@ -11,21 +11,6 @@
#include "cryptolib.h" #include "cryptolib.h"
#include "2sha.h" #include "2sha.h"
/* Read file named [input_file] into a buffer and stores the length into
* [len].
*
* Returns a pointer to the buffer. Caller owns the returned pointer and
* must free it.
*/
uint8_t* BufferFromFile(const char* input_file, uint64_t* len);
/* Read a pre-processed RSA Public Key from file [input_file].
*
* Returns a pointer to the read key. Caller owns the returned pointer and
* must free it.
*/
RSAPublicKey* RSAPublicKeyFromFile(const char* input_file);
/* Calculates the appropriate digest for the data in [input_file] based on the /* Calculates the appropriate digest for the data in [input_file] based on the
* hash algorithm [alg] and stores it into [digest], which is of size * hash algorithm [alg] and stores it into [digest], which is of size
* [digest_size]. Returns VB2_SUCCESS, or non-zero on error. * [digest_size]. Returns VB2_SUCCESS, or non-zero on error.

View File

@@ -20,8 +20,6 @@ int main(void)
WriteFile(0, 0, 0); WriteFile(0, 0, 0);
/* file_keys.h */ /* file_keys.h */
BufferFromFile(0, 0);
RSAPublicKeyFromFile(0);
DigestFile(0, 0, 0, 0); DigestFile(0, 0, 0, 0);
/* signature_digest.h */ /* signature_digest.h */

View File

@@ -1,91 +0,0 @@
/* 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.
*/
#include <stdint.h>
#include <stdio.h>
#include "cryptolib.h"
#include "file_keys.h"
#include "rsa_padding_test.h"
#include "test_common.h"
#include "utility.h"
/* Test valid and invalid signatures */
static void TestSignatures(RSAPublicKey* key) {
int unexpected_success;
int i;
/* The first test signature is valid. */
TEST_EQ(RSAVerify(key, signatures[0], RSA1024NUMBYTES, 0,
test_message_sha1_hash), 1, "RSA Padding Test valid sig");
/* All other signatures should fail verification. */
unexpected_success = 0;
for (i = 1; i < sizeof(signatures) / sizeof(signatures[0]); i++) {
if (RSAVerify(key, signatures[i], RSA1024NUMBYTES, 0,
test_message_sha1_hash)) {
fprintf(stderr, "RSA Padding Test vector %d FAILED!\n", i);
unexpected_success++;
}
}
TEST_EQ(unexpected_success, 0, "RSA Padding Test invalid sigs");
}
/* Test other error conditions in RSAVerify() */
static void TestRSAVerify(RSAPublicKey* key) {
uint8_t sig[RSA1024NUMBYTES];
TEST_EQ(RSAVerify(key, signatures[0], RSA1024NUMBYTES, 0,
test_message_sha1_hash), 1, "RSAVerify() good");
TEST_EQ(RSAVerify(key, signatures[0], RSA1024NUMBYTES - 1, 0,
test_message_sha1_hash), 0, "RSAVerify() sig len");
TEST_EQ(RSAVerify(key, signatures[0], RSA1024NUMBYTES, kNumAlgorithms,
test_message_sha1_hash), 0, "RSAVerify() invalid alg");
TEST_EQ(RSAVerify(key, signatures[0], RSA1024NUMBYTES, 3,
test_message_sha1_hash), 0, "RSAVerify() wrong alg");
/* Corrupt the signature near start and end */
memcpy(sig, signatures[0], RSA1024NUMBYTES);
sig[3] ^= 0x42;
TEST_EQ(RSAVerify(key, sig, RSA1024NUMBYTES, 0, test_message_sha1_hash), 0,
"RSAVerify() bad sig");
memcpy(sig, signatures[0], RSA1024NUMBYTES);
sig[RSA1024NUMBYTES - 3] ^= 0x56;
TEST_EQ(RSAVerify(key, sig, RSA1024NUMBYTES, 0, test_message_sha1_hash), 0,
"RSAVerify() bad sig end");
}
int main(int argc, char* argv[]) {
int error = 0;
RSAPublicKey* key;
/* Read test key */
if (argc != 2) {
fprintf(stderr, "Usage: %s <test public key>\n", argv[0]);
return 1;
}
key = RSAPublicKeyFromFile(argv[1]);
if (!key) {
fprintf(stderr, "Couldn't read RSA public key for the test.\n");
return 1;
}
/* Run tests */
TestSignatures(key);
TestRSAVerify(key);
/* Clean up and exit */
RSAPublicKeyFree(key);
if (!gTestSuccess)
error = 255;
return error;
}

View File

@@ -1,213 +0,0 @@
/* 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.
*/
#include <stdint.h>
#include <stdio.h>
#define _STUB_IMPLEMENTATION_
#include "cryptolib.h"
#include "file_keys.h"
#include "rsa_padding_test.h"
#include "test_common.h"
#include "utility.h"
#include "vboot_api.h"
/* Data for mock functions */
static int mock_rsaverify_retval;
int RSAVerify(const RSAPublicKey *key,
const uint8_t* sig,
const uint32_t sig_len,
const uint8_t sig_type,
const uint8_t* hash) {
return mock_rsaverify_retval;
}
static void ResetMocks(void) {
mock_rsaverify_retval = 1;
}
/* Test RSA utility funcs */
static void TestUtils(void) {
RSAPublicKey* key;
uint64_t u;
/* Processed key size */
TEST_EQ(RSAProcessedKeySize(0, &u), 1, "Processed key size 0");
TEST_EQ(u, RSA1024NUMBYTES * 2 + sizeof(uint32_t) * 2,
"Processed key size 0 size");
TEST_EQ(RSAProcessedKeySize(3, &u), 1, "Processed key size 3");
TEST_EQ(u, RSA2048NUMBYTES * 2 + sizeof(uint32_t) * 2,
"Processed key size 3 size");
TEST_EQ(RSAProcessedKeySize(7, &u), 1, "Processed key size 7");
TEST_EQ(u, RSA4096NUMBYTES * 2 + sizeof(uint32_t) * 2,
"Processed key size 7 size");
TEST_EQ(RSAProcessedKeySize(11, &u), 1, "Processed key size 11");
TEST_EQ(u, RSA8192NUMBYTES * 2 + sizeof(uint32_t) * 2,
"Processed key size 11 size");
TEST_EQ(RSAProcessedKeySize(kNumAlgorithms, &u), 0,
"Processed key size invalid algorithm");
/* Alloc key */
key = RSAPublicKeyNew();
TEST_EQ(key == NULL, 0, "New key not null");
/* New key fields */
TEST_PTR_EQ(key->n, NULL, "New key no n");
TEST_PTR_EQ(key->rr, NULL, "New key no rr");
TEST_EQ(key->len, 0, "New key len");
TEST_EQ(key->algorithm, kNumAlgorithms, "New key no algorithm");
/* Free key */
RSAPublicKeyFree(key);
/* Freeing null key shouldn't implode */
RSAPublicKeyFree(NULL);
}
/* Test creating key from buffer */
static void TestKeyFromBuffer(void) {
RSAPublicKey* key;
uint8_t* buf;
uint32_t* buf_key_len;
int i;
buf = malloc(8 + 2 * RSA8192NUMBYTES);
buf_key_len = (uint32_t*)buf;
for (i = 0; i < 4; i++) {
uint32_t key_len = RSA1024NUMBYTES << i;
memset(buf, 0xAB, 8 + 2 * RSA8192NUMBYTES);
*buf_key_len = key_len / sizeof(uint32_t);
*(buf_key_len + 1) = 0xF00D2345; /* n0inv */
buf[8] = 100;
buf[8 + key_len - 1] = 101;
buf[8 + key_len] = 120;
buf[8 + key_len * 2 - 1] = 121;
/* Correct length */
key = RSAPublicKeyFromBuf(buf, 8 + key_len * 2);
TEST_PTR_NEQ(key, NULL, "RSAPublicKeyFromBuf() ptr");
TEST_EQ(key->len, *buf_key_len, "RSAPublicKeyFromBuf() len");
TEST_EQ(key->n0inv, 0xF00D2345, "RSAPublicKeyFromBuf() n0inv");
TEST_PTR_NEQ(key->n, NULL, "RSAPublicKeyFromBuf() n ptr");
TEST_EQ(((uint8_t*)key->n)[0], 100, "RSAPublicKeyFromBuf() n start");
TEST_EQ(((uint8_t*)key->n)[key_len - 1], 101,
"RSAPublicKeyFromBuf() n end");
TEST_PTR_NEQ(key->rr, NULL, "RSAPublicKeyFromBuf() rr ptr");
TEST_EQ(((uint8_t*)key->rr)[0], 120, "RSAPublicKeyFromBuf() rr start");
TEST_EQ(((uint8_t*)key->rr)[key_len - 1], 121,
"RSAPublicKeyFromBuf() rr end");
RSAPublicKeyFree(key);
/* Underflow and overflow */
TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 - 1), NULL,
"RSAPublicKeyFromBuf() underflow");
TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL,
"RSAPublicKeyFromBuf() overflow");
/* Invalid key length in buffer */
*buf_key_len = key_len / sizeof(uint32_t) + 1;
TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL,
"RSAPublicKeyFromBuf() invalid key length");
/* Valid key length in buffer, but for some other length key */
*buf_key_len = (RSA1024NUMBYTES << ((i + 1) & 3)) / sizeof(uint32_t);
TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL,
"RSAPublicKeyFromBuf() key length for wrong key");
}
free(buf);
}
/* Test verifying binary */
static void TestVerifyBinary(void) {
RSAPublicKey key;
uint8_t keybuf[8 + 2 * RSA1024NUMBYTES];
uint32_t* keybuf_len = (uint32_t*)keybuf;
uint8_t buf[120];
uint8_t sig[4];
*keybuf_len = RSA1024NUMBYTES / sizeof(uint32_t);
/* Successful verification */
ResetMocks();
TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, 0),
1, "RSAVerifyBinary_f() success");
/* Successful verification using key blob */
TEST_EQ(RSAVerifyBinary_f(keybuf, NULL, buf, sizeof(buf), sig, 0),
1, "RSAVerifyBinary_f() success with keyblob");
/* Invalid algorithm */
ResetMocks();
TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, kNumAlgorithms),
0, "RSAVerifyBinary_f() invalid algorithm");
/* Must have either a key or a key blob */
ResetMocks();
TEST_EQ(RSAVerifyBinary_f(NULL, NULL, buf, sizeof(buf), sig, kNumAlgorithms),
0, "RSAVerifyBinary_f() no key or key_blob");
/* Wrong algorithm for key buffer (so key buffer is wrong size) */
ResetMocks();
TEST_EQ(RSAVerifyBinary_f(keybuf, NULL, buf, sizeof(buf), sig, 3),
0, "RSAVerifyBinary_f() wrong alg for key blob");
/* Simulate failed verification */
ResetMocks();
mock_rsaverify_retval = 0;
TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, 0),
0, "RSAVerifyBinary_f() bad verify");
}
/* Test verifying binary with digest */
static void TestVerifyBinaryWithDigest(void) {
RSAPublicKey key;
uint8_t keybuf[8 + 2 * RSA1024NUMBYTES];
uint32_t* keybuf_len = (uint32_t*)keybuf;
uint8_t digest[120];
uint8_t sig[4];
*keybuf_len = RSA1024NUMBYTES / sizeof(uint32_t);
/* Successful verification */
ResetMocks();
TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, 0),
1, "RSAVerifyBinaryWithDigest_f() success");
/* Successful verification using key blob */
TEST_EQ(RSAVerifyBinaryWithDigest_f(keybuf, NULL, digest, sig, 0),
1, "RSAVerifyBinaryWithDigest_f() success with keyblob");
/* Invalid algorithm */
ResetMocks();
TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, kNumAlgorithms),
0, "RSAVerifyBinaryWithDigest_f() invalid algorithm");
/* Must have either a key or a key blob */
ResetMocks();
TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, NULL, digest, sig, kNumAlgorithms),
0, "RSAVerifyBinaryWithDigest_f() no key or key_blob");
/* Wrong algorithm for key buffer (so key buffer is wrong size) */
ResetMocks();
TEST_EQ(RSAVerifyBinaryWithDigest_f(keybuf, NULL, digest, sig, 3),
0, "RSAVerifyBinaryWithDigest_f() wrong alg for key blob");
/* Simulate failed verification */
ResetMocks();
mock_rsaverify_retval = 0;
TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, 0),
0, "RSAVerifyBinaryWithDigest_f() bad verify");
}
int main(int argc, char* argv[]) {
int error_code = 0;
/* Run tests */
TestUtils();
TestKeyFromBuffer();
TestVerifyBinary();
TestVerifyBinaryWithDigest();
if (!gTestSuccess)
error_code = 255;
return error_code;
}

View File

@@ -1,95 +0,0 @@
/* 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.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "cryptolib.h"
#include "file_keys.h"
#include "host_common.h"
#include "timer_utils.h"
#define FILE_NAME_SIZE 128
#define NUM_OPERATIONS 100 /* Number of signature operations to time. */
int SpeedTestAlgorithm(int algorithm) {
int i, key_size;
int error_code = 0;
double speed, msecs;
char file_name[FILE_NAME_SIZE];
uint8_t* digest = NULL;
uint8_t* signature = NULL;
uint64_t digest_len, sig_len;
RSAPublicKey* key = NULL;
ClockTimerState ct;
char* sha_strings[] = { /* Maps algorithm->SHA algorithm. */
"sha1", "sha256", "sha512", /* RSA-1024 */
"sha1", "sha256", "sha512", /* RSA-2048 */
"sha1", "sha256", "sha512", /* RSA-4096 */
"sha1", "sha256", "sha512", /* RSA-8192 */
};
key_size = siglen_map[algorithm] * 8; /* in bits. */
/* Get key. */
snprintf(file_name, FILE_NAME_SIZE, "testkeys/key_rsa%d.keyb", key_size);
key = RSAPublicKeyFromFile(file_name);
if (!key) {
VBDEBUG(("Couldn't read RSA Public key from file: %s\n", file_name));
error_code = 1;
goto failure;
}
/* Get expected digest. */
snprintf(file_name, FILE_NAME_SIZE, "testcases/test_file.%s.digest",
sha_strings[algorithm]);
digest = BufferFromFile(file_name, &digest_len);
if (!digest) {
VBDEBUG(("Couldn't read digest file.\n"));
error_code = 1;
goto failure;
}
/* Get signature to verify against. */
snprintf(file_name, FILE_NAME_SIZE, "testcases/test_file.rsa%d_%s.sig",
key_size, sha_strings[algorithm]);
signature = BufferFromFile(file_name, &sig_len);
if (!signature) {
VBDEBUG(("Couldn't read signature file.\n"));
error_code = 1;
goto failure;
}
StartTimer(&ct);
for (i = 0; i < NUM_OPERATIONS; i++) {
if (!RSAVerify(key, signature, sig_len, algorithm, digest))
VBDEBUG(("Warning: Signature Check Failed.\n"));
}
StopTimer(&ct);
msecs = (float) GetDurationMsecs(&ct) / NUM_OPERATIONS;
speed = 1000.0 / msecs ;
fprintf(stderr, "# rsa%d/%s:\tTime taken per verification = %.02f ms,"
" Speed = %.02f verifications/s\n", key_size, sha_strings[algorithm],
msecs, speed);
fprintf(stdout, "ms_rsa%d_%s:%.02f\n", key_size, sha_strings[algorithm],
msecs);
failure:
free(signature);
free(digest);
RSAPublicKeyFree(key);
return error_code;
}
int main(int argc, char* argv[]) {
int i;
int error_code = 0;
for (i = 0; i < kNumAlgorithms; ++i) {
if(SpeedTestAlgorithm(i))
error_code = 1;
}
return error_code;
}

View File

@@ -1,44 +0,0 @@
#!/bin/bash
# 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.
#
# Run tests for RSA Signature verification.
# Load common constants and variables.
. "$(dirname "$0")/common.sh"
set -e
return_code=0
TEST_FILE=${TESTCASE_DIR}/test_file
function test_signatures {
algorithmcounter=0
for keylen in ${key_lengths[@]}
do
for hashalgo in ${hash_algos[@]}
do
echo -e "For ${COL_YELLOW}RSA-$keylen and $hashalgo${COL_STOP}:"
${BIN_DIR}/verify_data $algorithmcounter \
${TESTKEY_DIR}/key_rsa${keylen}.keyb \
${TEST_FILE}.rsa${keylen}_${hashalgo}.sig \
${TEST_FILE}
if [ $? -ne 0 ]
then
return_code=255
fi
let algorithmcounter=algorithmcounter+1
done
done
echo -e "Peforming ${COL_YELLOW}PKCS #1 v1.5 Padding Tests${COL_STOP}..."
${TEST_DIR}/rsa_padding_test ${TESTKEY_DIR}/rsa_padding_test_pubkey.keyb
}
check_test_keys
echo "Testing signature verification..."
test_signatures
exit $return_code

View File

@@ -7,6 +7,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#define _STUB_IMPLEMENTATION_
#include "cryptolib.h" #include "cryptolib.h"
#include "file_keys.h" #include "file_keys.h"
#include "rsa_padding_test.h" #include "rsa_padding_test.h"
@@ -15,28 +17,9 @@
#include "2sysincludes.h" #include "2sysincludes.h"
#include "2rsa.h" #include "2rsa.h"
#include "host_key.h"
#include "vb2_common.h" #include "vb2_common.h"
/**
* Convert an old-style RSA public key struct to a new one.
*
* The new one does not allocate memory, so you must keep the old one around
* until you're done with the new one.
*
* @param k2 Destination new key
* @param key Source old key
*/
void vb2_public_key_to_vb2(struct vb2_public_key *k2,
const struct RSAPublicKey *key)
{
k2->arrsize = key->len;
k2->n0inv = key->n0inv;
k2->n = key->n;
k2->rr = key->rr;
k2->sig_alg = vb2_crypto_to_signature(key->algorithm);
k2->hash_alg = vb2_crypto_to_hash(key->algorithm);
}
/** /**
* Test valid and invalid signatures. * Test valid and invalid signatures.
*/ */
@@ -122,37 +105,32 @@ static void test_verify_digest(struct vb2_public_key *key) {
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int error = 0;
RSAPublicKey *key;
struct vb2_public_key k2; struct vb2_public_key k2;
struct vb2_packed_key *pk;
/* Read test key */ /* Read test key */
if (argc != 2) { if (argc != 2) {
fprintf(stderr, "Usage: %s <test public key>\n", argv[0]); fprintf(stderr, "Usage: %s <test public key>\n", argv[0]);
return 1; return 1;
} }
key = RSAPublicKeyFromFile(argv[1]); pk = vb2_read_packed_keyb(argv[1], VB2_ALG_RSA1024_SHA1, 0);
if (!pk) {
if (!key) {
fprintf(stderr, "Couldn't read RSA public key for the test.\n"); fprintf(stderr, "Couldn't read RSA public key for the test.\n");
return 1; return 1;
} }
// TODO: why is test key algorithm wrong? if (VB2_SUCCESS != vb2_unpack_key(&k2, (const uint8_t *)pk,
key->algorithm = 0; pk->key_offset + pk->key_size)) {
fprintf(stderr, "Couldn't unpack RSA public key.\n");
/* Convert test key to Vb2 format */ free(pk);
vb2_public_key_to_vb2(&k2, key); return 1;
}
/* Run tests */ /* Run tests */
test_signatures(&k2); test_signatures(&k2);
test_verify_digest(&k2); test_verify_digest(&k2);
/* Clean up and exit */ /* Clean up and exit */
RSAPublicKeyFree(key); free(pk);
return gTestSuccess ? 0 : 255;
if (!gTestSuccess)
error = 255;
return error;
} }

View File

@@ -1,20 +0,0 @@
/* 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.
*/
#ifndef VBOOT_REFERENCE_VERIFY_DATA_H_
#define VBOOT_REFERENCE_VERIFY_DATA_H_
/* Reads a pre-processed key from [input_file] and
* returns it in a RSAPublicKey structure.
* Caller owns the returned key and must free it.
*/
RSAPublicKey* read_RSAkey(char *input_file);
/* Return a signature of [len] bytes read from [input_file].
* Caller owns the returned signature and must free it.
*/
uint8_t* read_signature(char *input_file, int len);
#endif /* VBOOT_REFERENCE_VERIFY_DATA_H_ */

View File

@@ -31,7 +31,7 @@ int main(int argc, char* argv[]) {
int error_code = 0; int error_code = 0;
uint8_t* digest = NULL; uint8_t* digest = NULL;
uint8_t* padded_digest = NULL; uint8_t* padded_digest = NULL;
uint64_t len; uint32_t len;
uint32_t padded_digest_len; uint32_t padded_digest_len;
if (argc != 3) { if (argc != 3) {
@@ -44,8 +44,7 @@ int main(int argc, char* argv[]) {
return -1; return -1;
} }
digest = BufferFromFile(argv[2], &len); if (VB2_SUCCESS != vb2_read_file(argv[2], &digest, &len)) {
if (!digest) {
fprintf(stderr, "Could not read file: %s\n", argv[2]); fprintf(stderr, "Could not read file: %s\n", argv[2]);
return -1; return -1;
} }

View File

@@ -11,6 +11,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "2sysincludes.h"
#include "2common.h"
#include "file_keys.h" #include "file_keys.h"
#include "host_common.h" #include "host_common.h"
#include "padding.h" #include "padding.h"
@@ -22,7 +25,7 @@ int main(int argc, char* argv[]) {
int error_code = 0; int error_code = 0;
uint8_t* buf = NULL; uint8_t* buf = NULL;
uint8_t* signature_digest = NULL; uint8_t* signature_digest = NULL;
uint64_t len; uint32_t len;
uint32_t signature_digest_len; uint32_t signature_digest_len;
if (argc != 3) { if (argc != 3) {
@@ -35,8 +38,7 @@ int main(int argc, char* argv[]) {
return -1; return -1;
} }
buf = BufferFromFile(argv[2], &len); if (VB2_SUCCESS != vb2_read_file(argv[2], &buf, &len)) {
if (!buf) {
fprintf(stderr, "Could not read file: %s\n", argv[2]); fprintf(stderr, "Could not read file: %s\n", argv[2]);
return -1; return -1;
} }

View File

@@ -15,88 +15,130 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#define _STUB_IMPLEMENTATION_ /* For malloc()/free() */
#include "2sysincludes.h" #include "2sysincludes.h"
#include "2common.h" #include "2common.h"
#include "2sha.h" #include "2sha.h"
#include "2rsa.h"
#include "cryptolib.h" #include "cryptolib.h"
#include "file_keys.h" #include "file_keys.h"
#include "verify_data.h" #include "host_key.h"
#include "host_misc.h"
#include "vb2_common.h"
/* ANSI Color coding sequences. */ /* ANSI Color coding sequences. */
#define COL_GREEN "\e[1;32m" #define COL_GREEN "\e[1;32m"
#define COL_RED "\e[0;31m" #define COL_RED "\e[0;31m"
#define COL_STOP "\e[m" #define COL_STOP "\e[m"
uint8_t* read_signature(char* input_file, int len) { uint8_t* read_signature(char* input_file, int len)
int i, sigfd; {
uint8_t* signature = NULL; int i, sigfd;
if ((sigfd = open(input_file, O_RDONLY)) == -1) { uint8_t* signature = NULL;
fprintf(stderr, "Couldn't open signature file\n"); if ((sigfd = open(input_file, O_RDONLY)) == -1) {
return NULL; fprintf(stderr, "Couldn't open signature file\n");
} return NULL;
}
/* Read the signature into a buffer*/ /* Read the signature into a buffer*/
signature = (uint8_t*) malloc(len); signature = (uint8_t*) malloc(len);
if (!signature) { if (!signature) {
close(sigfd); close(sigfd);
return NULL; return NULL;
} }
if( (i = read(sigfd, signature, len)) != len ) { if( (i = read(sigfd, signature, len)) != len ) {
fprintf(stderr, "Wrong signature length - Expected = %d, Received = %d\n", fprintf(stderr, "Expected signature length %d, Received %d\n",
len, i); len, i);
close(sigfd); close(sigfd);
free(signature); free(signature);
return NULL; return NULL;
} }
close(sigfd); close(sigfd);
return signature; return signature;
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[])
int i, algorithm, sig_len; {
int return_code = 1; /* Default to error. */ uint8_t workbuf[VB2_VERIFY_DIGEST_WORKBUF_BYTES]
uint8_t digest[VB2_MAX_DIGEST_SIZE]; __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
uint8_t* signature = NULL; struct vb2_workbuf wb;
RSAPublicKey* key = NULL; vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
if (argc!=5) { int return_code = 1; /* Default to error. */
fprintf(stderr, "Usage: %s <algorithm> <key file> <signature file>" uint8_t digest[VB2_MAX_DIGEST_SIZE];
" <input file>\n\n", argv[0]); struct vb2_packed_key *pk = NULL;
fprintf(stderr, "where <algorithm> depends on the signature algorithm" uint8_t *signature = NULL;
" used:\n"); uint32_t sig_len = 0;
for(i = 0; i<kNumAlgorithms; i++)
fprintf(stderr, "\t%d for %s\n", i, algo_strings[i]);
return -1;
}
algorithm = atoi(argv[1]); if (argc != 5) {
if (algorithm >= kNumAlgorithms) { int i;
fprintf(stderr, "Invalid Algorithm!\n"); fprintf(stderr,
return 0; "Usage: %s <algorithm> <key file> <signature file>"
} " <input file>\n\n", argv[0]);
/* Length of the RSA Signature/RSA Key */ fprintf(stderr,
sig_len = siglen_map[algorithm]; "where <algorithm> depends on the signature algorithm"
if ((key = RSAPublicKeyFromFile(argv[2])) && " used:\n");
(signature = read_signature(argv[3], sig_len)) && for(i = 0; i < VB2_ALG_COUNT; i++)
(VB2_SUCCESS == DigestFile(argv[4], vb2_crypto_to_hash(algorithm), fprintf(stderr, "\t%d for %s\n", i, algo_strings[i]);
digest, sizeof(digest)))) { return -1;
if (RSAVerify(key, signature, sig_len, algorithm, digest)) { }
return_code = 0;
fprintf(stderr, "Signature Verification "
COL_GREEN "SUCCEEDED" COL_STOP "\n");
} else {
fprintf(stderr, "Signature Verification "
COL_RED "FAILED" COL_STOP "\n");
}
}
else
return_code = -1;
free(key); int algorithm = atoi(argv[1]);
free(signature); if (algorithm >= kNumAlgorithms) {
fprintf(stderr, "Invalid algorithm %d\n", algorithm);
goto error;
}
return return_code; pk = vb2_read_packed_keyb(argv[2], algorithm, 0);
if (!pk) {
fprintf(stderr, "Can't read RSA public key.\n");
goto error;
}
struct vb2_public_key k2;
if (VB2_SUCCESS != vb2_unpack_key(&k2, (const uint8_t *)pk,
pk->key_offset + pk->key_size)) {
fprintf(stderr, "Can't unpack RSA public key.\n");
goto error;
}
if (VB2_SUCCESS != vb2_read_file(argv[3], &signature, &sig_len)) {
fprintf(stderr, "Can't read signature.\n");
goto error;
}
uint32_t expect_sig_size =
vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm));
if (sig_len != expect_sig_size) {
fprintf(stderr, "Expected signature size %u, got %u\n",
expect_sig_size, sig_len);
goto error;
}
if (VB2_SUCCESS != DigestFile(argv[4], vb2_crypto_to_hash(algorithm),
digest, sizeof(digest))) {
fprintf(stderr, "Error calculating digest.\n");
goto error;
}
if (VB2_SUCCESS == vb2_rsa_verify_digest(&k2, signature, digest, &wb)) {
return_code = 0;
fprintf(stderr, "Signature Verification "
COL_GREEN "SUCCEEDED" COL_STOP "\n");
} else {
fprintf(stderr, "Signature Verification "
COL_RED "FAILED" COL_STOP "\n");
}
error:
if (pk)
free(pk);
if (signature)
free(signature);
return return_code;
} }