1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
/* Copyright (c) 2014 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 host library vboot2 key functions
*/
#include <stdio.h>
#include <unistd.h>
#include "2common.h"
#include "2rsa.h"
#include "2sysincludes.h"
#include "common/tests.h"
#include "host_common.h"
#include "host_common21.h"
#include "host_key21.h"
#include "host_signature21.h"
/* Test only the algorithms we use */
struct alg_combo {
const char *name;
enum vb2_signature_algorithm sig_alg;
enum vb2_hash_algorithm hash_alg;
};
static const struct alg_combo test_algs[] = {
{"RSA2048/SHA-256", VB2_SIG_RSA2048, VB2_HASH_SHA256},
{"RSA4096/SHA-256", VB2_SIG_RSA4096, VB2_HASH_SHA256},
{"RSA8192/SHA-512", VB2_SIG_RSA8192, VB2_HASH_SHA512},
};
const struct vb2_id test_id = {.raw = {0xaa}};
const char *test_desc = "The test key";
const char *test_sig_desc = "The test signature";
const uint8_t test_data[] = "Some test data";
const uint32_t test_size = sizeof(test_data);
static void sig_tests(const struct alg_combo *combo,
const char *pemfile,
const char *keybfile)
{
struct vb2_private_key *prik, prik2;
const struct vb2_private_key *prihash, *priks[2];
struct vb2_public_key *pubk, pubhash;
struct vb21_signature *sig, *sig2;
uint32_t size;
uint8_t workbuf[VB2_VERIFY_DATA_WORKBUF_BYTES]
__attribute__((aligned(VB2_WORKBUF_ALIGN)));
struct vb2_workbuf wb;
uint8_t *buf;
uint32_t bufsize;
struct vb21_struct_common *c;
uint32_t c_sig_offs;
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
/* Create test keys */
/* TODO: should read these from .vbprik2, .vbpubk2 files */
TEST_SUCC(vb2_private_key_read_pem(&prik, pemfile), "Read private key");
prik->id = test_id;
prik->hash_alg = combo->hash_alg;
prik->sig_alg = combo->sig_alg;
vb2_private_key_set_desc(prik, test_desc);
TEST_SUCC(vb2_public_key_read_keyb(&pubk, keybfile), "Read pub key");
pubk->id = &test_id;
pubk->hash_alg = combo->hash_alg;
vb2_public_key_set_desc(pubk, test_desc);
TEST_SUCC(vb2_private_key_hash(&prihash, combo->hash_alg),
"Private hash key");
TEST_SUCC(vb2_public_key_hash(&pubhash, combo->hash_alg),
"Public hash key");
priks[0] = prik;
priks[1] = prihash;
/* Sign test data */
TEST_SUCC(vb21_sign_data(&sig, test_data, test_size, prik, NULL),
"Sign good");
TEST_PTR_NEQ(sig, NULL, " sig_ptr");
TEST_EQ(0, strcmp(vb21_common_desc(sig), test_desc), " desc");
TEST_EQ(0, memcmp(&sig->id, &test_id, sizeof(test_id)), " id");
TEST_EQ(sig->data_size, test_size, " data_size");
TEST_SUCC(vb21_sig_size_for_key(&size, prik, NULL), "Sig size");
TEST_EQ(size, sig->c.total_size, " size");
TEST_SUCC(vb21_verify_data(test_data, test_size, sig, pubk, &wb),
"Verify good");
free(sig);
TEST_SUCC(vb21_sign_data(&sig, test_data, test_size, prik,
test_sig_desc),
"Sign with desc");
TEST_EQ(0, strcmp(vb21_common_desc(sig), test_sig_desc), " desc");
free(sig);
TEST_SUCC(vb21_sign_data(&sig, test_data, test_size, prik, ""),
"Sign with no desc");
TEST_EQ(sig->c.desc_size, 0, " desc");
TEST_SUCC(vb21_sig_size_for_key(&size, prik, ""), "Sig size");
TEST_EQ(size, sig->c.total_size, " size");
free(sig);
TEST_SUCC(vb21_sign_data(&sig, test_data, test_size, prihash, NULL),
"Sign with hash");
TEST_SUCC(vb21_verify_data(test_data, test_size, sig, &pubhash, &wb),
"Verify with hash");
free(sig);
prik2 = *prik;
prik2.sig_alg = VB2_SIG_INVALID;
TEST_EQ(vb21_sign_data(&sig, test_data, test_size, &prik2, NULL),
VB2_SIGN_DATA_SIG_SIZE, "Sign bad sig alg");
/* Sign an object with a little (24 bytes) data */
c_sig_offs = sizeof(*c) + 24;
TEST_SUCC(vb21_sig_size_for_key(&size, prik, NULL), "Sig size");
bufsize = c_sig_offs + size;
buf = calloc(1, bufsize);
memset(buf + sizeof(*c), 0x12, 24);
c = (struct vb21_struct_common *)buf;
c->total_size = bufsize;
TEST_SUCC(vb21_sign_object(buf, c_sig_offs, prik, NULL), "Sign object");
sig = (struct vb21_signature *)(buf + c_sig_offs);
TEST_SUCC(vb21_verify_data(buf, c_sig_offs, sig, pubk, &wb),
"Verify object");
TEST_EQ(vb21_sign_object(buf, c_sig_offs + 4, prik, NULL),
VB2_SIGN_OBJECT_OVERFLOW, "Sign object overflow");
free(buf);
/* Multiply sign an object */
TEST_SUCC(vb21_sig_size_for_keys(&size, priks, 2), "Sigs size");
bufsize = c_sig_offs + size;
buf = calloc(1, bufsize);
memset(buf + sizeof(*c), 0x12, 24);
c = (struct vb21_struct_common *)buf;
c->total_size = bufsize;
TEST_SUCC(vb21_sign_object_multiple(buf, c_sig_offs, priks, 2),
"Sign multiple");
sig = (struct vb21_signature *)(buf + c_sig_offs);
TEST_SUCC(vb21_verify_data(buf, c_sig_offs, sig, pubk, &wb),
"Verify object with sig 1");
sig2 = (struct vb21_signature *)(buf + c_sig_offs + sig->c.total_size);
TEST_SUCC(vb21_verify_data(buf, c_sig_offs, sig2, &pubhash, &wb),
"Verify object with sig 2");
c->total_size -= 4;
TEST_EQ(vb21_sign_object_multiple(buf, c_sig_offs, priks, 2),
VB2_SIGN_OBJECT_OVERFLOW, "Sign multple overflow");
TEST_EQ(size, sig->c.total_size + sig2->c.total_size,
"Sigs size total");
free(buf);
vb2_private_key_free(prik);
vb2_public_key_free(pubk);
}
static int test_algorithm(const struct alg_combo *combo, const char *keys_dir)
{
int rsa_bits = vb2_rsa_sig_size(combo->sig_alg) * 8;
char pemfile[1024];
char keybfile[1024];
printf("***Testing algorithm: %s\n", combo->name);
snprintf(pemfile, sizeof(pemfile),
"%s/key_rsa%d.pem", keys_dir, rsa_bits);
snprintf(keybfile, sizeof(keybfile),
"%s/key_rsa%d.keyb", keys_dir, rsa_bits);
sig_tests(combo, pemfile, keybfile);
return 0;
}
int main(int argc, char *argv[]) {
if (argc == 2) {
int i;
for (i = 0; i < ARRAY_SIZE(test_algs); i++) {
if (test_algorithm(test_algs + i, argv[1]))
return 1;
}
} else {
fprintf(stderr, "Usage: %s <keys_dir>", argv[0]);
return -1;
}
return gTestSuccess ? 0 : 255;
}
|