mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-23 17:55:01 +00:00
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:
committed by
chrome-bot
parent
13b109762a
commit
5a9f498182
9
Makefile
9
Makefile
@@ -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
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_ */
|
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,20 +15,26 @@
|
|||||||
#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;
|
int i, sigfd;
|
||||||
uint8_t* signature = NULL;
|
uint8_t* signature = NULL;
|
||||||
if ((sigfd = open(input_file, O_RDONLY)) == -1) {
|
if ((sigfd = open(input_file, O_RDONLY)) == -1) {
|
||||||
@@ -44,7 +50,7 @@ uint8_t* read_signature(char* input_file, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
@@ -55,35 +61,71 @@ uint8_t* read_signature(char* input_file, int len) {
|
|||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[])
|
||||||
int i, algorithm, sig_len;
|
{
|
||||||
|
uint8_t workbuf[VB2_VERIFY_DIGEST_WORKBUF_BYTES]
|
||||||
|
__attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
|
||||||
|
struct vb2_workbuf wb;
|
||||||
|
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
|
||||||
|
|
||||||
int return_code = 1; /* Default to error. */
|
int return_code = 1; /* Default to error. */
|
||||||
uint8_t digest[VB2_MAX_DIGEST_SIZE];
|
uint8_t digest[VB2_MAX_DIGEST_SIZE];
|
||||||
uint8_t* signature = NULL;
|
struct vb2_packed_key *pk = NULL;
|
||||||
RSAPublicKey* key = NULL;
|
uint8_t *signature = NULL;
|
||||||
|
uint32_t sig_len = 0;
|
||||||
|
|
||||||
if (argc!=5) {
|
if (argc != 5) {
|
||||||
fprintf(stderr, "Usage: %s <algorithm> <key file> <signature file>"
|
int i;
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: %s <algorithm> <key file> <signature file>"
|
||||||
" <input file>\n\n", argv[0]);
|
" <input file>\n\n", argv[0]);
|
||||||
fprintf(stderr, "where <algorithm> depends on the signature algorithm"
|
fprintf(stderr,
|
||||||
|
"where <algorithm> depends on the signature algorithm"
|
||||||
" used:\n");
|
" used:\n");
|
||||||
for(i = 0; i<kNumAlgorithms; i++)
|
for(i = 0; i < VB2_ALG_COUNT; i++)
|
||||||
fprintf(stderr, "\t%d for %s\n", i, algo_strings[i]);
|
fprintf(stderr, "\t%d for %s\n", i, algo_strings[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
algorithm = atoi(argv[1]);
|
int algorithm = atoi(argv[1]);
|
||||||
if (algorithm >= kNumAlgorithms) {
|
if (algorithm >= kNumAlgorithms) {
|
||||||
fprintf(stderr, "Invalid Algorithm!\n");
|
fprintf(stderr, "Invalid algorithm %d\n", algorithm);
|
||||||
return 0;
|
goto error;
|
||||||
}
|
}
|
||||||
/* Length of the RSA Signature/RSA Key */
|
|
||||||
sig_len = siglen_map[algorithm];
|
pk = vb2_read_packed_keyb(argv[2], algorithm, 0);
|
||||||
if ((key = RSAPublicKeyFromFile(argv[2])) &&
|
if (!pk) {
|
||||||
(signature = read_signature(argv[3], sig_len)) &&
|
fprintf(stderr, "Can't read RSA public key.\n");
|
||||||
(VB2_SUCCESS == DigestFile(argv[4], vb2_crypto_to_hash(algorithm),
|
goto error;
|
||||||
digest, sizeof(digest)))) {
|
}
|
||||||
if (RSAVerify(key, signature, sig_len, algorithm, digest)) {
|
|
||||||
|
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;
|
return_code = 0;
|
||||||
fprintf(stderr, "Signature Verification "
|
fprintf(stderr, "Signature Verification "
|
||||||
COL_GREEN "SUCCEEDED" COL_STOP "\n");
|
COL_GREEN "SUCCEEDED" COL_STOP "\n");
|
||||||
@@ -91,11 +133,11 @@ int main(int argc, char* argv[]) {
|
|||||||
fprintf(stderr, "Signature Verification "
|
fprintf(stderr, "Signature Verification "
|
||||||
COL_RED "FAILED" COL_STOP "\n");
|
COL_RED "FAILED" COL_STOP "\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
return_code = -1;
|
|
||||||
|
|
||||||
free(key);
|
error:
|
||||||
|
if (pk)
|
||||||
|
free(pk);
|
||||||
|
if (signature)
|
||||||
free(signature);
|
free(signature);
|
||||||
|
|
||||||
return return_code;
|
return return_code;
|
||||||
|
|||||||
Reference in New Issue
Block a user