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 <jwerner@chromium.org>
Change-Id: I719b2499992a6e4395a29231bc8b9a7680c5b174
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2099447
Reviewed-by: Joel Kitching <kitching@chromium.org>
Commit-Queue: Joel Kitching <kitching@chromium.org>
This commit is contained in:
Julius Werner 2020-03-10 23:27:10 -07:00 committed by Commit Bot
parent 509a887c5a
commit b1c6ef3892
18 changed files with 460 additions and 353 deletions

View File

@ -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

202
firmware/2lib/2crypto.c Normal file
View File

@ -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;
}

View File

@ -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) {

View File

@ -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)

View File

@ -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_ */

View File

@ -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
*

View File

@ -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 <alg> is invalid.
*/
const char *vb2_get_hash_algorithm_name(enum vb2_hash_algorithm alg);
/**
* Initialize a digest context for doing block-style digesting.
*

View File

@ -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"

View File

@ -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"

View File

@ -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_ */

View File

@ -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;

View File

@ -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 */

44
host/lib/crypto.c Normal file
View File

@ -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);
}

View File

@ -14,6 +14,7 @@
#include "host_misc.h"
#include "host_signature.h"
#include "vboot_api.h"
#include "vboot_host.h"
#include "vboot_struct.h"
/**

View File

@ -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)

View File

@ -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.
*

104
tests/vb2_crypto_tests.c Normal file
View File

@ -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;
}

View File

@ -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);