Home | History | Annotate | Download | only in tests
      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 "2rsa.h"
     14 #include "file_keys.h"
     15 #include "host_common.h"
     16 #include "vb2_common.h"
     17 #include "vboot_common.h"
     18 #include "test_common.h"
     19 
     20 
     21 static const uint8_t test_data[] = "This is some test data to sign.";
     22 static const uint32_t test_size = sizeof(test_data);
     23 
     24 static void test_unpack_key(const struct vb2_packed_key *key1)
     25 {
     26 	struct vb2_public_key pubk;
     27 
     28 	/*
     29 	 * Key data follows the header for a newly allocated key, so we can
     30 	 * calculate the buffer size by looking at how far the key data goes.
     31 	 */
     32 	uint32_t size = key1->key_offset + key1->key_size;
     33 	uint8_t *buf = malloc(size);
     34 	struct vb2_packed_key *key = (struct vb2_packed_key *)buf;
     35 
     36 	memcpy(key, key1, size);
     37 	TEST_SUCC(vb2_unpack_key(&pubk, buf, size), "vb2_unpack_key() ok");
     38 
     39 	TEST_EQ(pubk.sig_alg, vb2_crypto_to_signature(key->algorithm),
     40 		"vb2_unpack_key() sig_alg");
     41 	TEST_EQ(pubk.hash_alg, vb2_crypto_to_hash(key->algorithm),
     42 		"vb2_unpack_key() hash_alg");
     43 
     44 
     45 	memcpy(key, key1, size);
     46 	key->algorithm = VB2_ALG_COUNT;
     47 	TEST_EQ(vb2_unpack_key(&pubk, buf, size),
     48 		VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM,
     49 		"vb2_unpack_key() invalid algorithm");
     50 
     51 	memcpy(key, key1, size);
     52 	key->key_size--;
     53 	TEST_EQ(vb2_unpack_key(&pubk, buf, size),
     54 		VB2_ERROR_UNPACK_KEY_SIZE,
     55 		"vb2_unpack_key() invalid size");
     56 
     57 	memcpy(key, key1, size);
     58 	key->key_offset++;
     59 	TEST_EQ(vb2_unpack_key(&pubk, buf, size + 1),
     60 		VB2_ERROR_UNPACK_KEY_ALIGN,
     61 		"vb2_unpack_key() unaligned data");
     62 
     63 	memcpy(key, key1, size);
     64 	*(uint32_t *)(buf + key->key_offset) /= 2;
     65 	TEST_EQ(vb2_unpack_key(&pubk, buf, size),
     66 		VB2_ERROR_UNPACK_KEY_ARRAY_SIZE,
     67 		"vb2_unpack_key() invalid key array size");
     68 
     69 	memcpy(key, key1, size);
     70 	TEST_EQ(vb2_unpack_key(&pubk, buf, size - 1),
     71 		VB2_ERROR_INSIDE_DATA_OUTSIDE,
     72 		"vb2_unpack_key() buffer too small");
     73 
     74 	free(key);
     75 }
     76 
     77 static void test_verify_data(const struct vb2_packed_key *key1,
     78 			     const struct vb2_signature *sig)
     79 {
     80 	uint8_t workbuf[VB2_VERIFY_DATA_WORKBUF_BYTES]
     81 		 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
     82 	struct vb2_workbuf wb;
     83 
     84 	uint32_t pubkey_size = key1->key_offset + key1->key_size;
     85 	struct vb2_public_key pubk, pubk_orig;
     86 	uint32_t sig_total_size = sig->sig_offset + sig->sig_size;
     87 	struct vb2_signature *sig2;
     88 
     89 	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
     90 
     91 	/* Allocate signature copy for tests */
     92 	sig2 = (struct vb2_signature *)malloc(sig_total_size);
     93 
     94 	TEST_EQ(vb2_unpack_key(&pubk, (uint8_t *)key1, pubkey_size),
     95 		0, "vb2_verify_data() unpack key");
     96 	pubk_orig = pubk;
     97 
     98 	memcpy(sig2, sig, sig_total_size);
     99 	pubk.sig_alg = VB2_SIG_INVALID;
    100 	TEST_NEQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb),
    101 		 0, "vb2_verify_data() bad sig alg");
    102 	pubk.sig_alg = pubk_orig.sig_alg;
    103 
    104 	memcpy(sig2, sig, sig_total_size);
    105 	pubk.hash_alg = VB2_HASH_INVALID;
    106 	TEST_NEQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb),
    107 		 0, "vb2_verify_data() bad hash alg");
    108 	pubk.hash_alg = pubk_orig.hash_alg;
    109 
    110 	vb2_workbuf_init(&wb, workbuf, 4);
    111 	memcpy(sig2, sig, sig_total_size);
    112 	TEST_NEQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb),
    113 		 0, "vb2_verify_data() workbuf too small");
    114 	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
    115 
    116 	memcpy(sig2, sig, sig_total_size);
    117 	TEST_EQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb),
    118 		0, "vb2_verify_data() ok");
    119 
    120 	memcpy(sig2, sig, sig_total_size);
    121 	sig2->sig_size -= 16;
    122 	TEST_NEQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb),
    123 		 0, "vb2_verify_data() wrong sig size");
    124 
    125 	memcpy(sig2, sig, sig_total_size);
    126 	TEST_NEQ(vb2_verify_data(test_data, test_size - 1, sig2, &pubk, &wb),
    127 		 0, "vb2_verify_data() input buffer too small");
    128 
    129 	memcpy(sig2, sig, sig_total_size);
    130 	vb2_signature_data(sig2)[0] ^= 0x5A;
    131 	TEST_NEQ(vb2_verify_data(test_data, test_size, sig2, &pubk, &wb),
    132 		 0, "vb2_verify_data() wrong sig");
    133 
    134 	free(sig2);
    135 }
    136 
    137 
    138 int test_algorithm(int key_algorithm, const char *keys_dir)
    139 {
    140 	char filename[1024];
    141 	int rsa_len = siglen_map[key_algorithm] * 8;
    142 
    143 	VbPrivateKey *private_key = NULL;
    144 	struct vb2_signature *sig = NULL;
    145 	struct vb2_packed_key *key1;
    146 
    147 	printf("***Testing algorithm: %s\n", algo_strings[key_algorithm]);
    148 
    149 	sprintf(filename, "%s/key_rsa%d.pem", keys_dir, rsa_len);
    150 	private_key = PrivateKeyReadPem(filename, key_algorithm);
    151 	if (!private_key) {
    152 		fprintf(stderr, "Error reading private_key: %s\n", filename);
    153 		return 1;
    154 	}
    155 
    156 	sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len);
    157 	key1 = (struct vb2_packed_key *)
    158 		PublicKeyReadKeyb(filename, key_algorithm, 1);
    159 	if (!key1) {
    160 		fprintf(stderr, "Error reading public_key: %s\n", filename);
    161 		return 1;
    162 	}
    163 
    164 	/* Calculate good signatures */
    165 	sig = (struct vb2_signature *)
    166 		CalculateSignature(test_data, sizeof(test_data), private_key);
    167 	TEST_PTR_NEQ(sig, 0, "Calculate signature");
    168 	if (!sig)
    169 		return 1;
    170 
    171 	test_unpack_key(key1);
    172 	test_verify_data(key1, sig);
    173 
    174 	free(key1);
    175 	free(private_key);
    176 	free(sig);
    177 
    178 	return 0;
    179 }
    180 
    181 /* Test only the algorithms we use */
    182 const int key_algs[] = {
    183 	VB2_ALG_RSA2048_SHA256,
    184 	VB2_ALG_RSA4096_SHA256,
    185 	VB2_ALG_RSA8192_SHA512,
    186 };
    187 
    188 int main(int argc, char *argv[]) {
    189 
    190 	if (argc == 2) {
    191 		int i;
    192 
    193 		for (i = 0; i < ARRAY_SIZE(key_algs); i++) {
    194 			if (test_algorithm(key_algs[i], argv[1]))
    195 				return 1;
    196 		}
    197 
    198 	} else if (argc == 3 && !strcasecmp(argv[2], "--all")) {
    199 		/* Test all the algorithms */
    200 		int alg;
    201 
    202 		for (alg = 0; alg < kNumAlgorithms; alg++) {
    203 			if (test_algorithm(alg, argv[1]))
    204 				return 1;
    205 		}
    206 
    207 	} else {
    208 		fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]);
    209 		return -1;
    210 	}
    211 
    212 	return gTestSuccess ? 0 : 255;
    213 }
    214