Major refactoring of structures, with unit tests.  This matches the doc I sent out earlier.

Firmware-side code for LoadKernel() is in place now.  LoadFirmware() replacement coming soon.

The new functions are implemented in parallel to the existing ones (i.e., everything that used to work still does).

Review URL: http://codereview.chromium.org/2745007
diff --git a/tests/vboot_common_tests.c b/tests/vboot_common_tests.c
new file mode 100644
index 0000000..e467471
--- /dev/null
+++ b/tests/vboot_common_tests.c
@@ -0,0 +1,101 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Tests for firmware image library.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "test_common.h"
+#include "vboot_common.h"
+
+
+/* Helper functions not dependent on specific key sizes */
+void VerifyHelperFunctions(void) {
+
+  {
+    uint8_t p[1];
+    TEST_EQ(OffsetOf(p, p), 0, "OffsetOf() equal");
+    TEST_EQ(OffsetOf(p, p+10), 10, "OffsetOf() positive");
+    TEST_EQ(OffsetOf(p, p+0x12345678), 0x12345678, "OffsetOf() large");
+  }
+
+  {
+    VbPublicKey k = {sizeof(k), 2, 3, 4};
+    TEST_EQ(OffsetOf(&k, GetPublicKeyData(&k)), sizeof(k),
+            "GetPublicKeyData() adjacent");
+    TEST_EQ(OffsetOf(&k, GetPublicKeyDataC(&k)), sizeof(k),
+            "GetPublicKeyDataC() adjacent");
+  }
+
+  {
+    VbPublicKey k = {123, 2, 3, 4};
+    TEST_EQ(OffsetOf(&k, GetPublicKeyData(&k)), 123,
+            "GetPublicKeyData() spaced");
+    TEST_EQ(OffsetOf(&k, GetPublicKeyDataC(&k)), 123,
+            "GetPublicKeyDataC() spaced");
+  }
+
+  {
+    uint8_t p[1];
+    TEST_EQ(VerifyMemberInside(p, 20, p, 6, 11, 3), 0, "MemberInside ok 1");
+    TEST_EQ(VerifyMemberInside(p, 20, p+4, 4, 8, 4), 0, "MemberInside ok 2");
+    TEST_EQ(VerifyMemberInside(p, 20, p-4, 4, 8, 4), 1,
+            "MemberInside member before parent");
+    TEST_EQ(VerifyMemberInside(p, 20, p+20, 4, 8, 4), 1,
+            "MemberInside member after parent");
+    TEST_EQ(VerifyMemberInside(p, 20, p, 21, 0, 0), 1,
+            "MemberInside member too big");
+    TEST_EQ(VerifyMemberInside(p, 20, p, 4, 21, 0), 1,
+            "MemberInside data after parent");
+    TEST_EQ(VerifyMemberInside(p, 20, p, 4, -1, 0), 1,
+            "MemberInside data before parent");
+    TEST_EQ(VerifyMemberInside(p, 20, p, 4, 4, 17), 1,
+            "MemberInside data too big");
+  }
+
+  {
+    VbPublicKey k = {sizeof(k), 128, 0, 0};
+    TEST_EQ(VerifyPublicKeyInside(&k, sizeof(k)+128, &k), 0,
+            "PublicKeyInside ok 1");
+    TEST_EQ(VerifyPublicKeyInside(&k - 1, 2*sizeof(k)+128, &k), 0,
+            "PublicKeyInside ok 2");
+    TEST_EQ(VerifyPublicKeyInside(&k, 128, &k), 1,
+            "PublicKeyInside key too big");
+  }
+  {
+    VbPublicKey k = {100, 4, 0, 0};
+    TEST_EQ(VerifyPublicKeyInside(&k, 99, &k), 1,
+            "PublicKeyInside offset too big");
+  }
+  {
+    VbSignature s = {sizeof(s), 128, 2000};
+    TEST_EQ(VerifySignatureInside(&s, sizeof(s)+128, &s), 0,
+            "SignatureInside ok 1");
+    TEST_EQ(VerifySignatureInside(&s - 1, 2*sizeof(s)+128, &s), 0,
+            "SignatureInside ok 2");
+    TEST_EQ(VerifySignatureInside(&s, 128, &s), 1,
+            "SignatureInside sig too big");
+  }
+  {
+    VbSignature s = {100, 4, 0};
+    TEST_EQ(VerifySignatureInside(&s, 99, &s), 1,
+            "SignatureInside offset too big");
+  }
+
+}
+
+
+int main(int argc, char* argv[]) {
+  int error_code = 0;
+
+  /* Test helper functions */
+  VerifyHelperFunctions();
+
+  if (!gTestSuccess)
+    error_code = 255;
+
+  return error_code;
+}