From b1c6ef3892c4e36a1375249ce4494959d2457011 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Tue, 10 Mar 2020 23:27:10 -0700 Subject: Rewrite algorithm type parsers and make them globally available There is some code strewn around between futility and the vb21-specific part of hostlib to allow parsing of textual algorithm names to vboot enums, but it is somewhat disorganized and not written in a super efficient way. This patch rewrites it and centralizes all the algorithm mapping stuff under 2crypto.c so it can be a single source of truth for all of vboot. (String parsing routines still need to stay in hostlib since not all firmware targets support things like stroul() and strcasecmp().) BRANCH=None BUG=None TEST=make runtests Signed-off-by: Julius Werner Change-Id: I719b2499992a6e4395a29231bc8b9a7680c5b174 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2099447 Reviewed-by: Joel Kitching Commit-Queue: Joel Kitching --- firmware/2lib/2crypto.c | 202 ++++++++++++++++++++++++++++++++++++++++ firmware/2lib/2rsa.c | 39 -------- firmware/2lib/2sha_utility.c | 67 ------------- firmware/2lib/include/2crypto.h | 63 ++++++++++++- firmware/2lib/include/2rsa.h | 11 --- firmware/2lib/include/2sha.h | 20 ---- 6 files changed, 264 insertions(+), 138 deletions(-) create mode 100644 firmware/2lib/2crypto.c (limited to 'firmware') 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 +#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 @@ -25,17 +25,6 @@ struct vb2_public_key { const struct vb2_id *id; /* Key ID */ }; -/** - * 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 * 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 @@ -174,17 +174,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. * @@ -201,15 +190,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 is invalid. - */ -const char *vb2_get_hash_algorithm_name(enum vb2_hash_algorithm alg); - /** * Initialize a digest context for doing block-style digesting. * -- cgit v1.2.1