OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can be | |
4 * found in the LICENSE file. | |
5 */ | |
6 | |
7 #include "gtest/gtest.h" | |
8 | |
9 #include <openssl/crypto/sha/sha.h> | |
10 #include "native_client/src/trusted/validator/caching/hashing_interface.h" | |
11 #include "native_client/src/trusted/validator/caching/validation_signature.h" | |
12 | |
13 void * TestHashCreate(const unsigned char *key, const unsigned int length) { | |
bsy
2012/02/22 01:43:35
either "void* TestHashCreate" or "void *TestHashCr
Nick Bray (chromium)
2012/02/22 03:07:28
Done.
| |
14 SHA256_CTX * ctx = (SHA256_CTX *) malloc(sizeof(SHA256_CTX)); | |
15 SHA256_Init(ctx); | |
16 // Peturb the hash with the key - unique keys ensure unique signatures. | |
17 // TODO(ncbray) full HMAC | |
18 SHA256_Update(ctx, key, length); | |
19 return ctx; | |
20 } | |
21 | |
22 void TestHashUpdate(void *ctx, const unsigned char *data, | |
23 const unsigned int length) { | |
24 SHA256_Update((SHA256_CTX *) ctx, data, length); | |
25 } | |
26 | |
27 void TestHashEnd(void *ctx, unsigned char *data, unsigned int *length, | |
28 const unsigned int max_length) { | |
29 unsigned char buffer[SHA256_DIGEST_LENGTH]; | |
30 unsigned int actual_length = SHA256_DIGEST_LENGTH; | |
31 if (max_length < actual_length) | |
32 actual_length = max_length; | |
33 SHA256_Final(buffer, (SHA256_CTX *) ctx); | |
34 memcpy(data, buffer, actual_length); | |
35 *length = actual_length; | |
36 free((SHA256_CTX *) ctx); | |
37 } | |
38 | |
39 void InitTestHashingInterface(HashingInterface *hashing) { | |
40 hashing->create = &TestHashCreate; | |
41 hashing->update = &TestHashUpdate; | |
42 hashing->end = &TestHashEnd; | |
43 } | |
44 | |
45 const unsigned char *code = (const unsigned char*) "foo bar!"; | |
46 const unsigned char *code_alt = (const unsigned char*) "barred!!"; | |
47 unsigned int code_length = 8; | |
48 | |
49 class ValidationCachingTests : public ::testing::Test { | |
50 protected: | |
51 HashingInterface hashing; | |
52 ValidationInfo info1; | |
53 ValidationInfo info2; | |
54 NaClCPUFeatures cpu_features1; | |
55 NaClCPUFeatures cpu_features2; | |
56 ValidationSignature sig1; | |
57 ValidationSignature sig2; | |
58 | |
59 void SetUp() { | |
60 InitTestHashingInterface(&hashing); | |
61 initInfo(&info1, &cpu_features1); | |
62 initInfo(&info2, &cpu_features2); | |
63 memset(&sig1, 0, sizeof(ValidationSignature)); | |
64 memset(&sig2, 0, sizeof(ValidationSignature)); | |
65 } | |
66 | |
67 void initInfo(ValidationInfo *info, NaClCPUFeatures *cpu_features) { | |
68 info->key = (unsigned char *) "a man a plan a canal panama"; | |
69 info->key_length = 27; | |
70 info->isa = "x86-32"; | |
71 info->version = "hello"; | |
72 info->cpu_features = cpu_features; | |
73 NaClSetAllCPUFeatures(cpu_features); | |
74 } | |
75 | |
76 void GetSig(ValidationInfo *info, const unsigned char *code, | |
77 unsigned int code_length, ValidationSignature *sig) { | |
78 GetValidationSignature(&hashing, info, code, code_length, sig); | |
79 } | |
80 | |
81 // For debugging. | |
82 void printSig(ValidationSignature *sig) { | |
83 for (unsigned int i = 0; i < sig->length; i++) { | |
84 printf("%2.2x ", sig->data[i]); | |
85 } | |
86 printf("\n"); | |
87 } | |
88 | |
89 void checkSanity(ValidationSignature *sig1, ValidationSignature *sig2) { | |
90 // printSig(sig1); | |
91 // printSig(sig2); | |
92 EXPECT_GE(sig1->length, (unsigned int) 16); | |
93 EXPECT_LE(sig1->length, (unsigned int) VALIDATION_SIGNATURE_MAX_LENGTH); | |
94 ASSERT_EQ(sig1->length, sig2->length); | |
95 } | |
96 | |
97 void expectDifferent(ValidationSignature *sig1, ValidationSignature *sig2) { | |
98 checkSanity(sig1, sig2); | |
99 ASSERT_NE(0, memcmp(sig1->data, sig2->data, sig1->length)); | |
100 } | |
101 | |
102 void expectSame(ValidationSignature *sig1, ValidationSignature *sig2) { | |
103 checkSanity(sig1, sig2); | |
104 ASSERT_EQ(0, memcmp(sig1->data, sig2->data, sig1->length)); | |
105 } | |
106 }; | |
107 | |
108 TEST_F(ValidationCachingTests, SetupSanity) { | |
109 ASSERT_EQ(0, memcmp(&sig1, &sig2, sizeof(ValidationSignature))); | |
110 } | |
111 | |
112 // Make sure the signature is repeatable. | |
113 TEST_F(ValidationCachingTests, Identical) { | |
114 GetSig(&info1, code, code_length, &sig1); | |
115 GetSig(&info2, code, code_length, &sig2); | |
116 expectSame(&sig1, &sig2); | |
117 } | |
118 | |
119 // Make sure every byte of the signature is written. | |
120 TEST_F(ValidationCachingTests, TotalOverwrite) { | |
121 memset(&sig1, 0x33, sizeof(ValidationSignature)); | |
122 memset(&sig2, 0x55, sizeof(ValidationSignature)); | |
123 GetSig(&info1, code, code_length, &sig1); | |
124 GetSig(&info2, code, code_length, &sig2); | |
125 expectSame(&sig1, &sig2); | |
126 } | |
127 | |
128 // Make sure the signature generation obeys null termination for strings. | |
129 TEST_F(ValidationCachingTests, VersionStringTermination) { | |
130 info1.version = "a\0b"; | |
131 info2.version = "a\0c"; | |
132 GetSig(&info1, code, code_length, &sig1); | |
133 GetSig(&info2, code, code_length, &sig2); | |
134 expectSame(&sig1, &sig2); | |
135 } | |
136 | |
137 // Make sure changing a single input byte changes the signature. | |
138 TEST_F(ValidationCachingTests, PeturbVersion) { | |
139 info2.version = "hell!"; | |
140 GetSig(&info1, code, code_length, &sig1); | |
141 GetSig(&info2, code, code_length, &sig2); | |
142 expectDifferent(&sig1, &sig2); | |
143 | |
144 info2.version = "yello"; | |
145 GetSig(&info1, code, code_length, &sig1); | |
146 GetSig(&info2, code, code_length, &sig2); | |
147 expectDifferent(&sig1, &sig2); | |
148 } | |
149 | |
150 TEST_F(ValidationCachingTests, PeturbISA) { | |
151 info2.isa = "x86-64"; | |
152 GetSig(&info1, code, code_length, &sig1); | |
153 GetSig(&info2, code, code_length, &sig2); | |
154 expectDifferent(&sig1, &sig2); | |
155 } | |
156 | |
157 TEST_F(ValidationCachingTests, PeturbCode) { | |
158 GetSig(&info1, code, code_length, &sig1); | |
159 GetSig(&info2, code_alt, code_length, &sig2); | |
160 expectDifferent(&sig1, &sig2); | |
161 } | |
162 | |
163 TEST_F(ValidationCachingTests, PeturbCodeLength) { | |
164 GetSig(&info1, code, code_length, &sig1); | |
165 GetSig(&info2, code, code_length-1, &sig2); | |
166 expectDifferent(&sig1, &sig2); | |
167 } | |
168 | |
169 TEST_F(ValidationCachingTests, PeturbKey) { | |
170 info2.key = (unsigned char *) "xxxxxxxxxxxxxxxxxxxxxxxxxxx"; | |
171 GetSig(&info1, code, code_length, &sig1); | |
172 GetSig(&info2, code, code_length, &sig2); | |
173 expectDifferent(&sig1, &sig2); | |
174 } | |
175 | |
176 TEST_F(ValidationCachingTests, PeturbKeyLength) { | |
177 info2.key_length -= 1; | |
178 GetSig(&info1, code, code_length, &sig1); | |
179 GetSig(&info2, code, code_length, &sig2); | |
180 expectDifferent(&sig1, &sig2); | |
181 } | |
182 | |
183 TEST_F(ValidationCachingTests, PeturbCPUFeatures) { | |
184 NaClClearCPUFeatures(info2.cpu_features); | |
185 GetSig(&info1, code, code_length, &sig1); | |
186 GetSig(&info2, code, code_length, &sig2); | |
187 expectDifferent(&sig1, &sig2); | |
188 } | |
189 | |
190 // Test driver function. | |
191 int main(int argc, char *argv[]) { | |
192 testing::InitGoogleTest(&argc, argv); | |
193 return RUN_ALL_TESTS(); | |
194 } | |
OLD | NEW |