Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 1 | /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 2 | * Use of this source code is governed by a BSD-style license that can be |
| 3 | * found in the LICENSE file. |
| 4 | * |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 5 | * Tests for firmware vboot_common.c |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 6 | */ |
| 7 | |
| 8 | #include <stdio.h> |
| 9 | #include <stdlib.h> |
| 10 | |
| 11 | #include "test_common.h" |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 12 | #include "utility.h" |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 13 | #include "vboot_common.h" |
| 14 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 15 | /* |
| 16 | * Test struct packing for vboot_struct.h structs which are passed between |
| 17 | * firmware and OS, or passed between different phases of firmware. |
| 18 | */ |
| 19 | static void StructPackingTest(void) |
| 20 | { |
| 21 | TEST_EQ(EXPECTED_VBPUBLICKEY_SIZE, sizeof(VbPublicKey), |
| 22 | "sizeof(VbPublicKey)"); |
| 23 | TEST_EQ(EXPECTED_VBSIGNATURE_SIZE, sizeof(VbSignature), |
| 24 | "sizeof(VbSignature)"); |
| 25 | TEST_EQ(EXPECTED_VBKEYBLOCKHEADER_SIZE, sizeof(VbKeyBlockHeader), |
| 26 | "sizeof(VbKeyBlockHeader)"); |
| 27 | TEST_EQ(EXPECTED_VBFIRMWAREPREAMBLEHEADER2_0_SIZE, |
| 28 | sizeof(VbFirmwarePreambleHeader2_0), |
| 29 | "sizeof(VbFirmwarePreambleHeader2_0)"); |
| 30 | TEST_EQ(EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE, |
| 31 | sizeof(VbFirmwarePreambleHeader), |
| 32 | "sizeof(VbFirmwarePreambleHeader)"); |
| 33 | TEST_EQ(EXPECTED_VBKERNELPREAMBLEHEADER_SIZE, |
| 34 | sizeof(VbKernelPreambleHeader), |
| 35 | "sizeof(VbKernelPreambleHeader)"); |
Randall Spangler | f02bbb4 | 2011-08-24 14:16:01 -0700 | [diff] [blame] | 36 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 37 | TEST_EQ(VB_SHARED_DATA_HEADER_SIZE_V1, |
| 38 | (long)&((VbSharedDataHeader*)NULL)->recovery_reason, |
| 39 | "sizeof(VbSharedDataHeader) V1"); |
Randall Spangler | f02bbb4 | 2011-08-24 14:16:01 -0700 | [diff] [blame] | 40 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 41 | TEST_EQ(VB_SHARED_DATA_HEADER_SIZE_V2, |
| 42 | sizeof(VbSharedDataHeader), |
| 43 | "sizeof(VbSharedDataHeader) V2"); |
Randall Spangler | f02bbb4 | 2011-08-24 14:16:01 -0700 | [diff] [blame] | 44 | } |
| 45 | |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 46 | /* Test array size macro */ |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 47 | static void ArraySizeTest(void) |
| 48 | { |
| 49 | uint8_t arr1[12]; |
| 50 | uint32_t arr2[7]; |
| 51 | uint64_t arr3[9]; |
Randall Spangler | f02bbb4 | 2011-08-24 14:16:01 -0700 | [diff] [blame] | 52 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 53 | TEST_EQ(ARRAY_SIZE(arr1), 12, "ARRAYSIZE(uint8_t)"); |
| 54 | TEST_EQ(ARRAY_SIZE(arr2), 7, "ARRAYSIZE(uint32_t)"); |
| 55 | TEST_EQ(ARRAY_SIZE(arr3), 9, "ARRAYSIZE(uint64_t)"); |
Randall Spangler | 81d0996 | 2010-06-23 10:15:38 -0700 | [diff] [blame] | 56 | } |
| 57 | |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 58 | /* Helper functions not dependent on specific key sizes */ |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 59 | static void VerifyHelperFunctions(void) |
| 60 | { |
| 61 | { |
| 62 | uint8_t *p = (uint8_t *)VerifyHelperFunctions; |
| 63 | TEST_EQ((int)OffsetOf(p, p), 0, "OffsetOf() equal"); |
| 64 | TEST_EQ((int)OffsetOf(p, p+10), 10, "OffsetOf() positive"); |
| 65 | TEST_EQ((int)OffsetOf(p, p+0x12345678), 0x12345678, |
| 66 | "OffsetOf() large"); |
| 67 | } |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 68 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 69 | { |
| 70 | VbPublicKey k = {sizeof(k), 2, 3, 4}; |
| 71 | TEST_EQ((int)OffsetOf(&k, GetPublicKeyData(&k)), sizeof(k), |
| 72 | "GetPublicKeyData() adjacent"); |
| 73 | TEST_EQ((int)OffsetOf(&k, GetPublicKeyDataC(&k)), sizeof(k), |
| 74 | "GetPublicKeyDataC() adjacent"); |
| 75 | } |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 76 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 77 | { |
| 78 | VbPublicKey k = {123, 2, 3, 4}; |
| 79 | TEST_EQ((int)OffsetOf(&k, GetPublicKeyData(&k)), 123, |
| 80 | "GetPublicKeyData() spaced"); |
| 81 | TEST_EQ((int)OffsetOf(&k, GetPublicKeyDataC(&k)), 123, |
| 82 | "GetPublicKeyDataC() spaced"); |
| 83 | } |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 84 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 85 | { |
| 86 | uint8_t *p = (uint8_t *)VerifyHelperFunctions; |
| 87 | TEST_EQ(VerifyMemberInside(p, 20, p, 6, 11, 3), 0, |
| 88 | "MemberInside ok 1"); |
| 89 | TEST_EQ(VerifyMemberInside(p, 20, p+4, 4, 8, 4), 0, |
| 90 | "MemberInside ok 2"); |
| 91 | TEST_EQ(VerifyMemberInside(p, 20, p-4, 4, 8, 4), 1, |
| 92 | "MemberInside member before parent"); |
| 93 | TEST_EQ(VerifyMemberInside(p, 20, p+20, 4, 8, 4), 1, |
| 94 | "MemberInside member after parent"); |
| 95 | TEST_EQ(VerifyMemberInside(p, 20, p, 21, 0, 0), 1, |
| 96 | "MemberInside member too big"); |
| 97 | TEST_EQ(VerifyMemberInside(p, 20, p, 4, 21, 0), 1, |
| 98 | "MemberInside data after parent"); |
| 99 | TEST_EQ(VerifyMemberInside(p, 20, p, 4, (uint64_t)-1, 0), 1, |
| 100 | "MemberInside data before parent"); |
| 101 | TEST_EQ(VerifyMemberInside(p, 20, p, 4, 4, 17), 1, |
| 102 | "MemberInside data too big"); |
| 103 | } |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 104 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 105 | { |
| 106 | VbPublicKey k = {sizeof(k), 128, 0, 0}; |
| 107 | TEST_EQ(VerifyPublicKeyInside(&k, sizeof(k)+128, &k), 0, |
| 108 | "PublicKeyInside ok 1"); |
| 109 | TEST_EQ(VerifyPublicKeyInside(&k - 1, 2*sizeof(k)+128, &k), 0, |
| 110 | "PublicKeyInside ok 2"); |
| 111 | TEST_EQ(VerifyPublicKeyInside(&k, 128, &k), 1, |
| 112 | "PublicKeyInside key too big"); |
| 113 | } |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 114 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 115 | { |
| 116 | VbPublicKey k = {100, 4, 0, 0}; |
| 117 | TEST_EQ(VerifyPublicKeyInside(&k, 99, &k), 1, |
| 118 | "PublicKeyInside offset too big"); |
| 119 | } |
| 120 | |
| 121 | { |
| 122 | VbSignature s = {sizeof(s), 128, 2000}; |
| 123 | TEST_EQ(VerifySignatureInside(&s, sizeof(s)+128, &s), 0, |
| 124 | "SignatureInside ok 1"); |
| 125 | TEST_EQ(VerifySignatureInside(&s - 1, 2*sizeof(s)+128, &s), 0, |
| 126 | "SignatureInside ok 2"); |
| 127 | TEST_EQ(VerifySignatureInside(&s, 128, &s), 1, |
| 128 | "SignatureInside sig too big"); |
| 129 | } |
| 130 | |
| 131 | { |
| 132 | VbSignature s = {100, 4, 0}; |
| 133 | TEST_EQ(VerifySignatureInside(&s, 99, &s), 1, |
| 134 | "SignatureInside offset too big"); |
| 135 | } |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 136 | } |
| 137 | |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 138 | /* Public key utility functions */ |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 139 | static void PublicKeyTest(void) |
| 140 | { |
| 141 | VbPublicKey k[3]; |
| 142 | VbPublicKey j[5]; |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 143 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 144 | /* Fill some bits of the public key data */ |
| 145 | Memset(j, 0, sizeof(j)); |
| 146 | Memset(k, 0x42, sizeof(k)); |
| 147 | k[1].key_size = 12345; |
| 148 | k[2].key_version = 67; |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 149 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 150 | PublicKeyInit(k, (uint8_t*)(k + 1), 2 * sizeof(VbPublicKey)); |
| 151 | TEST_EQ(k->key_offset, sizeof(VbPublicKey), "PublicKeyInit key_offset"); |
| 152 | TEST_EQ(k->key_size, 2 * sizeof(VbPublicKey), "PublicKeyInit key_size"); |
| 153 | TEST_EQ(k->algorithm, kNumAlgorithms, "PublicKeyInit algorithm"); |
| 154 | TEST_EQ(k->key_version, 0, "PublicKeyInit key_version"); |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 155 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 156 | /* Set algorithm and version, so we can tell if they get copied */ |
| 157 | k->algorithm = 3; |
| 158 | k->key_version = 21; |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 159 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 160 | /* Copying to a smaller destination should fail */ |
| 161 | PublicKeyInit(j, (uint8_t*)(j + 1), 2 * sizeof(VbPublicKey) - 1); |
| 162 | TEST_NEQ(0, PublicKeyCopy(j, k), "PublicKeyCopy too small"); |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 163 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 164 | /* Copying to same or larger size should succeed */ |
| 165 | PublicKeyInit(j, (uint8_t*)(j + 2), 2 * sizeof(VbPublicKey) + 1); |
| 166 | TEST_EQ(0, PublicKeyCopy(j, k), "PublicKeyCopy same"); |
| 167 | /* Offset in destination shouldn't have been modified */ |
| 168 | TEST_EQ(j->key_offset, 2 * sizeof(VbPublicKey), |
| 169 | "PublicKeyCopy key_offset"); |
| 170 | /* Size should have been reduced to match the source */ |
| 171 | TEST_EQ(k->key_size, 2 * sizeof(VbPublicKey), "PublicKeyCopy key_size"); |
| 172 | /* Other fields should have been copied */ |
| 173 | TEST_EQ(k->algorithm, j->algorithm, "PublicKeyCopy algorithm"); |
| 174 | TEST_EQ(k->key_version, j->key_version, "PublicKeyCopy key_version"); |
| 175 | /* Data should have been copied */ |
| 176 | TEST_EQ(0, |
| 177 | Memcmp(GetPublicKeyData(k), GetPublicKeyData(j), k->key_size), |
| 178 | "PublicKeyCopy data"); |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 179 | } |
| 180 | |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 181 | /* VbSharedData utility tests */ |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 182 | static void VbSharedDataTest(void) |
| 183 | { |
| 184 | uint8_t buf[VB_SHARED_DATA_MIN_SIZE + 1]; |
| 185 | VbSharedDataHeader* d = (VbSharedDataHeader*)buf; |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 186 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 187 | TEST_NEQ(VBOOT_SUCCESS, |
| 188 | VbSharedDataInit(d, sizeof(VbSharedDataHeader) - 1), |
| 189 | "VbSharedDataInit too small"); |
| 190 | TEST_NEQ(VBOOT_SUCCESS, |
| 191 | VbSharedDataInit(d, VB_SHARED_DATA_MIN_SIZE - 1), |
| 192 | "VbSharedDataInit too small 2"); |
| 193 | TEST_NEQ(VBOOT_SUCCESS, |
| 194 | VbSharedDataInit(NULL, VB_SHARED_DATA_MIN_SIZE), |
| 195 | "VbSharedDataInit null"); |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 196 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 197 | Memset(buf, 0x68, sizeof(buf)); |
| 198 | TEST_EQ(VBOOT_SUCCESS, VbSharedDataInit(d, VB_SHARED_DATA_MIN_SIZE), |
| 199 | "VbSharedDataInit"); |
| 200 | |
| 201 | /* Check fields that should have been initialized */ |
| 202 | TEST_EQ(d->magic, VB_SHARED_DATA_MAGIC, "VbSharedDataInit magic"); |
| 203 | TEST_EQ(d->struct_version, VB_SHARED_DATA_VERSION, |
| 204 | "VbSharedDataInit version"); |
| 205 | TEST_EQ(d->struct_size, sizeof(VbSharedDataHeader), |
| 206 | "VbSharedDataInit struct_size"); |
| 207 | TEST_EQ(d->data_size, VB_SHARED_DATA_MIN_SIZE, |
| 208 | "VbSharedDataInit data_size"); |
| 209 | TEST_EQ(d->data_used, d->struct_size, "VbSharedDataInit data_used"); |
| 210 | TEST_EQ(d->firmware_index, 0xFF, "VbSharedDataInit firmware index"); |
| 211 | |
| 212 | /* Sample some other fields to make sure they were zeroed */ |
| 213 | TEST_EQ(d->flags, 0, "VbSharedDataInit firmware flags"); |
| 214 | TEST_EQ(d->lk_call_count, 0, "VbSharedDataInit lk_call_count"); |
| 215 | TEST_EQ(d->kernel_version_lowest, 0, |
| 216 | "VbSharedDataInit kernel_version_lowest"); |
Randall Spangler | 68f6049 | 2011-08-24 15:38:20 -0700 | [diff] [blame] | 217 | } |
| 218 | |
vbendeb | 3ecaf77 | 2010-06-24 16:19:53 -0700 | [diff] [blame] | 219 | /* disable MSVC warnings on unused arguments */ |
| 220 | __pragma(warning (disable: 4100)) |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 221 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 222 | int main(int argc, char* argv[]) |
| 223 | { |
| 224 | StructPackingTest(); |
| 225 | ArraySizeTest(); |
| 226 | VerifyHelperFunctions(); |
| 227 | PublicKeyTest(); |
| 228 | VbSharedDataTest(); |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 229 | |
Randall Spangler | 91db232 | 2013-01-24 10:42:13 -0800 | [diff] [blame^] | 230 | return gTestSuccess ? 0 : 255; |
Randall Spangler | d183644 | 2010-06-10 09:59:04 -0700 | [diff] [blame] | 231 | } |