Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 1 | /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
| 2 | * Use of this source code is governed by a BSD-style license that can be |
| 3 | * found in the LICENSE file. |
| 4 | * |
| 5 | * Tests for host library vboot2 key functions |
| 6 | */ |
| 7 | |
| 8 | #include <stdio.h> |
| 9 | #include <unistd.h> |
| 10 | |
| 11 | #include "2sysincludes.h" |
| 12 | #include "2common.h" |
| 13 | #include "2rsa.h" |
Randall Spangler | 108d991 | 2014-12-02 15:55:56 -0800 | [diff] [blame] | 14 | #include "vb2_common.h" |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 15 | #include "host_common.h" |
| 16 | #include "host_key2.h" |
| 17 | |
| 18 | #include "test_common.h" |
| 19 | |
| 20 | /* Test only the algorithms we use */ |
| 21 | struct alg_combo { |
| 22 | const char *name; |
| 23 | enum vb2_signature_algorithm sig_alg; |
| 24 | enum vb2_hash_algorithm hash_alg; |
| 25 | }; |
| 26 | |
| 27 | static const struct alg_combo test_algs[] = { |
| 28 | {"RSA2048/SHA-256", VB2_SIG_RSA2048, VB2_HASH_SHA256}, |
| 29 | {"RSA4096/SHA-256", VB2_SIG_RSA4096, VB2_HASH_SHA256}, |
| 30 | {"RSA8192/SHA-512", VB2_SIG_RSA8192, VB2_HASH_SHA512}, |
| 31 | }; |
| 32 | |
| 33 | static void private_key_tests(const struct alg_combo *combo, |
| 34 | const char *pemfile) |
| 35 | { |
| 36 | struct vb2_private_key *key, *k2; |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 37 | const struct vb2_private_key *ckey; |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 38 | struct vb2_packed_private_key *pkey; |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 39 | const char *testfile = "test.vbprik2"; |
| 40 | const char *notapem = "not_a_pem"; |
| 41 | const char *testdesc = "test desc"; |
| 42 | const struct vb2_guid test_guid = {.raw = {0xaa}}; |
| 43 | uint8_t *buf, *buf2; |
| 44 | uint32_t bufsize; |
| 45 | |
| 46 | TEST_SUCC(vb2_private_key_read_pem(&key, pemfile), "Read pem - good"); |
| 47 | TEST_PTR_NEQ(key, NULL, " key_ptr"); |
| 48 | TEST_PTR_NEQ(key->rsa_private_key, NULL, " rsa_private_key"); |
| 49 | TEST_PTR_EQ(key->desc, NULL, " desc"); |
| 50 | vb2_private_key_free(key); |
| 51 | |
| 52 | TEST_EQ(vb2_private_key_read_pem(&key, "no_such_key"), |
| 53 | VB2_ERROR_READ_PEM_FILE_OPEN, "Read pem - no key"); |
| 54 | TEST_PTR_EQ(key, NULL, " key_ptr"); |
| 55 | |
| 56 | vb2_write_file(testfile, (const uint8_t *)notapem, sizeof(notapem)); |
| 57 | TEST_EQ(vb2_private_key_read_pem(&key, testfile), |
| 58 | VB2_ERROR_READ_PEM_RSA, "Read pem - not a pem"); |
| 59 | unlink(testfile); |
| 60 | |
| 61 | TEST_SUCC(vb2_private_key_read_pem(&key, pemfile), "Read pem - good2"); |
| 62 | TEST_SUCC(vb2_private_key_set_desc(key, testdesc), "Set desc"); |
| 63 | TEST_PTR_NEQ(key->desc, NULL, " desc"); |
| 64 | TEST_PTR_NEQ(key->desc, testdesc, " made a copy"); |
| 65 | TEST_EQ(strcmp(key->desc, testdesc), 0, " right contents"); |
| 66 | TEST_SUCC(vb2_private_key_set_desc(key, NULL), "Clear desc"); |
| 67 | TEST_PTR_EQ(key->desc, NULL, " desc"); |
| 68 | TEST_SUCC(vb2_private_key_set_desc(key, testdesc), "Set desc"); |
| 69 | vb2_private_key_free(key); |
| 70 | |
| 71 | TEST_SUCC(vb2_private_key_read_pem(&key, pemfile), "Read pem - good3"); |
| 72 | TEST_SUCC(vb2_private_key_set_desc(key, testdesc), "Set desc"); |
| 73 | key->hash_alg = combo->hash_alg; |
| 74 | key->sig_alg = combo->sig_alg; |
| 75 | key->guid = test_guid; |
| 76 | |
| 77 | unlink(testfile); |
| 78 | |
| 79 | TEST_EQ(vb2_private_key_read(&k2, testfile), |
| 80 | VB2_ERROR_READ_FILE_OPEN, "Read key no file"); |
| 81 | TEST_EQ(vb2_private_key_write(key, "no/such/dir"), |
| 82 | VB2_ERROR_PRIVATE_KEY_WRITE_FILE, "Write key to bad path"); |
| 83 | |
| 84 | TEST_SUCC(vb2_private_key_write(key, testfile), "Write key good"); |
| 85 | TEST_SUCC(vb2_private_key_read(&k2, testfile), "Read key good"); |
| 86 | TEST_PTR_NEQ(k2, NULL, " key_ptr"); |
| 87 | TEST_EQ(k2->sig_alg, key->sig_alg, " sig alg"); |
| 88 | TEST_EQ(k2->hash_alg, key->hash_alg, " hash alg"); |
| 89 | TEST_EQ(memcmp(&k2->guid, &key->guid, sizeof(k2->guid)), 0, " guid"); |
| 90 | TEST_EQ(strcmp(k2->desc, testdesc), 0, " desc"); |
| 91 | vb2_private_key_free(k2); |
| 92 | |
| 93 | TEST_SUCC(vb2_read_file(testfile, &buf, &bufsize), "Read key raw"); |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 94 | pkey = (struct vb2_packed_private_key *)buf; |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 95 | |
| 96 | /* Make a backup of the good buffer so we can mangle it */ |
| 97 | buf2 = malloc(bufsize); |
| 98 | memcpy(buf2, buf, bufsize); |
| 99 | |
| 100 | TEST_SUCC(vb2_private_key_unpack(&k2, buf, bufsize), |
| 101 | "Unpack private key good"); |
| 102 | vb2_private_key_free(k2); |
| 103 | |
| 104 | memcpy(buf, buf2, bufsize); |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 105 | pkey->c.magic = VB2_MAGIC_PACKED_KEY; |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 106 | TEST_EQ(vb2_private_key_unpack(&k2, buf, bufsize), |
| 107 | VB2_ERROR_UNPACK_PRIVATE_KEY_MAGIC, |
| 108 | "Unpack private key bad magic"); |
| 109 | TEST_PTR_EQ(k2, NULL, " key_ptr"); |
| 110 | |
| 111 | memcpy(buf, buf2, bufsize); |
| 112 | pkey->c.desc_size++; |
| 113 | TEST_EQ(vb2_private_key_unpack(&k2, buf, bufsize), |
| 114 | VB2_ERROR_UNPACK_PRIVATE_KEY_HEADER, |
| 115 | "Unpack private key bad header"); |
| 116 | |
| 117 | memcpy(buf, buf2, bufsize); |
| 118 | pkey->key_size += pkey->c.total_size; |
| 119 | TEST_EQ(vb2_private_key_unpack(&k2, buf, bufsize), |
| 120 | VB2_ERROR_UNPACK_PRIVATE_KEY_DATA, |
| 121 | "Unpack private key bad data size"); |
| 122 | |
| 123 | memcpy(buf, buf2, bufsize); |
| 124 | pkey->c.struct_version_major++; |
| 125 | TEST_EQ(vb2_private_key_unpack(&k2, buf, bufsize), |
| 126 | VB2_ERROR_UNPACK_PRIVATE_KEY_STRUCT_VERSION, |
| 127 | "Unpack private key bad struct version"); |
| 128 | |
| 129 | memcpy(buf, buf2, bufsize); |
| 130 | pkey->c.struct_version_minor++; |
| 131 | TEST_SUCC(vb2_private_key_unpack(&k2, buf, bufsize), |
| 132 | "Unpack private key minor version"); |
| 133 | vb2_private_key_free(k2); |
| 134 | |
| 135 | memcpy(buf, buf2, bufsize); |
| 136 | pkey->key_size -= 32; |
| 137 | TEST_EQ(vb2_private_key_unpack(&k2, buf, bufsize), |
| 138 | VB2_ERROR_UNPACK_PRIVATE_KEY_RSA, |
| 139 | "Unpack private key bad rsa data"); |
| 140 | |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 141 | memcpy(buf, buf2, bufsize); |
| 142 | pkey->sig_alg = VB2_SIG_NONE; |
| 143 | TEST_EQ(vb2_private_key_unpack(&k2, buf, bufsize), |
| 144 | VB2_ERROR_UNPACK_PRIVATE_KEY_HASH, |
| 145 | "Unpack private key hash but has data"); |
| 146 | |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 147 | free(buf); |
| 148 | free(buf2); |
| 149 | unlink(testfile); |
| 150 | |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 151 | TEST_EQ(vb2_private_key_hash(&ckey, VB2_HASH_INVALID), |
| 152 | VB2_ERROR_PRIVATE_KEY_HASH, |
| 153 | "Hash key invalid"); |
| 154 | TEST_PTR_EQ(ckey, NULL, " key_ptr"); |
| 155 | |
| 156 | TEST_SUCC(vb2_private_key_hash(&ckey, combo->hash_alg), "Hash key"); |
| 157 | TEST_PTR_NEQ(ckey, NULL, " key_ptr"); |
| 158 | TEST_EQ(ckey->hash_alg, combo->hash_alg, " hash_alg"); |
| 159 | TEST_EQ(ckey->sig_alg, VB2_SIG_NONE, " sig_alg"); |
| 160 | TEST_EQ(memcmp(&ckey->guid, vb2_hash_guid(combo->hash_alg), |
| 161 | sizeof(ckey->guid)), 0, " guid"); |
| 162 | |
| 163 | TEST_SUCC(vb2_private_key_write(ckey, testfile), "Write hash key"); |
| 164 | TEST_SUCC(vb2_private_key_read(&key, testfile), "Read hash key"); |
| 165 | unlink(testfile); |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 166 | } |
| 167 | |
| 168 | static void public_key_tests(const struct alg_combo *combo, |
| 169 | const char *keybfile) |
| 170 | { |
| 171 | struct vb2_public_key *key, k2; |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 172 | struct vb2_packed_key *pkey; |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 173 | const char *testfile = "test.vbpubk2"; |
| 174 | const char *testdesc = "test desc"; |
| 175 | const struct vb2_guid test_guid = {.raw = {0xbb}}; |
| 176 | const uint32_t test_version = 0xcc01; |
| 177 | uint8_t *buf; |
| 178 | uint32_t bufsize; |
| 179 | |
| 180 | TEST_EQ(vb2_public_key_read_keyb(&key, "no_such_key"), |
| 181 | VB2_ERROR_READ_KEYB_DATA, "Read keyb - no file"); |
| 182 | TEST_PTR_EQ(key, NULL, " key_ptr"); |
| 183 | |
| 184 | TEST_SUCC(vb2_public_key_read_keyb(&key, keybfile), "Read keyb - good"); |
| 185 | TEST_PTR_NEQ(key, NULL, " key_ptr"); |
| 186 | TEST_EQ(key->sig_alg, combo->sig_alg, " sig_alg"); |
| 187 | TEST_PTR_EQ(key->desc, NULL, " desc"); |
| 188 | vb2_public_key_free(key); |
| 189 | |
| 190 | bufsize = vb2_packed_key_size(combo->sig_alg); |
Randall Spangler | 45562fb | 2014-12-01 15:06:53 -0800 | [diff] [blame] | 191 | buf = calloc(1, bufsize); |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 192 | |
| 193 | vb2_write_file(testfile, buf, bufsize - 1); |
| 194 | TEST_EQ(vb2_public_key_read_keyb(&key, testfile), |
| 195 | VB2_ERROR_READ_KEYB_SIZE, "Read keyb - bad size"); |
| 196 | unlink(testfile); |
| 197 | |
| 198 | vb2_write_file(testfile, buf, bufsize); |
| 199 | free(buf); |
| 200 | TEST_EQ(vb2_public_key_read_keyb(&key, testfile), |
| 201 | VB2_ERROR_READ_KEYB_UNPACK, "Read keyb - unpack"); |
| 202 | unlink(testfile); |
| 203 | |
| 204 | TEST_SUCC(vb2_public_key_read_keyb(&key, keybfile), "Read keyb 2"); |
| 205 | TEST_SUCC(vb2_public_key_set_desc(key, testdesc), "Set desc"); |
| 206 | TEST_PTR_NEQ(key->desc, NULL, " desc"); |
| 207 | TEST_PTR_NEQ(key->desc, testdesc, " made a copy"); |
| 208 | TEST_EQ(strcmp(key->desc, testdesc), 0, " right contents"); |
| 209 | TEST_SUCC(vb2_public_key_set_desc(key, NULL), "Clear desc"); |
| 210 | TEST_PTR_EQ(key->desc, NULL, " desc"); |
| 211 | TEST_SUCC(vb2_public_key_set_desc(key, testdesc), "Set desc"); |
| 212 | vb2_public_key_free(key); |
| 213 | |
| 214 | TEST_SUCC(vb2_public_key_read_keyb(&key, keybfile), "Read keyb 3"); |
| 215 | TEST_SUCC(vb2_public_key_set_desc(key, testdesc), "Set desc"); |
| 216 | key->hash_alg = combo->hash_alg; |
| 217 | key->guid = &test_guid; |
| 218 | key->version = test_version; |
| 219 | |
| 220 | TEST_SUCC(vb2_public_key_pack(&pkey, key), "Pack public key"); |
| 221 | TEST_PTR_NEQ(pkey, NULL, " key_ptr"); |
| 222 | TEST_EQ(pkey->hash_alg, key->hash_alg, " hash_alg"); |
| 223 | TEST_EQ(pkey->sig_alg, key->sig_alg, " sig_alg"); |
| 224 | TEST_EQ(pkey->key_version, key->version, " version"); |
| 225 | TEST_EQ(memcmp(&pkey->guid, key->guid, sizeof(pkey->guid)), 0, |
| 226 | " guid"); |
Randall Spangler | 9328bbf | 2014-11-24 12:55:29 -0800 | [diff] [blame] | 227 | TEST_EQ(strcmp(vb2_common_desc(pkey), key->desc), 0, " desc"); |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 228 | TEST_SUCC(vb2_unpack_key(&k2, (uint8_t *)pkey, pkey->c.total_size), |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 229 | "Unpack public key"); |
| 230 | TEST_EQ(key->arrsize, k2.arrsize, " arrsize"); |
| 231 | TEST_EQ(key->n0inv, k2.n0inv, " n0inv"); |
| 232 | TEST_EQ(memcmp(key->n, k2.n, key->arrsize * sizeof(uint32_t)), 0, |
| 233 | " n"); |
| 234 | TEST_EQ(memcmp(key->rr, k2.rr, key->arrsize * sizeof(uint32_t)), 0, |
| 235 | " rr"); |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 236 | |
| 237 | TEST_SUCC(vb2_write_object(testfile, pkey), "Write packed key"); |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 238 | free(pkey); |
| 239 | |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 240 | TEST_SUCC(vb2_packed_key_read(&pkey, testfile), "Read packed key"); |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 241 | TEST_PTR_NEQ(pkey, NULL, " key_ptr"); |
| 242 | unlink(testfile); |
| 243 | |
| 244 | pkey->hash_alg = VB2_HASH_INVALID; |
| 245 | TEST_SUCC(vb2_write_object(testfile, pkey), "Write bad packed key"); |
| 246 | free(pkey); |
| 247 | |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 248 | TEST_EQ(vb2_packed_key_read(&pkey, testfile), |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 249 | VB2_ERROR_READ_PACKED_KEY, "Read bad packed key"); |
| 250 | TEST_PTR_EQ(pkey, NULL, " key_ptr"); |
| 251 | unlink(testfile); |
| 252 | |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 253 | TEST_EQ(vb2_packed_key_read(&pkey, testfile), |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 254 | VB2_ERROR_READ_PACKED_KEY_DATA, "Read missing packed key"); |
| 255 | |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 256 | key->sig_alg = VB2_SIG_INVALID; |
| 257 | TEST_EQ(vb2_public_key_pack(&pkey, key), |
| 258 | VB2_ERROR_PUBLIC_KEY_PACK_SIZE, |
| 259 | "Pack invalid sig alg"); |
| 260 | vb2_public_key_free(key); |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 261 | |
| 262 | TEST_EQ(vb2_public_key_hash(&k2, VB2_HASH_INVALID), |
| 263 | VB2_ERROR_PUBLIC_KEY_HASH, |
| 264 | "Hash key invalid"); |
| 265 | |
| 266 | TEST_SUCC(vb2_public_key_hash(&k2, combo->hash_alg), "Hash key"); |
| 267 | TEST_EQ(k2.hash_alg, combo->hash_alg, " hash_alg"); |
| 268 | TEST_EQ(k2.sig_alg, VB2_SIG_NONE, " sig_alg"); |
| 269 | TEST_EQ(memcmp(k2.guid, vb2_hash_guid(combo->hash_alg), |
| 270 | sizeof(*k2.guid)), 0, " guid"); |
| 271 | |
| 272 | TEST_SUCC(vb2_public_key_pack(&pkey, &k2), "Pack public hash key"); |
| 273 | TEST_PTR_NEQ(pkey, NULL, " key_ptr"); |
Randall Spangler | 308d254 | 2014-12-04 09:54:37 -0800 | [diff] [blame] | 274 | TEST_SUCC(vb2_unpack_key(&k2, (uint8_t *)pkey, pkey->c.total_size), |
Randall Spangler | fb9a216 | 2014-11-20 11:27:38 -0800 | [diff] [blame] | 275 | "Unpack public hash key"); |
| 276 | free(pkey); |
Randall Spangler | 59c2920 | 2014-11-17 14:24:59 -0800 | [diff] [blame] | 277 | } |
| 278 | |
| 279 | static int test_algorithm(const struct alg_combo *combo, const char *keys_dir) |
| 280 | { |
| 281 | int rsa_bits = vb2_rsa_sig_size(combo->sig_alg) * 8; |
| 282 | char pemfile[1024]; |
| 283 | char keybfile[1024]; |
| 284 | |
| 285 | printf("***Testing algorithm: %s\n", combo->name); |
| 286 | |
| 287 | sprintf(pemfile, "%s/key_rsa%d.pem", keys_dir, rsa_bits); |
| 288 | sprintf(keybfile, "%s/key_rsa%d.keyb", keys_dir, rsa_bits); |
| 289 | |
| 290 | private_key_tests(combo, pemfile); |
| 291 | public_key_tests(combo, keybfile); |
| 292 | |
| 293 | return 0; |
| 294 | } |
| 295 | |
| 296 | int main(int argc, char *argv[]) { |
| 297 | |
| 298 | if (argc == 2) { |
| 299 | int i; |
| 300 | |
| 301 | for (i = 0; i < ARRAY_SIZE(test_algs); i++) { |
| 302 | if (test_algorithm(test_algs + i, argv[1])) |
| 303 | return 1; |
| 304 | } |
| 305 | } else { |
| 306 | fprintf(stderr, "Usage: %s <keys_dir>", argv[0]); |
| 307 | return -1; |
| 308 | } |
| 309 | |
| 310 | return gTestSuccess ? 0 : 255; |
| 311 | } |