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