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 21static const uint8_t test_data[] = "This is some test data to sign."; 22static const uint32_t test_size = sizeof(test_data); 23 24static 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 77static 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 138int 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 */ 182const int key_algs[] = { 183 VB2_ALG_RSA2048_SHA256, 184 VB2_ALG_RSA4096_SHA256, 185 VB2_ALG_RSA8192_SHA512, 186}; 187 188int 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