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