vboot: Remove vboot1 cryptolib padding source

The old vboot1 cryptolib hard-coded many of its padding arrays in a
padding.c file.  Use the equivalent vboot2 apis instead.

This change is almost exclusively on the host and test side; the only
firmware impact is on a single line of debug output.

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

Change-Id: If689ffd92f0255847bea2424950da4547b2c0df3
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/400902
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
This commit is contained in:
Randall Spangler
2016-10-18 12:00:07 -07:00
parent a03a164a76
commit 46a382d613
27 changed files with 201 additions and 631 deletions

View File

@@ -323,7 +323,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/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 \

View File

@@ -8,7 +8,6 @@
#ifndef VBOOT_REFERENCE_CRYPTOLIB_H_ #ifndef VBOOT_REFERENCE_CRYPTOLIB_H_
#define VBOOT_REFERENCE_CRYPTOLIB_H_ #define VBOOT_REFERENCE_CRYPTOLIB_H_
#include "padding.h"
#include "rsa.h" #include "rsa.h"
#endif /* VBOOT_REFERENCE_CRYPTOLIB_H_ */ #endif /* VBOOT_REFERENCE_CRYPTOLIB_H_ */

View File

@@ -1,37 +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_PADDING_H_
#define VBOOT_REFERENCE_PADDING_H_
#ifndef VBOOT_REFERENCE_CRYPTOLIB_H_
#error "Do not include this file directly. Use cryptolib.h instead."
#endif
#include "sysincludes.h"
extern const uint8_t paddingRSA1024_SHA1[];
extern const uint8_t paddingRSA1024_SHA256[];
extern const uint8_t paddingRSA1024_SHA512[];
extern const uint8_t paddingRSA2048_SHA1[];
extern const uint8_t paddingRSA2048_SHA256[];
extern const uint8_t paddingRSA2048_SHA512[];
extern const uint8_t paddingRSA4096_SHA1[];
extern const uint8_t paddingRSA4096_SHA256[];
extern const uint8_t paddingRSA4096_SHA512[];
extern const uint8_t paddingRSA8192_SHA1[];
extern const uint8_t paddingRSA8192_SHA256[];
extern const uint8_t paddingRSA8192_SHA512[];
extern const int kNumAlgorithms;
extern const int digestinfo_size_map[];
extern const int siglen_map[];
extern const uint8_t* const padding_map[];
extern const int padding_size_map[];
extern const uint8_t* const hash_digestinfo_map[];
extern const char* const algo_strings[];
#endif /* VBOOT_REFERENCE_PADDING_H_ */

View File

@@ -17,9 +17,4 @@
#define RSA4096NUMBYTES 512 /* 4096 bit key length */ #define RSA4096NUMBYTES 512 /* 4096 bit key length */
#define RSA8192NUMBYTES 1024 /* 8192 bit key length */ #define RSA8192NUMBYTES 1024 /* 8192 bit key length */
#define RSA1024NUMWORDS (RSA1024NUMBYTES / sizeof(uint32_t))
#define RSA2048NUMWORDS (RSA2048NUMBYTES / sizeof(uint32_t))
#define RSA4096NUMWORDS (RSA4096NUMBYTES / sizeof(uint32_t))
#define RSA8192NUMWORDS (RSA8192NUMBYTES / sizeof(uint32_t))
#endif /* VBOOT_REFERENCE_RSA_H_ */ #endif /* VBOOT_REFERENCE_RSA_H_ */

File diff suppressed because one or more lines are too long

View File

@@ -10,6 +10,7 @@
#include "2sysincludes.h" #include "2sysincludes.h"
#include "2common.h" #include "2common.h"
#include "2rsa.h"
#include "2sha.h" #include "2sha.h"
#include "vboot_api.h" #include "vboot_api.h"
#include "vboot_common.h" #include "vboot_common.h"
@@ -107,7 +108,7 @@ void PublicKeyInit(VbPublicKey *key, uint8_t *key_data, uint64_t key_size)
{ {
key->key_offset = OffsetOf(key, key_data); key->key_offset = OffsetOf(key, key_data);
key->key_size = key_size; key->key_size = key_size;
key->algorithm = kNumAlgorithms; /* Key not present yet */ key->algorithm = VB2_ALG_COUNT; /* Key not present yet */
key->key_version = 0; key->key_version = 0;
} }
@@ -190,7 +191,8 @@ int VbSharedDataSetKernelKey(VbSharedDataHeader *header, const VbPublicKey *src)
kdest = &header->kernel_subkey; kdest = &header->kernel_subkey;
VBDEBUG(("Saving kernel subkey to shared data: size %d, algo %d\n", VBDEBUG(("Saving kernel subkey to shared data: size %d, algo %d\n",
siglen_map[src->algorithm], (int)src->algorithm)); vb2_rsa_sig_size(vb2_crypto_to_signature(src->algorithm)),
(int)src->algorithm));
/* Attempt to allocate space for key, if it hasn't been allocated yet */ /* Attempt to allocate space for key, if it hasn't been allocated yet */
if (!header->kernel_subkey_data_offset) { if (!header->kernel_subkey_data_offset) {

View File

@@ -49,7 +49,7 @@ void show_pubkey(const struct vb2_packed_key *pubkey, const char *sp)
{ {
printf("%sVboot API: 1.0\n", sp); printf("%sVboot API: 1.0\n", sp);
printf("%sAlgorithm: %d %s\n", sp, pubkey->algorithm, printf("%sAlgorithm: %d %s\n", sp, pubkey->algorithm,
vb1_crypto_name(pubkey->algorithm)); vb2_get_crypto_algorithm_name(pubkey->algorithm));
printf("%sKey Version: %d\n", sp, pubkey->key_version); printf("%sKey Version: %d\n", sp, pubkey->key_version);
printf("%sKey sha1sum: %s\n", printf("%sKey sha1sum: %s\n",
sp, packed_key_sha1_string(pubkey)); sp, packed_key_sha1_string(pubkey));
@@ -78,7 +78,7 @@ static void show_keyblock(struct vb2_keyblock *keyblock, const char *name,
struct vb2_packed_key *data_key = &keyblock->data_key; struct vb2_packed_key *data_key = &keyblock->data_key;
printf(" Data key algorithm: %d %s\n", data_key->algorithm, printf(" Data key algorithm: %d %s\n", data_key->algorithm,
vb1_crypto_name(data_key->algorithm)); vb2_get_crypto_algorithm_name(data_key->algorithm));
printf(" Data key version: %d\n", data_key->key_version); printf(" Data key version: %d\n", data_key->key_version);
printf(" Data key sha1sum: %s\n", printf(" Data key sha1sum: %s\n",
packed_key_sha1_string(data_key)); packed_key_sha1_string(data_key));
@@ -116,7 +116,7 @@ int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data)
printf("Private Key file: %s\n", name); printf("Private Key file: %s\n", name);
printf(" Vboot API: 1.0\n"); printf(" Vboot API: 1.0\n");
printf(" Algorithm: %u %s\n", pkey->algorithm, printf(" Algorithm: %u %s\n", pkey->algorithm,
vb1_crypto_name(pkey->algorithm)); vb2_get_crypto_algorithm_name(pkey->algorithm));
printf(" Key sha1sum: %s\n", printf(" Key sha1sum: %s\n",
private_key_sha1_string(&key)); private_key_sha1_string(&key));
@@ -230,8 +230,8 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey; struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey;
printf(" Kernel key algorithm: %d %s\n", printf(" Kernel key algorithm: %d %s\n",
kernel_subkey->algorithm, kernel_subkey->algorithm,
vb1_crypto_name(kernel_subkey->algorithm)); vb2_get_crypto_algorithm_name(kernel_subkey->algorithm));
if (kernel_subkey->algorithm >= kNumAlgorithms) if (kernel_subkey->algorithm >= VB2_ALG_COUNT)
retval = 1; retval = 1;
printf(" Kernel key version: %d\n", kernel_subkey->key_version); printf(" Kernel key version: %d\n", kernel_subkey->key_version);
printf(" Kernel key sha1sum: %s\n", printf(" Kernel key sha1sum: %s\n",

View File

@@ -309,7 +309,7 @@ static const char usage_pubkey[] = "\n"
"\n"; "\n";
static void print_help_pubkey(int argc, char *argv[]) static void print_help_pubkey(int argc, char *argv[])
{ {
printf(usage_pubkey, kNumAlgorithms - 1); printf(usage_pubkey, VB2_ALG_COUNT - 1);
} }
@@ -800,7 +800,7 @@ static int do_sign(int argc, char *argv[])
sign_option.pem_algo_specified = 1; sign_option.pem_algo_specified = 1;
sign_option.pem_algo = strtoul(optarg, &e, 0); sign_option.pem_algo = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e) || if (!*optarg || (e && *e) ||
(sign_option.pem_algo >= kNumAlgorithms)) { (sign_option.pem_algo >= VB2_ALG_COUNT)) {
fprintf(stderr, fprintf(stderr,
"Invalid --pem_algo \"%s\"\n", optarg); "Invalid --pem_algo \"%s\"\n", optarg);
errorcnt++; errorcnt++;

View File

@@ -248,7 +248,7 @@ static int do_verify(const char *infile, const char *signpubkey,
struct vb2_packed_key *packed_key = &keyblock->data_key; struct vb2_packed_key *packed_key = &keyblock->data_key;
printf(" Data key algorithm: %d %s\n", packed_key->algorithm, printf(" Data key algorithm: %d %s\n", packed_key->algorithm,
vb1_crypto_name(packed_key->algorithm)); vb2_get_crypto_algorithm_name(packed_key->algorithm));
printf(" Data key version: %d\n", packed_key->key_version); printf(" Data key version: %d\n", packed_key->key_version);
printf(" Data key sha1sum: %s\n", printf(" Data key sha1sum: %s\n",
packed_key_sha1_string(packed_key)); packed_key_sha1_string(packed_key));
@@ -283,7 +283,7 @@ static int do_verify(const char *infile, const char *signpubkey,
struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey; struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey;
printf(" Kernel key algorithm: %d %s\n", kernel_subkey->algorithm, printf(" Kernel key algorithm: %d %s\n", kernel_subkey->algorithm,
vb1_crypto_name(kernel_subkey->algorithm)); vb2_get_crypto_algorithm_name(kernel_subkey->algorithm));
printf(" Kernel key version: %d\n", kernel_subkey->key_version); printf(" Kernel key version: %d\n", kernel_subkey->key_version);
printf(" Kernel key sha1sum: %s\n", printf(" Kernel key sha1sum: %s\n",
packed_key_sha1_string(kernel_subkey)); packed_key_sha1_string(kernel_subkey));

View File

@@ -59,9 +59,9 @@ static void print_help(int argc, char *argv[])
" --algorithm <number> " " --algorithm <number> "
"Signing algorithm to use with key:\n", argv[0]); "Signing algorithm to use with key:\n", argv[0]);
for (i = 0; i < kNumAlgorithms; i++) { for (i = 0; i < VB2_ALG_COUNT; i++) {
printf(" %d = (%s)\n", printf(" %d = (%s)\n",
i, vb1_crypto_name(i)); i, vb2_get_crypto_algorithm_name(i));
} }
printf("\nOR\n\n" printf("\nOR\n\n"
@@ -123,7 +123,7 @@ static int do_unpack(const char *infile, const char *outfile)
if (pubkey) { if (pubkey) {
printf("Public Key file: %s\n", infile); printf("Public Key file: %s\n", infile);
printf("Algorithm: %u %s\n", pubkey->algorithm, printf("Algorithm: %u %s\n", pubkey->algorithm,
vb1_crypto_name(pubkey->algorithm)); vb2_get_crypto_algorithm_name(pubkey->algorithm));
printf("Key Version: %u\n", pubkey->key_version); printf("Key Version: %u\n", pubkey->key_version);
printf("Key sha1sum: %s\n", printf("Key sha1sum: %s\n",
packed_key_sha1_string(pubkey)); packed_key_sha1_string(pubkey));
@@ -144,7 +144,8 @@ static int do_unpack(const char *infile, const char *outfile)
enum vb2_crypto_algorithm alg = enum vb2_crypto_algorithm alg =
vb2_get_crypto_algorithm(privkey->hash_alg, vb2_get_crypto_algorithm(privkey->hash_alg,
privkey->sig_alg); privkey->sig_alg);
printf("Algorithm: %u %s\n", alg, vb1_crypto_name(alg)); printf("Algorithm: %u %s\n", alg,
vb2_get_crypto_algorithm_name(alg));
if (outfile && if (outfile &&
VB2_SUCCESS != vb2_write_private_key(outfile, privkey)) { VB2_SUCCESS != vb2_write_private_key(outfile, privkey)) {
fprintf(stderr,"vbutil_key: Error writing key copy\n"); fprintf(stderr,"vbutil_key: Error writing key copy\n");

View File

@@ -17,6 +17,7 @@
#include "cryptolib.h" #include "cryptolib.h"
#include "futility.h" #include "futility.h"
#include "host_common.h" #include "host_common.h"
#include "host_key2.h"
#include "util_misc.h" #include "util_misc.h"
#include "vb1_helper.h" #include "vb1_helper.h"
#include "vb2_common.h" #include "vb2_common.h"
@@ -110,7 +111,7 @@ static int Pack(const char *outfile, const char *datapubkey,
} }
if (signprivate_pem) { if (signprivate_pem) {
if (pem_algorithm >= kNumAlgorithms) { if (pem_algorithm >= VB2_ALG_COUNT) {
fprintf(stderr, fprintf(stderr,
"vbutil_keyblock: Invalid --pem_algorithm %" "vbutil_keyblock: Invalid --pem_algorithm %"
PRIu64 "\n", pem_algorithm); PRIu64 "\n", pem_algorithm);
@@ -222,7 +223,7 @@ static int Unpack(const char *infile, const char *datapubkey,
struct vb2_packed_key *data_key = &block->data_key; struct vb2_packed_key *data_key = &block->data_key;
printf("Data key algorithm: %u %s\n", data_key->algorithm, printf("Data key algorithm: %u %s\n", data_key->algorithm,
vb1_crypto_name(data_key->algorithm)); vb2_get_crypto_algorithm_name(data_key->algorithm));
printf("Data key version: %u\n", data_key->key_version); printf("Data key version: %u\n", data_key->key_version);
printf("Data key sha1sum: %s\n", printf("Data key sha1sum: %s\n",
packed_key_sha1_string(data_key)); packed_key_sha1_string(data_key));

View File

@@ -24,11 +24,6 @@
#include "vb1_helper.h" #include "vb1_helper.h"
#include "vb2_common.h" #include "vb2_common.h"
const char *vb1_crypto_name(uint32_t algo)
{
return algo < kNumAlgorithms ? algo_strings[algo] : "(invalid)";
}
/****************************************************************************/ /****************************************************************************/
/* Here are globals containing all the bits & pieces I'm working on. /* Here are globals containing all the bits & pieces I'm working on.
* *
@@ -544,8 +539,7 @@ int VerifyKernelBlob(uint8_t *kernel_blob,
printf(" REC"); printf(" REC");
printf("\n"); printf("\n");
printf(" Data key algorithm: %u %s\n", data_key->algorithm, printf(" Data key algorithm: %u %s\n", data_key->algorithm,
(data_key->algorithm < kNumAlgorithms ? vb2_get_crypto_algorithm_name(data_key->algorithm));
algo_strings[data_key->algorithm] : "(invalid)"));
printf(" Data key version: %u\n", data_key->key_version); printf(" Data key version: %u\n", data_key->key_version);
printf(" Data key sha1sum: %s\n", printf(" Data key sha1sum: %s\n",
packed_key_sha1_string(data_key)); packed_key_sha1_string(data_key));

View File

@@ -10,14 +10,6 @@ struct vb2_kernel_preamble;
struct vb2_keyblock; struct vb2_keyblock;
struct vb2_packed_key; struct vb2_packed_key;
/**
* Return the name of the vb1 crypto algorithm
*
* @param algo Crypto algorithm
* @return The name of the algorithm, or "(invalid)" if algo is not valid.
*/
const char *vb1_crypto_name(uint32_t algo);
/* Display a public key with variable indentation */ /* Display a public key with variable indentation */
void show_pubkey(const struct vb2_packed_key *pubkey, const char *sp); void show_pubkey(const struct vb2_packed_key *pubkey, const char *sp);

View File

@@ -16,6 +16,7 @@
#include "cryptolib.h" #include "cryptolib.h"
#include "host_key.h" #include "host_key.h"
#include "host_key2.h"
#include "host_keyblock.h" #include "host_keyblock.h"
#include "host_misc.h" #include "host_misc.h"
#include "host_signature.h" #include "host_signature.h"

View File

@@ -11,7 +11,7 @@
/* Returns a buffer with DigestInfo (which depends on [algorithm]) /* Returns a buffer with DigestInfo (which depends on [algorithm])
* prepended to [digest]. * prepended to [digest].
*/ */
uint8_t* PrependDigestInfo(unsigned int algorithm, uint8_t* digest); uint8_t* PrependDigestInfo(enum vb2_hash_algorithm hash_alg, uint8_t* digest);
/* Function that outputs the message digest of the contents of a buffer in a /* Function that outputs the message digest of the contents of a buffer in a
* format that can be used as input to OpenSSL for an RSA signature. * format that can be used as input to OpenSSL for an RSA signature.

View File

@@ -12,16 +12,23 @@
#include "2sysincludes.h" #include "2sysincludes.h"
#include "2common.h" #include "2common.h"
#include "2rsa.h"
#include "2sha.h" #include "2sha.h"
#include "cryptolib.h" #include "cryptolib.h"
#include "host_common.h" #include "host_common.h"
#include "host_signature2.h"
#include "signature_digest.h" #include "signature_digest.h"
uint8_t* PrependDigestInfo(unsigned int algorithm, uint8_t* digest) uint8_t* PrependDigestInfo(enum vb2_hash_algorithm hash_alg, uint8_t* digest)
{ {
const int digest_size = vb2_digest_size(vb2_crypto_to_hash(algorithm)); const int digest_size = vb2_digest_size(hash_alg);
const int digestinfo_size = digestinfo_size_map[algorithm]; uint32_t digestinfo_size = 0;
const uint8_t* digestinfo = hash_digestinfo_map[algorithm]; const uint8_t* digestinfo = NULL;
if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
&digestinfo_size))
return NULL;
uint8_t* p = malloc(digestinfo_size + digest_size); uint8_t* p = malloc(digestinfo_size + digest_size);
memcpy(p, digestinfo, digestinfo_size); memcpy(p, digestinfo, digestinfo_size);
memcpy(p + digestinfo_size, digest, digest_size); memcpy(p + digestinfo_size, digest, digest_size);
@@ -35,7 +42,7 @@ uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */ uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */
if (algorithm >= kNumAlgorithms) { if (algorithm >= VB2_ALG_COUNT) {
VBDEBUG(("SignatureDigest() called with invalid algorithm!\n")); VBDEBUG(("SignatureDigest() called with invalid algorithm!\n"));
} else if (VB2_SUCCESS == } else if (VB2_SUCCESS ==
vb2_digest_buffer(buf, len, vb2_crypto_to_hash(algorithm), vb2_digest_buffer(buf, len, vb2_crypto_to_hash(algorithm),
@@ -48,12 +55,29 @@ uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file, uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
unsigned int algorithm) unsigned int algorithm)
{ {
const enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(algorithm);
FILE* key_fp = NULL; FILE* key_fp = NULL;
RSA* key = NULL; RSA* key = NULL;
uint8_t* signature = NULL; uint8_t* signature = NULL;
uint8_t* signature_digest = SignatureDigest(buf, len, algorithm); uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
const int digest_size = vb2_digest_size(vb2_crypto_to_hash(algorithm)); if (!signature_digest) {
int signature_digest_len = digest_size + digestinfo_size_map[algorithm]; VBDEBUG(("SignatureBuf(): Couldn't get signature digest\n"));
return NULL;
}
const int digest_size = vb2_digest_size(hash_alg);
uint32_t digestinfo_size = 0;
const uint8_t* digestinfo = NULL;
if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
&digestinfo_size)) {
VBDEBUG(("SignatureBuf(): Couldn't get digest info\n"));
free(signature_digest);
return NULL;
}
int signature_digest_len = digest_size + digestinfo_size;
key_fp = fopen(key_file, "r"); key_fp = fopen(key_file, "r");
if (!key_fp) { if (!key_fp) {
VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n", VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n",
@@ -62,7 +86,8 @@ uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
return NULL; return NULL;
} }
if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL))) if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
signature = (uint8_t*) malloc(siglen_map[algorithm]); signature = (uint8_t *)malloc(
vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm)));
else else
VBDEBUG(("SignatureBuf(): Couldn't read private key from: %s\n", VBDEBUG(("SignatureBuf(): Couldn't read private key from: %s\n",
key_file)); key_file));

View File

@@ -33,6 +33,22 @@ const struct vb2_text_vs_enum vb2_text_vs_hash[] = {
{0, 0} {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},
{0, 0}
};
const struct vb2_text_vs_enum *vb2_lookup_by_num( const struct vb2_text_vs_enum *vb2_lookup_by_num(
const struct vb2_text_vs_enum *table, const struct vb2_text_vs_enum *table,
const unsigned int num) const unsigned int num)
@@ -61,6 +77,14 @@ const char *vb2_get_sig_algorithm_name(enum vb2_signature_algorithm sig_alg)
return entry ? entry->name : VB2_INVALID_ALG_NAME; 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;
}
void vb2_private_key_free(struct vb2_private_key *key) void vb2_private_key_free(struct vb2_private_key *key)
{ {
if (!key) if (!key)

View File

@@ -66,6 +66,14 @@ extern const struct vb2_text_vs_enum vb2_text_vs_hash[];
*/ */
const char *vb2_get_sig_algorithm_name(enum vb2_signature_algorithm sig_alg); 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);
/** /**
* Free a private key. * Free a private key.
* *

View File

@@ -1,235 +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.
# Script to generate padding.c containing PKCS 1.5 padding byte arrays for
# various combinations of RSA key lengths and message digest algorithms.
Pad_Preamble="0x00,0x01"
SHA1_digestinfo="0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05"\
",0x00,0x04,0x14"
SHA256_digestinfo="0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03"\
",0x04,0x02,0x01,0x05,0x00,0x04,0x20"
SHA512_digestinfo="0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03"\
",0x04,0x02,0x03,0x05,0x00,0x04,0x40"
RSA1024_Len=128
RSA2048_Len=256
RSA4096_Len=512
RSA8192_Len=1024
SHA1_T_Len=35
SHA256_T_Len=51
SHA512_T_Len=83
HashAlgos=( SHA1 SHA256 SHA512 )
RSAAlgos=( RSA1024 RSA2048 RSA4096 RSA8192 )
function genFFOctets {
count=$1
while [ $count -gt 0 ]; do
echo -n "0xff,"
let count=count-1
done
}
cat <<EOF
/*
* DO NOT MODIFY THIS FILE DIRECTLY.
*
* This file is automatically generated by genpadding.sh and contains padding
* arrays corresponding to various combinations of algorithms for RSA signatures.
*/
EOF
echo '#include "cryptolib.h"'
echo
echo
cat <<EOF
/*
* PKCS 1.5 padding (from the RSA PKCS#1 v2.1 standard)
*
* Depending on the RSA key size and hash function, the padding is calculated
* as follows:
*
* 0x00 || 0x01 || PS || 0x00 || T
*
* T: DER Encoded DigestInfo value which depends on the hash function used.
*
* SHA-1: (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.
* SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H.
* SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H.
*
* Length(T) = 35 octets for SHA-1
* Length(T) = 51 octets for SHA-256
* Length(T) = 83 octets for SHA-512
*
* PS: octet string consisting of {Length(RSA Key) - Length(T) - 3} 0xFF
*
*/
EOF
echo
echo
# Generate padding arrays.
algorithmcounter=0
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo "/* Algorithm Type $algorithmcounter */"
let algorithmcounter=algorithmcounter+1
eval rsalen=${rsaalgo}_Len
eval hashlen=${hashalgo}_T_Len
let nums=rsalen-hashlen-3
echo "const uint8_t padding${rsaalgo}_${hashalgo}[${rsaalgo}NUMBYTES - ${hashalgo}_DIGEST_SIZE] = {"
echo -n $Pad_Preamble,
genFFOctets $nums
echo -n "0x00,"
eval digestinfo=\$${hashalgo}_digestinfo
echo $digestinfo
echo "};"
echo
done
done
echo "const int kNumAlgorithms = $algorithmcounter;";
echo "#define NUMALGORITHMS $algorithmcounter"
echo
# Output DigestInfo field lengths.
cat <<EOF
#define SHA1_DIGESTINFO_LEN 15
#define SHA256_DIGESTINFO_LEN 19
#define SHA512_DIGESTINFO_LEN 19
EOF
# Generate DigestInfo arrays.
for hashalgo in ${HashAlgos[@]}
do
echo "const uint8_t ${hashalgo}_digestinfo[] = {"
eval digestinfo=\$${hashalgo}_digestinfo
echo $digestinfo
echo "};"
echo
done
# Generate DigestInfo to size map.
echo "const int digestinfo_size_map[] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo ${hashalgo}_DIGESTINFO_LEN,
done
done
echo "};"
echo
# Generate algorithm signature length map.
echo "const int siglen_map[NUMALGORITHMS] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo ${rsaalgo}NUMBYTES,
done
done
echo "};"
echo
# Generate algorithm padding array map.
echo "const uint8_t* padding_map[NUMALGORITHMS] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo padding${rsaalgo}_${hashalgo},
done
done
echo "};"
echo
# Generate algorithm padding size map.
echo "const int padding_size_map[NUMALGORITHMS] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo ${rsaalgo}NUMBYTES - ${hashalgo}_DIGEST_SIZE,
done
done
echo "};"
echo
# Generate signature algorithm to messge digest algorithm map.
echo "const int hash_type_map[] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo ${hashalgo}_DIGEST_ALGORITHM,
done
done
echo "};"
echo
# Generate algorithm to message digest's output size map.
echo "const int hash_size_map[NUMALGORITHMS] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo ${hashalgo}_DIGEST_SIZE,
done
done
echo "};"
echo
# Generate algorithm to message digest's input block size map.
echo "const int hash_blocksize_map[NUMALGORITHMS] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo ${hashalgo}_BLOCK_SIZE,
done
done
echo "};"
echo
# Generate algorithm to message's digest ASN.1 DigestInfo map.
echo "const uint8_t* hash_digestinfo_map[NUMALGORITHMS] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo ${hashalgo}_digestinfo,
done
done
echo "};"
echo
# Generate algorithm description strings.
echo "const char* algo_strings[NUMALGORITHMS] = {"
for rsaalgo in ${RSAAlgos[@]}
do
for hashalgo in ${HashAlgos[@]}
do
echo \"${rsaalgo} ${hashalgo}\",
done
done
echo "};"
echo
#echo "#endif /* VBOOT_REFERENCE_PADDING_H_ */"

View File

@@ -13,6 +13,7 @@
#include "2rsa.h" #include "2rsa.h"
#include "file_keys.h" #include "file_keys.h"
#include "host_common.h" #include "host_common.h"
#include "host_key2.h"
#include "vb2_common.h" #include "vb2_common.h"
#include "vboot_common.h" #include "vboot_common.h"
#include "test_common.h" #include "test_common.h"
@@ -138,7 +139,8 @@ static void test_verify_data(const struct vb2_packed_key *key1,
int test_algorithm(int key_algorithm, const char *keys_dir) int test_algorithm(int key_algorithm, const char *keys_dir)
{ {
char filename[1024]; char filename[1024];
int rsa_len = siglen_map[key_algorithm] * 8; int rsa_bits = 8 * vb2_rsa_sig_size(
vb2_crypto_to_signature(key_algorithm));
struct vb2_private_key *private_key = NULL; struct vb2_private_key *private_key = NULL;
struct vb2_signature *sig = NULL; struct vb2_signature *sig = NULL;
@@ -146,10 +148,11 @@ int test_algorithm(int key_algorithm, const char *keys_dir)
int retval = 1; int retval = 1;
printf("***Testing algorithm: %s\n", algo_strings[key_algorithm]); printf("***Testing algorithm: %s\n",
vb2_get_crypto_algorithm_name(key_algorithm));
snprintf(filename, sizeof(filename), snprintf(filename, sizeof(filename),
"%s/key_rsa%d.pem", keys_dir, rsa_len); "%s/key_rsa%d.pem", keys_dir, rsa_bits);
private_key = vb2_read_private_key_pem(filename, key_algorithm); private_key = vb2_read_private_key_pem(filename, key_algorithm);
if (!private_key) { if (!private_key) {
fprintf(stderr, "Error reading private_key: %s\n", filename); fprintf(stderr, "Error reading private_key: %s\n", filename);
@@ -157,7 +160,7 @@ int test_algorithm(int key_algorithm, const char *keys_dir)
} }
snprintf(filename, sizeof(filename), snprintf(filename, sizeof(filename),
"%s/key_rsa%d.keyb", keys_dir, rsa_len); "%s/key_rsa%d.keyb", keys_dir, rsa_bits);
key1 = vb2_read_packed_keyb(filename, key_algorithm, 1); key1 = vb2_read_packed_keyb(filename, key_algorithm, 1);
if (!key1) { if (!key1) {
fprintf(stderr, "Error reading public_key: %s\n", filename); fprintf(stderr, "Error reading public_key: %s\n", filename);
@@ -208,7 +211,7 @@ int main(int argc, char *argv[]) {
/* Test all the algorithms */ /* Test all the algorithms */
int alg; int alg;
for (alg = 0; alg < kNumAlgorithms; alg++) { for (alg = 0; alg < VB2_ALG_COUNT; alg++) {
if (test_algorithm(alg, argv[1])) if (test_algorithm(alg, argv[1]))
return 1; return 1;
} }

View File

@@ -515,8 +515,10 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
const char *keys_dir) const char *keys_dir)
{ {
char filename[1024]; char filename[1024];
int signing_rsa_len = siglen_map[signing_key_algorithm] * 8; int signing_rsa_len = 8 * vb2_rsa_sig_size(
int data_rsa_len = siglen_map[data_key_algorithm] * 8; vb2_crypto_to_signature(signing_key_algorithm));
int data_rsa_len = 8 * vb2_rsa_sig_size(
vb2_crypto_to_signature(data_key_algorithm));
int retval = 1; int retval = 1;
struct vb2_private_key *signing_private_key = NULL; struct vb2_private_key *signing_private_key = NULL;
@@ -524,9 +526,9 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
struct vb2_packed_key *data_public_key = NULL; struct vb2_packed_key *data_public_key = NULL;
printf("***Testing signing algorithm: %s\n", printf("***Testing signing algorithm: %s\n",
algo_strings[signing_key_algorithm]); vb2_get_crypto_algorithm_name(signing_key_algorithm));
printf("***With data key algorithm: %s\n", printf("***With data key algorithm: %s\n",
algo_strings[data_key_algorithm]); vb2_get_crypto_algorithm_name(data_key_algorithm));
snprintf(filename, sizeof(filename), snprintf(filename, sizeof(filename),
"%s/key_rsa%d.pem", keys_dir, signing_rsa_len); "%s/key_rsa%d.pem", keys_dir, signing_rsa_len);

View File

@@ -239,7 +239,8 @@ static void test_verify_data(const struct vb2_public_key *pubk_orig,
int test_algorithm(int key_algorithm, const char *keys_dir) int test_algorithm(int key_algorithm, const char *keys_dir)
{ {
char filename[1024]; char filename[1024];
int rsa_len = siglen_map[key_algorithm] * 8; int rsa_bits = 8 * vb2_rsa_sig_size(
vb2_crypto_to_signature(key_algorithm));
enum vb2_signature_algorithm sig_alg = enum vb2_signature_algorithm sig_alg =
vb2_crypto_to_signature(key_algorithm); vb2_crypto_to_signature(key_algorithm);
@@ -250,10 +251,11 @@ int test_algorithm(int key_algorithm, const char *keys_dir)
struct vb2_public_key *pubk = NULL; struct vb2_public_key *pubk = NULL;
struct vb21_packed_key *key2 = NULL; struct vb21_packed_key *key2 = NULL;
printf("***Testing algorithm: %s\n", algo_strings[key_algorithm]); printf("***Testing algorithm: %s\n",
vb2_get_crypto_algorithm_name(key_algorithm));
snprintf(filename, sizeof(filename), snprintf(filename, sizeof(filename),
"%s/key_rsa%d.pem", keys_dir, rsa_len); "%s/key_rsa%d.pem", keys_dir, rsa_bits);
TEST_SUCC(vb2_private_key_read_pem(&prik, filename), TEST_SUCC(vb2_private_key_read_pem(&prik, filename),
"Read private key"); "Read private key");
prik->hash_alg = hash_alg; prik->hash_alg = hash_alg;
@@ -261,7 +263,7 @@ int test_algorithm(int key_algorithm, const char *keys_dir)
vb2_private_key_set_desc(prik, "private key"); vb2_private_key_set_desc(prik, "private key");
snprintf(filename, sizeof(filename), snprintf(filename, sizeof(filename),
"%s/key_rsa%d.keyb", keys_dir, rsa_len); "%s/key_rsa%d.keyb", keys_dir, rsa_bits);
TEST_SUCC(vb2_public_key_read_keyb(&pubk, filename), TEST_SUCC(vb2_public_key_read_keyb(&pubk, filename),
"Read public key"); "Read public key");
pubk->hash_alg = hash_alg; pubk->hash_alg = hash_alg;
@@ -305,7 +307,7 @@ int main(int argc, char *argv[]) {
/* Test all the algorithms */ /* Test all the algorithms */
int alg; int alg;
for (alg = 0; alg < kNumAlgorithms; alg++) { for (alg = 0; alg < VB2_ALG_COUNT; alg++) {
if (test_algorithm(alg, argv[1])) if (test_algorithm(alg, argv[1]))
return 1; return 1;
} }

View File

@@ -40,7 +40,7 @@ static void test_utils(void)
.hash_alg = VB2_HASH_INVALID}; .hash_alg = VB2_HASH_INVALID};
/* Verify old and new algorithm count constants match */ /* Verify old and new algorithm count constants match */
TEST_EQ(kNumAlgorithms, VB2_ALG_COUNT, "Algorithm counts"); TEST_EQ(VB2_ALG_COUNT, VB2_ALG_COUNT, "Algorithm counts");
/* Crypto algorithm to sig algorithm mapping */ /* Crypto algorithm to sig algorithm mapping */
TEST_EQ(vb2_crypto_to_signature(VB2_ALG_RSA1024_SHA1), TEST_EQ(vb2_crypto_to_signature(VB2_ALG_RSA1024_SHA1),

View File

@@ -9,6 +9,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "host_common.h"
#include "test_common.h" #include "test_common.h"
#include "utility.h" #include "utility.h"
#include "vboot_common.h" #include "vboot_common.h"
@@ -154,7 +155,7 @@ static void PublicKeyTest(void)
PublicKeyInit(k, (uint8_t*)(k + 1), 2 * sizeof(VbPublicKey)); PublicKeyInit(k, (uint8_t*)(k + 1), 2 * sizeof(VbPublicKey));
TEST_EQ(k->key_offset, sizeof(VbPublicKey), "PublicKeyInit key_offset"); TEST_EQ(k->key_offset, sizeof(VbPublicKey), "PublicKeyInit key_offset");
TEST_EQ(k->key_size, 2 * sizeof(VbPublicKey), "PublicKeyInit key_size"); TEST_EQ(k->key_size, 2 * sizeof(VbPublicKey), "PublicKeyInit key_size");
TEST_EQ(k->algorithm, kNumAlgorithms, "PublicKeyInit algorithm"); TEST_EQ(k->algorithm, VB2_ALG_COUNT, "PublicKeyInit algorithm");
TEST_EQ(k->key_version, 0, "PublicKeyInit key_version"); TEST_EQ(k->key_version, 0, "PublicKeyInit key_version");
/* Set algorithm and version, so we can tell if they get copied */ /* Set algorithm and version, so we can tell if they get copied */

View File

@@ -9,56 +9,62 @@
#include <string.h> #include <string.h>
#include "2sysincludes.h" #include "2sysincludes.h"
#include "2common.h" #include "2common.h"
#include "2sha.h" #include "2sha.h"
#include "file_keys.h"
#include "host_common.h" #include "host_common.h"
#include "padding.h" #include "host_signature2.h"
#include "signature_digest.h" #include "signature_digest.h"
static void usage(char* argv[]) { static void usage(char* argv[]) {
fprintf(stderr, fprintf(stderr,
"Usage: %s <alg_id> <digest_file>\n" "Usage: %s <alg_id> <digest_file>\n"
"\n" "\n"
"Generate a padded hash suitable for generating PKCS#1.5 " "Generate a padded hash suitable for generating PKCS#1.5 "
"signatures.\n", "signatures.\n",
basename(argv[0])); basename(argv[0]));
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[])
int algorithm = -1; {
int error_code = 0; int algorithm = -1;
uint8_t* digest = NULL; int error_code = -1;
uint8_t* padded_digest = NULL; uint8_t* digest = NULL;
uint32_t len; uint8_t* padded_digest = NULL;
uint32_t padded_digest_len; uint32_t len;
if (argc != 3) { if (argc != 3) {
usage(argv); usage(argv);
return -1; goto cleanup;
} }
algorithm = atoi(argv[1]); algorithm = atoi(argv[1]);
if (algorithm < 0 || algorithm >= kNumAlgorithms) { if (algorithm < 0 || algorithm >= VB2_ALG_COUNT) {
fprintf(stderr, "Invalid Algorithm!\n"); fprintf(stderr, "Invalid Algorithm!\n");
return -1; goto cleanup;
} }
if (VB2_SUCCESS != vb2_read_file(argv[2], &digest, &len)) { enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(algorithm);
fprintf(stderr, "Could not read file: %s\n", argv[2]); uint32_t digest_size = vb2_digest_size(hash_alg);
return -1; uint32_t digestinfo_size = 0;
} const uint8_t* digestinfo = NULL;
if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
&digestinfo_size)) {
fprintf(stderr, "SignatureBuf(): Couldn't get digest info\n");
goto cleanup;
}
uint32_t padded_digest_len = digest_size + digestinfo_size;
padded_digest = PrependDigestInfo(algorithm, digest); if (VB2_SUCCESS != vb2_read_file(argv[2], &digest, &len)) {
const int digest_size = vb2_digest_size(vb2_crypto_to_hash(algorithm)); fprintf(stderr, "Could not read file: %s\n", argv[2]);
padded_digest_len = (digest_size + digestinfo_size_map[algorithm]); goto cleanup;
}
if (!padded_digest) padded_digest = PrependDigestInfo(hash_alg, digest);
error_code = -1; if(padded_digest &&
if(padded_digest && fwrite(padded_digest, padded_digest_len, 1, stdout) == 1)
1 != fwrite(padded_digest, padded_digest_len, 1, stdout)) error_code = 0;
error_code = -1;
free(padded_digest); cleanup:
free(digest); free(padded_digest);
return error_code; free(digest);
return error_code;
} }

View File

@@ -13,45 +13,49 @@
#include "2sysincludes.h" #include "2sysincludes.h"
#include "2common.h" #include "2common.h"
#include "file_keys.h"
#include "host_common.h" #include "host_common.h"
#include "padding.h" #include "host_signature2.h"
#include "signature_digest.h" #include "signature_digest.h"
int main(int argc, char* argv[])
{
int error_code = -1;
uint8_t *buf = NULL;
uint8_t *signature_digest = NULL;
uint32_t len;
int main(int argc, char* argv[]) { if (argc != 3) {
int algorithm = -1; fprintf(stderr, "Usage: %s <alg_id> <file>", argv[0]);
int error_code = 0; goto cleanup;
uint8_t* buf = NULL; }
uint8_t* signature_digest = NULL;
uint32_t len;
uint32_t signature_digest_len;
if (argc != 3) { int algorithm = atoi(argv[1]);
fprintf(stderr, "Usage: %s <alg_id> <file>", argv[0]); if (algorithm < 0 || algorithm >= VB2_ALG_COUNT) {
return -1; fprintf(stderr, "Invalid Algorithm!\n");
} goto cleanup;
algorithm = atoi(argv[1]); }
if (algorithm < 0 || algorithm >= kNumAlgorithms) {
fprintf(stderr, "Invalid Algorithm!\n");
return -1;
}
if (VB2_SUCCESS != vb2_read_file(argv[2], &buf, &len)) { if (VB2_SUCCESS != vb2_read_file(argv[2], &buf, &len)) {
fprintf(stderr, "Could not read file: %s\n", argv[2]); fprintf(stderr, "Could not read file: %s\n", argv[2]);
return -1; goto cleanup;
} }
signature_digest = SignatureDigest(buf, len, algorithm); enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(algorithm);
const int digest_size = vb2_digest_size(vb2_crypto_to_hash(algorithm)); uint32_t digest_size = vb2_digest_size(hash_alg);
signature_digest_len = (digest_size + digestinfo_size_map[algorithm]); uint32_t digestinfo_size = 0;
if (!signature_digest) const uint8_t *digestinfo = NULL;
error_code = -1; if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
if(signature_digest && &digestinfo_size))
1 != fwrite(signature_digest, signature_digest_len, 1, stdout)) goto cleanup;
error_code = -1;
free(signature_digest); uint32_t signature_digest_len = digest_size + digestinfo_size;
free(buf); signature_digest = SignatureDigest(buf, len, algorithm);
return error_code; if(signature_digest &&
fwrite(signature_digest, signature_digest_len, 1, stdout) == 1)
error_code = 0;
cleanup:
free(signature_digest);
free(buf);
return error_code;
} }

View File

@@ -24,8 +24,7 @@
#include "2rsa.h" #include "2rsa.h"
#include "cryptolib.h" #include "cryptolib.h"
#include "file_keys.h" #include "file_keys.h"
#include "host_key.h" #include "host_common.h"
#include "host_misc.h"
#include "vb2_common.h" #include "vb2_common.h"
/* ANSI Color coding sequences. */ /* ANSI Color coding sequences. */
@@ -83,12 +82,13 @@ int main(int argc, char* argv[])
"where <algorithm> depends on the signature algorithm" "where <algorithm> depends on the signature algorithm"
" used:\n"); " used:\n");
for(i = 0; i < VB2_ALG_COUNT; 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,
vb2_get_crypto_algorithm_name(i));
return -1; return -1;
} }
int algorithm = atoi(argv[1]); int algorithm = atoi(argv[1]);
if (algorithm >= kNumAlgorithms) { if (algorithm >= VB2_ALG_COUNT) {
fprintf(stderr, "Invalid algorithm %d\n", algorithm); fprintf(stderr, "Invalid algorithm %d\n", algorithm);
goto error; goto error;
} }