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 firmware image library. 6 */ 7 8 #include <stdint.h> 9 #include <stdio.h> 10 #include <string.h> 11 12 #include "2sysincludes.h" 13 #include "2common.h" 14 #include "2rsa.h" 15 #include "vb2_common.h" 16 #include "host_common.h" 17 #include "host_key2.h" 18 #include "host_signature2.h" 19 #include "test_common.h" 20 21 22 static const uint8_t test_data[] = "This is some test data to sign."; 23 static const uint32_t test_size = sizeof(test_data); 24 25 static void test_unpack_key(const struct vb2_packed_key *key) 26 { 27 struct vb2_public_key pubk; 28 struct vb2_packed_key *key2; 29 uint32_t size = key->c.total_size; 30 31 /* Make a copy of the key for testing */ 32 key2 = (struct vb2_packed_key *)malloc(size); 33 34 memcpy(key2, key, size); 35 TEST_SUCC(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 36 "vb2_unpack_key() ok"); 37 38 memcpy(key2, key, size); 39 key2->key_offset += 4; 40 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 41 VB2_ERROR_COMMON_MEMBER_SIZE, 42 "vb2_unpack_key() buffer too small"); 43 44 memcpy(key2, key, size); 45 key2->c.fixed_size += size; 46 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 47 VB2_ERROR_COMMON_FIXED_SIZE, 48 "vb2_unpack_key() buffer too small for desc"); 49 50 memcpy(key2, key, size); 51 key2->c.desc_size = 0; 52 TEST_SUCC(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 53 "vb2_unpack_key() no desc"); 54 TEST_EQ(strcmp(pubk.desc, ""), 0, " empty desc string"); 55 56 memcpy(key2, key, size); 57 key2->c.magic++; 58 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 59 VB2_ERROR_UNPACK_KEY_MAGIC, 60 "vb2_unpack_key() bad magic"); 61 62 memcpy(key2, key, size); 63 key2->c.struct_version_major++; 64 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 65 VB2_ERROR_UNPACK_KEY_STRUCT_VERSION, 66 "vb2_unpack_key() bad major version"); 67 68 /* 69 * Minor version changes are ok. Note that this test assumes that the 70 * source key struct version is the highest actually known to the 71 * reader. If the reader does know about minor version + 1 and that 72 * adds fields, this test will likely fail. But at that point, we 73 * should have already added a test for minor version compatibility to 74 * handle both old and new struct versions, so someone will have 75 * noticed this comment. 76 */ 77 memcpy(key2, key, size); 78 key2->c.struct_version_minor++; 79 TEST_SUCC(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 80 "vb2_unpack_key() minor version change ok"); 81 82 memcpy(key2, key, size); 83 key2->sig_alg = VB2_SIG_INVALID; 84 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 85 VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM, 86 "vb2_unpack_key() bad sig algorithm"); 87 88 memcpy(key2, key, size); 89 key2->hash_alg = VB2_HASH_INVALID; 90 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 91 VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM, 92 "vb2_unpack_key() bad hash algorithm"); 93 94 memcpy(key2, key, size); 95 key2->key_size -= 4; 96 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 97 VB2_ERROR_UNPACK_KEY_SIZE, 98 "vb2_unpack_key() invalid size"); 99 100 memcpy(key2, key, size); 101 key2->key_offset--; 102 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 103 VB2_ERROR_COMMON_MEMBER_UNALIGNED, 104 "vb2_unpack_key() unaligned data"); 105 106 memcpy(key2, key, size); 107 *(uint32_t *)((uint8_t *)key2 + key2->key_offset) /= 2; 108 TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key2, size), 109 VB2_ERROR_UNPACK_KEY_ARRAY_SIZE, 110 "vb2_unpack_key() invalid key array size"); 111 112 free(key2); 113 } 114 115 static void test_verify_signature(const struct vb2_signature *sig) 116 { 117 struct vb2_signature *sig2; 118 uint8_t *buf2; 119 uint32_t size; 120 121 /* Make a copy of the signature */ 122 size = sig->c.total_size; 123 buf2 = malloc(size); 124 sig2 = (struct vb2_signature *)buf2; 125 126 memcpy(buf2, sig, size); 127 TEST_SUCC(vb2_verify_signature(sig2, size), "verify_sig ok"); 128 sig2->c.magic = VB2_MAGIC_PACKED_KEY; 129 TEST_EQ(vb2_verify_signature(sig2, size), VB2_ERROR_SIG_MAGIC, 130 "verify_sig magic"); 131 132 memcpy(buf2, sig, size); 133 sig2->c.total_size += 4; 134 TEST_EQ(vb2_verify_signature(sig2, size), VB2_ERROR_COMMON_TOTAL_SIZE, 135 "verify_sig common header"); 136 137 memcpy(buf2, sig, size); 138 sig2->c.struct_version_minor++; 139 TEST_SUCC(vb2_verify_signature(sig2, size), "verify_sig minor ver"); 140 sig2->c.struct_version_major++; 141 TEST_EQ(vb2_verify_signature(sig2, size), VB2_ERROR_SIG_VERSION, 142 "verify_sig major ver"); 143 144 memcpy(buf2, sig, size); 145 sig2->c.fixed_size -= 4; 146 sig2->c.desc_size += 4; 147 TEST_EQ(vb2_verify_signature(sig2, size), VB2_ERROR_SIG_HEADER_SIZE, 148 "verify_sig header size"); 149 150 memcpy(buf2, sig, size); 151 sig2->sig_size += 4; 152 TEST_EQ(vb2_verify_signature(sig2, size), VB2_ERROR_COMMON_MEMBER_SIZE, 153 "verify_sig sig size"); 154 155 memcpy(buf2, sig, size); 156 sig2->sig_alg = VB2_SIG_INVALID; 157 TEST_EQ(vb2_verify_signature(sig2, size), VB2_ERROR_SIG_ALGORITHM, 158 "verify_sig sig alg"); 159 160 memcpy(buf2, sig, size); 161 sig2->sig_alg = (sig2->sig_alg == VB2_SIG_NONE ? 162 VB2_SIG_RSA1024 : VB2_SIG_NONE); 163 TEST_EQ(vb2_verify_signature(sig2, size), VB2_ERROR_SIG_SIZE, 164 "verify_sig sig size"); 165 166 free(buf2); 167 } 168 169 static void test_verify_data(const struct vb2_public_key *pubk_orig, 170 const struct vb2_signature *sig) 171 { 172 uint8_t workbuf[VB2_VERIFY_DATA_WORKBUF_BYTES] 173 __attribute__ ((aligned (VB2_WORKBUF_ALIGN))); 174 struct vb2_workbuf wb; 175 176 struct vb2_public_key pubk; 177 struct vb2_signature *sig2; 178 uint8_t *buf2; 179 uint32_t size; 180 181 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); 182 183 pubk = *pubk_orig; 184 185 /* Allocate signature copy for tests */ 186 size = sig->c.total_size; 187 buf2 = malloc(size); 188 sig2 = (struct vb2_signature *)buf2; 189 190 memcpy(buf2, sig, size); 191 pubk.sig_alg = VB2_SIG_INVALID; 192 TEST_EQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb), 193 VB2_ERROR_VDATA_ALGORITHM, "vb2_verify_data() bad sig alg"); 194 pubk = *pubk_orig; 195 196 memcpy(buf2, sig, size); 197 pubk.hash_alg = VB2_HASH_INVALID; 198 TEST_EQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb), 199 VB2_ERROR_VDATA_DIGEST_SIZE, 200 "vb2_verify_data() bad hash alg"); 201 pubk = *pubk_orig; 202 203 vb2_workbuf_init(&wb, workbuf, 4); 204 memcpy(buf2, sig, size); 205 TEST_EQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb), 206 VB2_ERROR_VDATA_WORKBUF_DIGEST, 207 "vb2_verify_data() workbuf too small"); 208 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); 209 210 memcpy(buf2, sig, size); 211 TEST_EQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb), 212 0, "vb2_verify_data() ok"); 213 214 memcpy(buf2, sig, size); 215 sig2->sig_size -= 16; 216 TEST_EQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb), 217 VB2_ERROR_VDATA_SIG_SIZE, "vb2_verify_data() wrong sig size"); 218 219 memcpy(buf2, sig, size); 220 TEST_EQ(vb2_verify_data(test_data, test_size - 1, sig2, &pubk, &wb), 221 VB2_ERROR_VDATA_SIZE, "vb2_verify_data() wrong data size"); 222 223 memcpy(buf2, sig, size); 224 sig2->hash_alg = (sig2->hash_alg == VB2_HASH_SHA1 ? 225 VB2_HASH_SHA256 : VB2_HASH_SHA1); 226 TEST_EQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb), 227 VB2_ERROR_VDATA_ALGORITHM_MISMATCH, 228 "vb2_verify_data() alg mismatch"); 229 230 231 memcpy(buf2, sig, size); 232 buf2[sig2->sig_offset] ^= 0x5A; 233 TEST_EQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb), 234 VB2_ERROR_RSA_PADDING, "vb2_verify_data() wrong sig"); 235 236 free(buf2); 237 } 238 239 int test_algorithm(int key_algorithm, const char *keys_dir) 240 { 241 char filename[1024]; 242 int rsa_len = siglen_map[key_algorithm] * 8; 243 244 enum vb2_signature_algorithm sig_alg = 245 vb2_crypto_to_signature(key_algorithm); 246 enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(key_algorithm); 247 248 struct vb2_private_key *prik = NULL; 249 struct vb2_signature *sig2 = NULL; 250 struct vb2_public_key *pubk = NULL; 251 struct vb2_packed_key *key2 = NULL; 252 253 printf("***Testing algorithm: %s\n", algo_strings[key_algorithm]); 254 255 sprintf(filename, "%s/key_rsa%d.pem", keys_dir, rsa_len); 256 TEST_SUCC(vb2_private_key_read_pem(&prik, filename), 257 "Read private key"); 258 prik->hash_alg = hash_alg; 259 prik->sig_alg = sig_alg; 260 vb2_private_key_set_desc(prik, "private key"); 261 262 sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len); 263 TEST_SUCC(vb2_public_key_read_keyb(&pubk, filename), 264 "Read public key"); 265 pubk->hash_alg = hash_alg; 266 vb2_public_key_set_desc(pubk, "public key"); 267 TEST_SUCC(vb2_public_key_pack(&key2, pubk), "Pack public key"); 268 269 /* Calculate good signatures */ 270 TEST_SUCC(vb2_sign_data(&sig2, test_data, test_size, prik, ""), 271 "Make test signature"); 272 273 test_unpack_key(key2); 274 test_verify_data(pubk, sig2); 275 test_verify_signature(sig2); 276 277 free(key2); 278 free(sig2); 279 vb2_private_key_free(prik); 280 vb2_public_key_free(pubk); 281 282 return 0; 283 } 284 285 /* Test only the algorithms we use */ 286 const int key_algs[] = { 287 VB2_ALG_RSA2048_SHA256, 288 VB2_ALG_RSA4096_SHA256, 289 VB2_ALG_RSA8192_SHA512, 290 }; 291 292 int main(int argc, char *argv[]) { 293 294 if (argc == 2) { 295 int i; 296 297 for (i = 0; i < ARRAY_SIZE(key_algs); i++) { 298 if (test_algorithm(key_algs[i], argv[1])) 299 return 1; 300 } 301 302 } else if (argc == 3 && !strcasecmp(argv[2], "--all")) { 303 /* Test all the algorithms */ 304 int alg; 305 306 for (alg = 0; alg < kNumAlgorithms; alg++) { 307 if (test_algorithm(alg, argv[1])) 308 return 1; 309 } 310 311 } else { 312 fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]); 313 return -1; 314 } 315 316 return gTestSuccess ? 0 : 255; 317 } 318