diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | firmware/2lib/2crypto.c | 202 | ||||
-rw-r--r-- | firmware/2lib/2rsa.c | 39 | ||||
-rw-r--r-- | firmware/2lib/2sha_utility.c | 67 | ||||
-rw-r--r-- | firmware/2lib/include/2crypto.h | 63 | ||||
-rw-r--r-- | firmware/2lib/include/2rsa.h | 11 | ||||
-rw-r--r-- | firmware/2lib/include/2sha.h | 20 | ||||
-rw-r--r-- | futility/cmd_create.c | 14 | ||||
-rw-r--r-- | futility/cmd_sign.c | 13 | ||||
-rw-r--r-- | futility/futility_options.h | 3 | ||||
-rw-r--r-- | futility/vb2_helper.c | 27 | ||||
-rw-r--r-- | host/include/vboot_host.h | 24 | ||||
-rw-r--r-- | host/lib/crypto.c | 44 | ||||
-rw-r--r-- | host/lib/include/host_common.h | 1 | ||||
-rw-r--r-- | host/lib21/host_key.c | 105 | ||||
-rw-r--r-- | host/lib21/include/host_key21.h | 51 | ||||
-rw-r--r-- | tests/vb2_crypto_tests.c | 104 | ||||
-rw-r--r-- | tests/vb2_sha_tests.c | 17 |
18 files changed, 460 insertions, 353 deletions
@@ -361,6 +361,7 @@ FWLIB_SRCS = \ firmware/2lib/2common.c \ firmware/2lib/2context.c \ firmware/2lib/2crc8.c \ + firmware/2lib/2crypto.c \ firmware/2lib/2ec_sync.c \ firmware/2lib/2gbb.c \ firmware/2lib/2hmac.c \ @@ -451,6 +452,7 @@ UTILLIB_SRCS = \ host/arch/${ARCH}/lib/crossystem_arch.c \ host/lib/chromeos_config.c \ host/lib/crossystem.c \ + host/lib/crypto.c \ host/lib/file_keys.c \ host/lib/fmap.c \ host/lib/host_common.c \ @@ -487,6 +489,7 @@ HOSTLIB_SRCS = \ firmware/2lib/2common.c \ firmware/2lib/2context.c \ firmware/2lib/2crc8.c \ + firmware/2lib/2crypto.c \ firmware/2lib/2hmac.c \ firmware/2lib/2kernel.c \ firmware/2lib/2nvstorage.c \ @@ -507,6 +510,7 @@ HOSTLIB_SRCS = \ host/arch/${ARCH}/lib/crossystem_arch.c \ host/lib/chromeos_config.c \ host/lib/crossystem.c \ + host/lib/crypto.c \ host/lib/extract_vmlinuz.c \ host/lib/fmap.c \ host/lib/host_misc.c \ @@ -702,6 +706,7 @@ TEST2X_NAMES = \ tests/vb2_common_tests \ tests/vb2_common2_tests \ tests/vb2_common3_tests \ + tests/vb2_crypto_tests \ tests/vb2_ec_sync_tests \ tests/vb2_gbb_tests \ tests/vb2_host_key_tests \ @@ -884,6 +889,8 @@ headers_install: ${Q}mkdir -p ${UI_DIR} ${Q}${INSTALL} -t ${UI_DIR} -m644 \ host/include/* \ + firmware/2lib/include/2crypto.h \ + firmware/2lib/include/2sysincludes.h \ firmware/include/gpt.h \ firmware/include/tlcl.h \ firmware/include/tss_constants.h \ @@ -1215,6 +1222,7 @@ run2tests: install_for_test ${RUNTEST} ${BUILD_RUN}/tests/vb2_common_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_common2_tests ${TEST_KEYS} ${RUNTEST} ${BUILD_RUN}/tests/vb2_common3_tests ${TEST_KEYS} + ${RUNTEST} ${BUILD_RUN}/tests/vb2_crypto_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_ec_sync_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_gbb_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_host_key_tests diff --git a/firmware/2lib/2crypto.c b/firmware/2lib/2crypto.c new file mode 100644 index 00000000..5906301d --- /dev/null +++ b/firmware/2lib/2crypto.c @@ -0,0 +1,202 @@ +/* Copyright 2020 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. + * + * Hash and signature algorithm parsing helpers for host utilities. + */ + +#include "2common.h" +#include "2crypto.h" +#include "2rsa.h" +#include "2sha.h" +#include "2sysincludes.h" + +/* These two need to be exported for host/lib/crypto.c */ + +const char *vb2_sig_names[VB2_SIG_ALG_COUNT] = { + [VB2_SIG_NONE] = "none", + [VB2_SIG_RSA1024] = "RSA1024", + [VB2_SIG_RSA2048] = "RSA2048", + [VB2_SIG_RSA4096] = "RSA4096", + [VB2_SIG_RSA8192] = "RSA8192", + [VB2_SIG_RSA2048_EXP3] = "RSA2048EXP3", + [VB2_SIG_RSA3072_EXP3] = "RSA3072EXP3", +}; + +const char *vb2_hash_names[VB2_HASH_ALG_COUNT] = { + [VB2_HASH_NONE] = "none", +#if VB2_SUPPORT_SHA1 + [VB2_HASH_SHA1] = VB2_SHA1_ALG_NAME, +#endif +#if VB2_SUPPORT_SHA256 + [VB2_HASH_SHA256] = VB2_SHA256_ALG_NAME, +#endif +#if VB2_SUPPORT_SHA512 + [VB2_HASH_SHA512] = VB2_SHA512_ALG_NAME, +#endif +}; + +/* The others are internal to this file. */ + +static const char *crypto_names[] = { +#if VB2_SUPPORT_SHA1 + [VB2_ALG_RSA1024_SHA1] = "RSA1024 SHA1", + [VB2_ALG_RSA2048_SHA1] = "RSA2048 SHA1", + [VB2_ALG_RSA4096_SHA1] = "RSA4096 SHA1", + [VB2_ALG_RSA8192_SHA1] = "RSA8192 SHA1", + [VB2_ALG_RSA2048_EXP3_SHA1] = "RSA2048 EXP3 SHA1", + [VB2_ALG_RSA3072_EXP3_SHA1] = "RSA3072 EXP3 SHA1", +#endif +#if VB2_SUPPORT_SHA256 + [VB2_ALG_RSA1024_SHA256] = "RSA1024 SHA256", + [VB2_ALG_RSA2048_SHA256] = "RSA2048 SHA256", + [VB2_ALG_RSA4096_SHA256] = "RSA4096 SHA256", + [VB2_ALG_RSA8192_SHA256] = "RSA8192 SHA256", + [VB2_ALG_RSA2048_EXP3_SHA256] = "RSA2048 EXP3 SHA256", + [VB2_ALG_RSA3072_EXP3_SHA256] = "RSA3072 EXP3 SHA256", +#endif +#if VB2_SUPPORT_SHA512 + [VB2_ALG_RSA1024_SHA512] = "RSA1024 SHA512", + [VB2_ALG_RSA2048_SHA512] = "RSA2048 SHA512", + [VB2_ALG_RSA4096_SHA512] = "RSA4096 SHA512", + [VB2_ALG_RSA8192_SHA512] = "RSA8192 SHA512", + [VB2_ALG_RSA2048_EXP3_SHA512] = "RSA2048 EXP3 SHA512", + [VB2_ALG_RSA3072_EXP3_SHA512] = "RSA3072 EXP3 SHA512", +#endif +}; + +static const char *crypto_filenames[] = { +#if VB2_SUPPORT_SHA1 + [VB2_ALG_RSA1024_SHA1] = "rsa1024", + [VB2_ALG_RSA2048_SHA1] = "rsa2048", + [VB2_ALG_RSA4096_SHA1] = "rsa4096", + [VB2_ALG_RSA8192_SHA1] = "rsa8192", + [VB2_ALG_RSA2048_EXP3_SHA1] = "rsa2048_exp3", + [VB2_ALG_RSA3072_EXP3_SHA1] = "rsa3072_exp3", +#endif +#if VB2_SUPPORT_SHA256 + [VB2_ALG_RSA1024_SHA256] = "rsa1024", + [VB2_ALG_RSA2048_SHA256] = "rsa2048", + [VB2_ALG_RSA4096_SHA256] = "rsa4096", + [VB2_ALG_RSA8192_SHA256] = "rsa8192", + [VB2_ALG_RSA2048_EXP3_SHA256] = "rsa2048_exp3", + [VB2_ALG_RSA3072_EXP3_SHA256] = "rsa3072_exp3", +#endif +#if VB2_SUPPORT_SHA512 + [VB2_ALG_RSA1024_SHA512] = "rsa1024", + [VB2_ALG_RSA2048_SHA512] = "rsa2048", + [VB2_ALG_RSA4096_SHA512] = "rsa4096", + [VB2_ALG_RSA8192_SHA512] = "rsa8192", + [VB2_ALG_RSA2048_EXP3_SHA512] = "rsa2048_exp3", + [VB2_ALG_RSA3072_EXP3_SHA512] = "rsa3072_exp3", +#endif +}; + +static const uint8_t crypto_to_sig[] = { +#if VB2_SUPPORT_SHA1 + [VB2_ALG_RSA1024_SHA1] = VB2_SIG_RSA1024, + [VB2_ALG_RSA2048_SHA1] = VB2_SIG_RSA2048, + [VB2_ALG_RSA4096_SHA1] = VB2_SIG_RSA4096, + [VB2_ALG_RSA8192_SHA1] = VB2_SIG_RSA8192, + [VB2_ALG_RSA2048_EXP3_SHA1] = VB2_SIG_RSA2048_EXP3, + [VB2_ALG_RSA3072_EXP3_SHA1] = VB2_SIG_RSA3072_EXP3, +#endif +#if VB2_SUPPORT_SHA256 + [VB2_ALG_RSA1024_SHA256] = VB2_SIG_RSA1024, + [VB2_ALG_RSA2048_SHA256] = VB2_SIG_RSA2048, + [VB2_ALG_RSA4096_SHA256] = VB2_SIG_RSA4096, + [VB2_ALG_RSA8192_SHA256] = VB2_SIG_RSA8192, + [VB2_ALG_RSA2048_EXP3_SHA256] = VB2_SIG_RSA2048_EXP3, + [VB2_ALG_RSA3072_EXP3_SHA256] = VB2_SIG_RSA3072_EXP3, +#endif +#if VB2_SUPPORT_SHA512 + [VB2_ALG_RSA1024_SHA512] = VB2_SIG_RSA1024, + [VB2_ALG_RSA2048_SHA512] = VB2_SIG_RSA2048, + [VB2_ALG_RSA4096_SHA512] = VB2_SIG_RSA4096, + [VB2_ALG_RSA8192_SHA512] = VB2_SIG_RSA8192, + [VB2_ALG_RSA2048_EXP3_SHA512] = VB2_SIG_RSA2048_EXP3, + [VB2_ALG_RSA3072_EXP3_SHA512] = VB2_SIG_RSA3072_EXP3, +#endif +}; + +static const uint8_t crypto_to_hash[] = { +#if VB2_SUPPORT_SHA1 + [VB2_ALG_RSA1024_SHA1] = VB2_HASH_SHA1, + [VB2_ALG_RSA2048_SHA1] = VB2_HASH_SHA1, + [VB2_ALG_RSA4096_SHA1] = VB2_HASH_SHA1, + [VB2_ALG_RSA8192_SHA1] = VB2_HASH_SHA1, + [VB2_ALG_RSA2048_EXP3_SHA1] = VB2_HASH_SHA1, + [VB2_ALG_RSA3072_EXP3_SHA1] = VB2_HASH_SHA1, +#endif +#if VB2_SUPPORT_SHA256 + [VB2_ALG_RSA1024_SHA256] = VB2_HASH_SHA256, + [VB2_ALG_RSA2048_SHA256] = VB2_HASH_SHA256, + [VB2_ALG_RSA4096_SHA256] = VB2_HASH_SHA256, + [VB2_ALG_RSA8192_SHA256] = VB2_HASH_SHA256, + [VB2_ALG_RSA2048_EXP3_SHA256] = VB2_HASH_SHA256, + [VB2_ALG_RSA3072_EXP3_SHA256] = VB2_HASH_SHA256, +#endif +#if VB2_SUPPORT_SHA512 + [VB2_ALG_RSA1024_SHA512] = VB2_HASH_SHA512, + [VB2_ALG_RSA2048_SHA512] = VB2_HASH_SHA512, + [VB2_ALG_RSA4096_SHA512] = VB2_HASH_SHA512, + [VB2_ALG_RSA8192_SHA512] = VB2_HASH_SHA512, + [VB2_ALG_RSA2048_EXP3_SHA512] = VB2_HASH_SHA512, + [VB2_ALG_RSA3072_EXP3_SHA512] = VB2_HASH_SHA512, +#endif +}; + +#if VB2_SUPPORT_SHA512 +_Static_assert(ARRAY_SIZE(crypto_names) == VB2_ALG_COUNT, ""); +_Static_assert(ARRAY_SIZE(crypto_filenames) == VB2_ALG_COUNT, ""); +_Static_assert(ARRAY_SIZE(crypto_to_sig) == VB2_ALG_COUNT, ""); +_Static_assert(ARRAY_SIZE(crypto_to_hash) == VB2_ALG_COUNT, ""); +#endif + +const char *vb2_get_hash_algorithm_name(enum vb2_hash_algorithm hash_alg) +{ if (hash_alg < ARRAY_SIZE(vb2_hash_names) && vb2_hash_names[hash_alg]) + return vb2_hash_names[hash_alg]; + else + return VB2_INVALID_ALG_NAME; +} + +const char *vb2_get_sig_algorithm_name(enum vb2_signature_algorithm sig_alg) +{ + if (sig_alg < ARRAY_SIZE(vb2_sig_names) && vb2_sig_names[sig_alg]) + return vb2_sig_names[sig_alg]; + else + return VB2_INVALID_ALG_NAME; +} + +const char *vb2_get_crypto_algorithm_name(enum vb2_crypto_algorithm alg) +{ + if (alg < ARRAY_SIZE(crypto_names) && crypto_names[alg]) + return crypto_names[alg]; + else + return VB2_INVALID_ALG_NAME; +} + +const char *vb2_get_crypto_algorithm_file(enum vb2_crypto_algorithm alg) +{ + if (alg < ARRAY_SIZE(crypto_filenames) && crypto_filenames[alg]) + return crypto_filenames[alg]; + else + return VB2_INVALID_ALG_NAME; +} + +enum vb2_signature_algorithm vb2_crypto_to_signature( + enum vb2_crypto_algorithm algorithm) +{ + if (algorithm < ARRAY_SIZE(crypto_to_sig)) + return crypto_to_sig[algorithm]; + else + return VB2_SIG_INVALID; +} + +enum vb2_hash_algorithm vb2_crypto_to_hash(enum vb2_crypto_algorithm algorithm) +{ + if (algorithm < ARRAY_SIZE(crypto_to_hash)) + return crypto_to_hash[algorithm]; + else + return VB2_HASH_INVALID; +} diff --git a/firmware/2lib/2rsa.c b/firmware/2lib/2rsa.c index 54b00b63..1a23d023 100644 --- a/firmware/2lib/2rsa.c +++ b/firmware/2lib/2rsa.c @@ -182,45 +182,6 @@ static void modpow(const struct vb2_public_key *key, uint8_t *inout, } } - -static const uint8_t crypto_to_sig[] = { - VB2_SIG_RSA1024, - VB2_SIG_RSA1024, - VB2_SIG_RSA1024, - VB2_SIG_RSA2048, - VB2_SIG_RSA2048, - VB2_SIG_RSA2048, - VB2_SIG_RSA4096, - VB2_SIG_RSA4096, - VB2_SIG_RSA4096, - VB2_SIG_RSA8192, - VB2_SIG_RSA8192, - VB2_SIG_RSA8192, - VB2_SIG_RSA2048_EXP3, - VB2_SIG_RSA2048_EXP3, - VB2_SIG_RSA2048_EXP3, - VB2_SIG_RSA3072_EXP3, - VB2_SIG_RSA3072_EXP3, - VB2_SIG_RSA3072_EXP3, -}; - -/** - * Convert vb2_crypto_algorithm to vb2_signature_algorithm. - * - * @param algorithm Crypto algorithm (vb2_crypto_algorithm) - * - * @return The signature algorithm for that crypto algorithm, or - * VB2_SIG_INVALID if the crypto algorithm or its corresponding signature - * algorithm is invalid or not supported. - */ -enum vb2_signature_algorithm vb2_crypto_to_signature(uint32_t algorithm) -{ - if (algorithm < ARRAY_SIZE(crypto_to_sig)) - return crypto_to_sig[algorithm]; - else - return VB2_SIG_INVALID; -} - uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg) { switch (sig_alg) { diff --git a/firmware/2lib/2sha_utility.c b/firmware/2lib/2sha_utility.c index 4c8d41ca..0af117a4 100644 --- a/firmware/2lib/2sha_utility.c +++ b/firmware/2lib/2sha_utility.c @@ -9,53 +9,6 @@ #include "2sha.h" #include "2sysincludes.h" -#if VB2_SUPPORT_SHA1 -#define CTH_SHA1 VB2_HASH_SHA1 -#else -#define CTH_SHA1 VB2_HASH_INVALID -#endif - -#if VB2_SUPPORT_SHA256 -#define CTH_SHA256 VB2_HASH_SHA256 -#else -#define CTH_SHA256 VB2_HASH_INVALID -#endif - -#if VB2_SUPPORT_SHA512 -#define CTH_SHA512 VB2_HASH_SHA512 -#else -#define CTH_SHA512 VB2_HASH_INVALID -#endif - -static const uint8_t crypto_to_hash[] = { - CTH_SHA1, - CTH_SHA256, - CTH_SHA512, - CTH_SHA1, - CTH_SHA256, - CTH_SHA512, - CTH_SHA1, - CTH_SHA256, - CTH_SHA512, - CTH_SHA1, - CTH_SHA256, - CTH_SHA512, - CTH_SHA1, - CTH_SHA256, - CTH_SHA512, - CTH_SHA1, - CTH_SHA256, - CTH_SHA512, -}; - -enum vb2_hash_algorithm vb2_crypto_to_hash(uint32_t algorithm) -{ - if (algorithm < ARRAY_SIZE(crypto_to_hash)) - return crypto_to_hash[algorithm]; - else - return VB2_HASH_INVALID; -} - size_t vb2_digest_size(enum vb2_hash_algorithm hash_alg) { switch (hash_alg) { @@ -96,26 +49,6 @@ size_t vb2_hash_block_size(enum vb2_hash_algorithm alg) } } -const char *vb2_get_hash_algorithm_name(enum vb2_hash_algorithm alg) -{ - switch (alg) { -#if VB2_SUPPORT_SHA1 - case VB2_HASH_SHA1: - return VB2_SHA1_ALG_NAME; -#endif -#if VB2_SUPPORT_SHA256 - case VB2_HASH_SHA256: - return VB2_SHA256_ALG_NAME; -#endif -#if VB2_SUPPORT_SHA512 - case VB2_HASH_SHA512: - return VB2_SHA512_ALG_NAME; -#endif - default: - return VB2_INVALID_ALG_NAME; - } -} - test_mockable vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, enum vb2_hash_algorithm hash_alg) diff --git a/firmware/2lib/include/2crypto.h b/firmware/2lib/include/2crypto.h index f595fd4f..0413a624 100644 --- a/firmware/2lib/include/2crypto.h +++ b/firmware/2lib/include/2crypto.h @@ -8,7 +8,7 @@ #ifndef VBOOT_REFERENCE_2CRYPTO_H_ #define VBOOT_REFERENCE_2CRYPTO_H_ -#include <stdint.h> +#include "2sysincludes.h" /* Verified boot crypto algorithms */ enum vb2_crypto_algorithm { @@ -61,6 +61,8 @@ enum vb2_signature_algorithm { enum vb2_hash_algorithm { /* Invalid or unsupported digest type */ VB2_HASH_INVALID = 0, + /* For some applications, it's more useful that 0 means "no hash". */ + VB2_HASH_NONE = VB2_HASH_INVALID, /* SHA-1. Warning: This is likely to be deprecated soon! */ VB2_HASH_SHA1 = 1, @@ -73,4 +75,63 @@ enum vb2_hash_algorithm { VB2_HASH_ALG_COUNT, }; +/* Arrays mapping signature/hash types to their string representations. */ +extern const char *vb2_sig_names[VB2_SIG_ALG_COUNT]; +extern const char *vb2_hash_names[VB2_HASH_ALG_COUNT]; + +/** + * Convert vb2_crypto_algorithm to vb2_signature_algorithm. + * + * @param algorithm Crypto algorithm (vb2_crypto_algorithm) + * + * @return The signature algorithm for that crypto algorithm, or + * VB2_SIG_INVALID if the crypto algorithm or its corresponding signature + * algorithm is invalid or not supported. + */ +enum vb2_signature_algorithm vb2_crypto_to_signature( + enum vb2_crypto_algorithm algorithm); + +/** + * Convert vb2_crypto_algorithm to vb2_hash_algorithm. + * + * @param algorithm Crypto algorithm (vb2_crypto_algorithm) + * + * @return The hash algorithm for that crypto algorithm, or VB2_HASH_INVALID if + * the crypto algorithm or its corresponding hash algorithm is invalid or not + * supported. + */ +enum vb2_hash_algorithm vb2_crypto_to_hash(enum vb2_crypto_algorithm algorithm); + +/** + * Return the name of a signature algorithm. + * + * @param sig_alg Signature algorithm to look up + * @return The corresponding name, or VB2_INVALID_ALG_NAME if no match. + */ +const char *vb2_get_sig_algorithm_name(enum vb2_signature_algorithm sig_alg); + +/** + * Return the name of a hash algorithm + * + * @param alg Hash algorithm ID + * @return The corresponding name, or VB2_INVALID_ALG_NAME if no match. + */ +const char *vb2_get_hash_algorithm_name(enum vb2_hash_algorithm alg); + +/** + * Return the name of a crypto algorithm. + * + * @param alg Crypto algorithm to look up + * @return The corresponding name, or VB2_INVALID_ALG_NAME if no match. + */ +const char *vb2_get_crypto_algorithm_name(enum vb2_crypto_algorithm alg); + +/** + * Return the name of a crypto algorithm. + * + * @param alg Crypto algorithm to look up + * @return The corresponding stem filename, or VB2_INVALID_ALG_NAME if no match. + */ +const char *vb2_get_crypto_algorithm_file(enum vb2_crypto_algorithm alg); + #endif /* VBOOT_REFERENCE_2CRYPTO_H_ */ diff --git a/firmware/2lib/include/2rsa.h b/firmware/2lib/include/2rsa.h index 0ee72ca5..0d0bf2aa 100644 --- a/firmware/2lib/include/2rsa.h +++ b/firmware/2lib/include/2rsa.h @@ -26,17 +26,6 @@ struct vb2_public_key { }; /** - * Convert vb2_crypto_algorithm to vb2_signature_algorithm. - * - * @param algorithm Crypto algorithm (vb2_crypto_algorithm) - * - * @return The signature algorithm for that crypto algorithm, or - * VB2_SIG_INVALID if the crypto algorithm or its corresponding signature - * algorithm is invalid or not supported. - */ -enum vb2_signature_algorithm vb2_crypto_to_signature(uint32_t algorithm); - -/** * Return the size of a RSA signature * * @param sig_alg Signature algorithm diff --git a/firmware/2lib/include/2sha.h b/firmware/2lib/include/2sha.h index 95f85804..a8e654e3 100644 --- a/firmware/2lib/include/2sha.h +++ b/firmware/2lib/include/2sha.h @@ -175,17 +175,6 @@ void vb2_sha512_finalize(struct vb2_sha512_context *ctx, uint8_t *digest); void vb2_sha256_extend(const uint8_t *from, const uint8_t *by, uint8_t *to); /** - * Convert vb2_crypto_algorithm to vb2_hash_algorithm. - * - * @param algorithm Crypto algorithm (vb2_crypto_algorithm) - * - * @return The hash algorithm for that crypto algorithm, or VB2_HASH_INVALID if - * the crypto algorithm or its corresponding hash algorithm is invalid or not - * supported. - */ -enum vb2_hash_algorithm vb2_crypto_to_hash(uint32_t algorithm); - -/** * Return the size of the digest for a hash algorithm. * * @param hash_alg Hash algorithm @@ -202,15 +191,6 @@ size_t vb2_digest_size(enum vb2_hash_algorithm hash_alg); size_t vb2_hash_block_size(enum vb2_hash_algorithm alg); /** - * Return the name of a hash algorithm - * - * @param alg Hash algorithm ID - * @return String containing a hash name or VB2_INVALID_ALG_NAME - * if <alg> is invalid. - */ -const char *vb2_get_hash_algorithm_name(enum vb2_hash_algorithm alg); - -/** * Initialize a digest context for doing block-style digesting. * * @param dc Digest context diff --git a/futility/cmd_create.c b/futility/cmd_create.c index 2f7a8d5f..aca1d4c0 100644 --- a/futility/cmd_create.c +++ b/futility/cmd_create.c @@ -23,6 +23,7 @@ #include "openssl_compat.h" #include "util_misc.h" #include "vb2_common.h" +#include "vboot_host.h" /* Command line options */ enum { @@ -55,7 +56,7 @@ static const struct option long_opts[] = { static void print_help(int argc, char *argv[]) { - const struct vb2_text_vs_enum *entry; + enum vb2_hash_algorithm alg; printf("\n" "Usage: " MYNAME " %s [options] <INFILE> [<BASENAME>]\n", argv[0]); @@ -67,10 +68,13 @@ static void print_help(int argc, char *argv[]) " --version <number> Key version (default %d)\n" " --hash_alg <number> Hashing algorithm to use:\n", DEFAULT_VERSION); - for (entry = vb2_text_vs_hash; entry->name; entry++) - printf(" %d / %s%s\n", - entry->num, entry->name, - entry->num == VB2_HASH_SHA256 ? " (default)" : ""); + for (alg = 0; alg < VB2_HASH_ALG_COUNT; alg++) { + const char *name = vb2_get_hash_algorithm_name(alg); + if (strcmp(name, VB2_INVALID_ALG_NAME) != 0) + printf(" %d / %s%s\n", + alg, name, + alg == VB2_HASH_SHA256 ? " (default)" : ""); + } printf( " --id <id> Identifier for this keypair (vb21 only)\n" " --desc <text> Human-readable description (vb21 only)\n" diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c index 980e6d12..c95b8c97 100644 --- a/futility/cmd_sign.c +++ b/futility/cmd_sign.c @@ -423,7 +423,7 @@ static void print_help_kern_preamble(int argc, char *argv[]) static void print_help_usbpd1(int argc, char *argv[]) { - const struct vb2_text_vs_enum *entry; + enum vb2_hash_algorithm algo; printf("\n" "Usage: " MYNAME " %s --type %s [options] INFILE [OUTFILE]\n" @@ -450,10 +450,13 @@ static void print_help_usbpd1(int argc, char *argv[]) argv[0], futil_file_type_name(FILE_TYPE_USBPD1), futil_file_type_desc(FILE_TYPE_USBPD1)); - for (entry = vb2_text_vs_hash; entry->name; entry++) - printf(" %d / %s%s\n", - entry->num, entry->name, - entry->num == VB2_HASH_SHA256 ? " (default)" : ""); + for (algo = 0; algo < VB2_HASH_ALG_COUNT; algo++) { + const char *name = vb2_get_hash_algorithm_name(algo); + if (strcmp(name, VB2_INVALID_ALG_NAME) != 0) + printf(" %d / %s%s\n", + algo, name, + algo == VB2_HASH_SHA256 ? " (default)" : ""); + } printf("\n" "The size and offset assumptions can be overridden. " "All numbers are in bytes.\n" diff --git a/futility/futility_options.h b/futility/futility_options.h index a3bdd650..a79505c3 100644 --- a/futility/futility_options.h +++ b/futility/futility_options.h @@ -67,7 +67,4 @@ struct sign_option_s { }; extern struct sign_option_s sign_option; -/* Return true if hash_alg was identified, either by name or number */ -int vb2_lookup_hash_alg(const char *str, enum vb2_hash_algorithm *alg); - #endif /* VBOOT_REFERENCE_FUTILITY_OPTIONS_H_ */ diff --git a/futility/vb2_helper.c b/futility/vb2_helper.c index fb0362ae..4d676a68 100644 --- a/futility/vb2_helper.c +++ b/futility/vb2_helper.c @@ -20,33 +20,6 @@ #include "openssl_compat.h" #include "util_misc.h" -int vb2_lookup_hash_alg(const char *str, enum vb2_hash_algorithm *alg) -{ - const struct vb2_text_vs_enum *entry; - uint32_t val; - char *e; - - /* try string first */ - entry = vb2_lookup_by_name(vb2_text_vs_hash, str); - if (entry) { - *alg = entry->num; - return 1; - } - - /* fine, try number */ - val = strtoul(str, &e, 0); - if (!*str || (e && *e)) - /* that's not a number */ - return 0; - - if (!vb2_lookup_by_num(vb2_text_vs_hash, val)) - /* That's not a valid alg */ - return 0; - - *alg = val; - return 1; -} - enum futil_file_type ft_recognize_vb21_key(uint8_t *buf, uint32_t len) { struct vb2_public_key pubkey; diff --git a/host/include/vboot_host.h b/host/include/vboot_host.h index 81c5434f..328c063b 100644 --- a/host/include/vboot_host.h +++ b/host/include/vboot_host.h @@ -9,14 +9,16 @@ #define VBOOT_REFERENCE_VBOOT_HOST_H_ #include <inttypes.h> +#include <stdbool.h> #include <stdint.h> #include <stdlib.h> +#include "2crypto.h" +#include "cgpt_params.h" + /****************************************************************************/ /* EFI GPT manipulation */ -#include "cgpt_params.h" - #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -73,6 +75,24 @@ char *FindKernelConfig(const char *filename, int ExtractVmlinuz(void *kpart_data, size_t kpart_size, void **vmlinuz_out, size_t *vmlinuz_size); +/** + * Look up a signature algorithm by its string representation. + * + * @param str String representation of algo (e.g. "rsa2048" or "1") + * @param alg Output parameter that will be filled with found enum + * @return True if algorithm was found, false otherwise. + */ +bool vb2_lookup_sig_alg(const char *str, enum vb2_signature_algorithm *sig_alg); + +/** + * Look up a hash algorithm by its string representation. + * + * @param str String representation of algorithm (e.g. "sha1" or "1") + * @param alg Output parameter that will be filled with found enum + * @return True if algorithm was found, false otherwise. + */ +bool vb2_lookup_hash_alg(const char *str, enum vb2_hash_algorithm *hash_alg); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/host/lib/crypto.c b/host/lib/crypto.c new file mode 100644 index 00000000..7103ed8a --- /dev/null +++ b/host/lib/crypto.c @@ -0,0 +1,44 @@ +/* Copyright 2020 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 <stdlib.h> +#include <strings.h> + +#include "vboot_host.h" + +static int lookup_helper(const char *str, const char *table[], size_t size, + unsigned int *out) +{ + unsigned int algo; + char *e; + + /* try string first */ + for (algo = 0; algo < size; algo++) + if (table[algo] && !strcasecmp(table[algo], str)) + goto found; + + /* fine, try number */ + algo = strtoul(str, &e, 0); + if (!*str || (e && *e)) + /* that's not a number */ + return false; + if (algo >= size || !table[algo]) + /* that's not a valid algorithm */ + return false; + + found: + *out = algo; + return true; +} + +bool vb2_lookup_sig_alg(const char *str, enum vb2_signature_algorithm *sig_alg) +{ + return lookup_helper(str, vb2_sig_names, VB2_SIG_ALG_COUNT, sig_alg); +} + +bool vb2_lookup_hash_alg(const char *str, enum vb2_hash_algorithm *hash_alg) +{ + return lookup_helper(str, vb2_hash_names, VB2_HASH_ALG_COUNT, hash_alg); +} diff --git a/host/lib/include/host_common.h b/host/lib/include/host_common.h index 43cb0250..55b15d3b 100644 --- a/host/lib/include/host_common.h +++ b/host/lib/include/host_common.h @@ -14,6 +14,7 @@ #include "host_misc.h" #include "host_signature.h" #include "vboot_api.h" +#include "vboot_host.h" #include "vboot_struct.h" /** diff --git a/host/lib21/host_key.c b/host/lib21/host_key.c index 6e3a2765..cfa99419 100644 --- a/host/lib21/host_key.c +++ b/host/lib21/host_key.c @@ -19,111 +19,6 @@ #include "host_misc.h" #include "openssl_compat.h" -const struct vb2_text_vs_enum vb2_text_vs_sig[] = { - {"RSA1024", VB2_SIG_RSA1024}, - {"RSA2048", VB2_SIG_RSA2048}, - {"RSA4096", VB2_SIG_RSA4096}, - {"RSA8192", VB2_SIG_RSA8192}, - {"RSA2048EXP3", VB2_SIG_RSA2048_EXP3}, - {"RSA3072EXP3", VB2_SIG_RSA3072_EXP3}, - {0, 0} -}; - -const struct vb2_text_vs_enum vb2_text_vs_hash[] = { - {"SHA1", VB2_HASH_SHA1}, - {"SHA256", VB2_HASH_SHA256}, - {"SHA512", VB2_HASH_SHA512}, - {0, 0} -}; - -const struct vb2_text_vs_enum vb2_text_vs_crypto[] = { - {"RSA1024 SHA1", VB2_ALG_RSA1024_SHA1}, - {"RSA1024 SHA256", VB2_ALG_RSA1024_SHA256}, - {"RSA1024 SHA512", VB2_ALG_RSA1024_SHA512}, - {"RSA2048 SHA1", VB2_ALG_RSA2048_SHA1}, - {"RSA2048 SHA256", VB2_ALG_RSA2048_SHA256}, - {"RSA2048 SHA512", VB2_ALG_RSA2048_SHA512}, - {"RSA4096 SHA1", VB2_ALG_RSA4096_SHA1}, - {"RSA4096 SHA256", VB2_ALG_RSA4096_SHA256}, - {"RSA4096 SHA512", VB2_ALG_RSA4096_SHA512}, - {"RSA8192 SHA1", VB2_ALG_RSA8192_SHA1}, - {"RSA8192 SHA256", VB2_ALG_RSA8192_SHA256}, - {"RSA8192 SHA512", VB2_ALG_RSA8192_SHA512}, - {"RSA2048 EXP3 SHA1", VB2_ALG_RSA2048_EXP3_SHA1}, - {"RSA2048 EXP3 SHA256", VB2_ALG_RSA2048_EXP3_SHA256}, - {"RSA2048 EXP3 SHA512", VB2_ALG_RSA2048_EXP3_SHA512}, - {"RSA3072 EXP3 SHA1", VB2_ALG_RSA3072_EXP3_SHA1}, - {"RSA3072 EXP3 SHA256", VB2_ALG_RSA3072_EXP3_SHA256}, - {"RSA3072 EXP3 SHA512", VB2_ALG_RSA3072_EXP3_SHA512}, - {0, 0} -}; - -const struct vb2_text_vs_enum vb2_file_vs_crypto[] = { - {"rsa1024", VB2_ALG_RSA1024_SHA1}, - {"rsa1024", VB2_ALG_RSA1024_SHA256}, - {"rsa1024", VB2_ALG_RSA1024_SHA512}, - {"rsa2048", VB2_ALG_RSA2048_SHA1}, - {"rsa2048", VB2_ALG_RSA2048_SHA256}, - {"rsa2048", VB2_ALG_RSA2048_SHA512}, - {"rsa4096", VB2_ALG_RSA4096_SHA1}, - {"rsa4096", VB2_ALG_RSA4096_SHA256}, - {"rsa4096", VB2_ALG_RSA4096_SHA512}, - {"rsa8192", VB2_ALG_RSA8192_SHA1}, - {"rsa8192", VB2_ALG_RSA8192_SHA256}, - {"rsa8192", VB2_ALG_RSA8192_SHA512}, - {"rsa2048_exp3", VB2_ALG_RSA2048_EXP3_SHA1}, - {"rsa2048_exp3", VB2_ALG_RSA2048_EXP3_SHA256}, - {"rsa2048_exp3", VB2_ALG_RSA2048_EXP3_SHA512}, - {"rsa3072_exp3", VB2_ALG_RSA3072_EXP3_SHA1}, - {"rsa3072_exp3", VB2_ALG_RSA3072_EXP3_SHA256}, - {"rsa3072_exp3", VB2_ALG_RSA3072_EXP3_SHA512}, - {0, 0} -}; - -const struct vb2_text_vs_enum *vb2_lookup_by_num( - const struct vb2_text_vs_enum *table, - const unsigned int num) -{ - for (; table->name; table++) - if (table->num == num) - return table; - return 0; -} - -const struct vb2_text_vs_enum *vb2_lookup_by_name( - const struct vb2_text_vs_enum *table, - const char *name) -{ - for (; table->name; table++) - if (!strcasecmp(table->name, name)) - return table; - return 0; -} - -const char *vb2_get_sig_algorithm_name(enum vb2_signature_algorithm sig_alg) -{ - const struct vb2_text_vs_enum *entry = - vb2_lookup_by_num(vb2_text_vs_sig, sig_alg); - - return entry ? entry->name : VB2_INVALID_ALG_NAME; -} - -const char *vb2_get_crypto_algorithm_name(enum vb2_crypto_algorithm alg) -{ - const struct vb2_text_vs_enum *entry = - vb2_lookup_by_num(vb2_text_vs_crypto, alg); - - return entry ? entry->name : VB2_INVALID_ALG_NAME; -} - -const char *vb2_get_crypto_algorithm_file(enum vb2_crypto_algorithm alg) -{ - const struct vb2_text_vs_enum *entry = - vb2_lookup_by_num(vb2_file_vs_crypto, alg); - - return entry ? entry->name : VB2_INVALID_ALG_NAME; -} - void vb2_private_key_free(struct vb2_private_key *key) { if (!key) diff --git a/host/lib21/include/host_key21.h b/host/lib21/include/host_key21.h index 219e98ab..ae53ad5c 100644 --- a/host/lib21/include/host_key21.h +++ b/host/lib21/include/host_key21.h @@ -32,57 +32,6 @@ struct vb2_packed_private_key { uint8_t key_data[0]; }; -/* Convert between enums and human-readable form. Terminated with {0, 0}. */ -struct vb2_text_vs_enum { - const char *name; - unsigned int num; -}; - -/** - * @param table Table to search - * @param num Enum value to search for - * @return pointer to table entry or NULL if no match - */ -const struct vb2_text_vs_enum *vb2_lookup_by_num( - const struct vb2_text_vs_enum *table, - const unsigned int num); - -/** - * @param table Table to search - * @param name String value to search for - * @return pointer to table entry or NULL if no match - */ -const struct vb2_text_vs_enum *vb2_lookup_by_name( - const struct vb2_text_vs_enum *table, - const char *name); - -extern const struct vb2_text_vs_enum vb2_text_vs_sig[]; -extern const struct vb2_text_vs_enum vb2_text_vs_hash[]; - -/** - * Return the name of a signature algorithm. - * - * @param sig_alg Signature algorithm to look up - * @return The corresponding name, or VB2_INVALID_ALG_NAME if no match. - */ -const char *vb2_get_sig_algorithm_name(enum vb2_signature_algorithm sig_alg); - -/** - * Return the name of a crypto algorithm. - * - * @param alg Crypto algorithm to look up - * @return The corresponding name, or VB2_INVALID_ALG_NAME if no match. - */ -const char *vb2_get_crypto_algorithm_name(enum vb2_crypto_algorithm alg); - -/** - * Return the name of a crypto algorithm. - * - * @param alg Crypto algorithm to look up - * @return The corresponding stem filename, or VB2_INVALID_ALG_NAME if no match. - */ -const char *vb2_get_crypto_algorithm_file(enum vb2_crypto_algorithm alg); - /** * Free a private key. * diff --git a/tests/vb2_crypto_tests.c b/tests/vb2_crypto_tests.c new file mode 100644 index 00000000..c7d66760 --- /dev/null +++ b/tests/vb2_crypto_tests.c @@ -0,0 +1,104 @@ +/* Copyright 2020 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. + * + * Tests for generic crypto algorithm helper stuff. + */ + +#include <stdio.h> + +#include "2crypto.h" +#include "2return_codes.h" +#include "2rsa.h" +#include "2sha.h" +#include "2sysincludes.h" +#include "test_common.h" +#include "vboot_host.h" + +static void hash_algorithm_name_tests(void) +{ + enum vb2_hash_algorithm alg; + char test_name[256]; + + for (alg = 0; alg < VB2_HASH_ALG_COUNT; alg++) { + sprintf(test_name, "%s (alg=%d)", + vb2_get_hash_algorithm_name(alg), alg); + TEST_STR_NEQ(vb2_get_hash_algorithm_name(alg), + VB2_INVALID_ALG_NAME, test_name); + } + + TEST_STR_EQ(vb2_get_hash_algorithm_name(VB2_HASH_ALG_COUNT), + VB2_INVALID_ALG_NAME, "hash alg name out of range"); +} + +static void sig_algorithm_name_tests(void) +{ + enum vb2_signature_algorithm alg; + char test_name[256]; + + for (alg = 1; alg < VB2_SIG_ALG_COUNT; alg++) { + sprintf(test_name, "%s (alg=%d)", + vb2_get_sig_algorithm_name(alg), alg); + TEST_STR_NEQ(vb2_get_sig_algorithm_name(alg), + VB2_INVALID_ALG_NAME, test_name); + } + + TEST_STR_EQ(vb2_get_sig_algorithm_name(VB2_SIG_INVALID), + VB2_INVALID_ALG_NAME, "sig alg name invalid"); + TEST_STR_EQ(vb2_get_sig_algorithm_name(VB2_SIG_ALG_COUNT), + VB2_INVALID_ALG_NAME, "sig alg name out of range"); +} + +static void hash_algorithm_lookup_tests(void) +{ + enum vb2_hash_algorithm alg, out; + char test_name[256]; + + for (alg = 1; alg < VB2_HASH_ALG_COUNT; alg++) { + sprintf(test_name, "%s (alg=%d)", + vb2_get_hash_algorithm_name(alg), alg); + TEST_EQ(vb2_lookup_hash_alg(vb2_get_hash_algorithm_name(alg), + &out), 1, test_name); + TEST_EQ(out, alg, " algorithm correct"); + } + + TEST_EQ(vb2_lookup_hash_alg(VB2_INVALID_ALG_NAME, &out), 0, + "invalid algorithm cannot be parsed"); + TEST_EQ(vb2_lookup_hash_alg("RSA1024", &out), 0, + "cannot parse hash as signature"); + TEST_EQ(vb2_lookup_hash_alg("shA512", &out), 1, + "case insensitivity spot check"); + TEST_EQ(out, VB2_HASH_SHA512, " algorithm correct"); +} + +static void sig_algorithm_lookup_tests(void) +{ + enum vb2_signature_algorithm alg, out; + char test_name[256]; + + for (alg = 1; alg < VB2_SIG_ALG_COUNT; alg++) { + sprintf(test_name, "%s (alg=%d)", + vb2_get_sig_algorithm_name(alg), alg); + TEST_EQ(vb2_lookup_sig_alg(vb2_get_sig_algorithm_name(alg), + &out), 1, test_name); + TEST_EQ(out, alg, " algorithm correct"); + } + + TEST_EQ(vb2_lookup_sig_alg(VB2_INVALID_ALG_NAME, &out), 0, + "invalid algorithm cannot be parsed"); + TEST_EQ(vb2_lookup_sig_alg("SHA256", &out), 0, + "cannot parse signature as hash"); + TEST_EQ(vb2_lookup_sig_alg("rSa2048", &out), 1, + "case insensitivity spot check"); + TEST_EQ(out, VB2_SIG_RSA2048, " algorithm correct"); +} + +int main(int argc, char *argv[]) +{ + hash_algorithm_name_tests(); + sig_algorithm_name_tests(); + hash_algorithm_lookup_tests(); + sig_algorithm_lookup_tests(); + + return gTestSuccess ? 0 : 255; +} diff --git a/tests/vb2_sha_tests.c b/tests/vb2_sha_tests.c index 30d32f6c..9fcac1f3 100644 --- a/tests/vb2_sha_tests.c +++ b/tests/vb2_sha_tests.c @@ -169,22 +169,6 @@ static void misc_tests(void) "vb2_digest_finalize() invalid alg"); } -static void hash_algorithm_name_tests(void) -{ - enum vb2_hash_algorithm alg; - char test_name[256]; - - for (alg = 1; alg < VB2_HASH_ALG_COUNT; alg++) { - sprintf(test_name, "%s: %s (alg=%d)", - __func__, vb2_get_hash_algorithm_name(alg), alg); - TEST_STR_NEQ(vb2_get_hash_algorithm_name(alg), - VB2_INVALID_ALG_NAME, test_name); - } - - TEST_STR_EQ(vb2_get_hash_algorithm_name(VB2_HASH_INVALID), - VB2_INVALID_ALG_NAME, "hash alg name invalid"); -} - int main(int argc, char *argv[]) { /* Initialize long_msg with 'a' x 1,000,000 */ @@ -196,7 +180,6 @@ int main(int argc, char *argv[]) sha256_tests(); sha512_tests(); misc_tests(); - hash_algorithm_name_tests(); free(long_msg); |