1/* Copyright (c) 2011 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
6
7#include <stdint.h>
8#include <stdio.h>
9
10#define _STUB_IMPLEMENTATION_
11
12#include "cryptolib.h"
13#include "file_keys.h"
14#include "rsa_padding_test.h"
15#include "test_common.h"
16#include "utility.h"
17#include "vboot_api.h"
18
19
20/* Data for mock functions */
21static int mock_rsaverify_retval;
22
23/* Mock functions */
24uint8_t* DigestBuf(const uint8_t* buf, uint64_t len, int sig_algorithm) {
25  /* Just need to return something; it's only passed to the mock RSAVerify() */
26  return VbExMalloc(4);
27}
28
29int RSAVerify(const RSAPublicKey *key,
30              const uint8_t* sig,
31              const uint32_t sig_len,
32              const uint8_t sig_type,
33              const uint8_t* hash) {
34  return mock_rsaverify_retval;
35}
36
37static void ResetMocks(void) {
38  mock_rsaverify_retval = 1;
39}
40
41/* Test RSA utility funcs */
42static void TestUtils(void) {
43  RSAPublicKey* key;
44  uint64_t u;
45
46  /* Processed key size */
47  TEST_EQ(RSAProcessedKeySize(0, &u), 1, "Processed key size 0");
48  TEST_EQ(u, RSA1024NUMBYTES * 2 + sizeof(uint32_t) * 2,
49          "Processed key size 0 size");
50  TEST_EQ(RSAProcessedKeySize(3, &u), 1, "Processed key size 3");
51  TEST_EQ(u, RSA2048NUMBYTES * 2 + sizeof(uint32_t) * 2,
52          "Processed key size 3 size");
53  TEST_EQ(RSAProcessedKeySize(7, &u), 1, "Processed key size 7");
54  TEST_EQ(u, RSA4096NUMBYTES * 2 + sizeof(uint32_t) * 2,
55          "Processed key size 7 size");
56  TEST_EQ(RSAProcessedKeySize(11, &u), 1, "Processed key size 11");
57  TEST_EQ(u, RSA8192NUMBYTES * 2 + sizeof(uint32_t) * 2,
58          "Processed key size 11 size");
59  TEST_EQ(RSAProcessedKeySize(kNumAlgorithms, &u), 0,
60          "Processed key size invalid algorithm");
61
62  /* Alloc key */
63  key = RSAPublicKeyNew();
64  TEST_EQ(key == NULL, 0, "New key not null");
65  /* New key fields */
66  TEST_PTR_EQ(key->n, NULL, "New key no n");
67  TEST_PTR_EQ(key->rr, NULL, "New key no rr");
68  TEST_EQ(key->len, 0, "New key len");
69  TEST_EQ(key->algorithm, kNumAlgorithms, "New key no algorithm");
70  /* Free key */
71  RSAPublicKeyFree(key);
72  /* Freeing null key shouldn't implode */
73  RSAPublicKeyFree(NULL);
74}
75
76/* Test creating key from buffer */
77static void TestKeyFromBuffer(void) {
78  RSAPublicKey* key;
79  uint8_t* buf;
80  uint32_t* buf_key_len;
81  int i;
82
83  buf = malloc(8 + 2 * RSA8192NUMBYTES);
84  buf_key_len = (uint32_t*)buf;
85
86  for (i = 0; i < 4; i++) {
87    uint32_t key_len = RSA1024NUMBYTES << i;
88    Memset(buf, 0xAB, sizeof(buf));
89    *buf_key_len = key_len / sizeof(uint32_t);
90    *(buf_key_len + 1) = 0xF00D2345;  /* n0inv */
91    buf[8] = 100;
92    buf[8 + key_len - 1] = 101;
93    buf[8 + key_len] = 120;
94    buf[8 + key_len * 2 - 1] = 121;
95
96    /* Correct length */
97    key = RSAPublicKeyFromBuf(buf, 8 + key_len * 2);
98    TEST_PTR_NEQ(key, NULL, "RSAPublicKeyFromBuf() ptr");
99    TEST_EQ(key->len, *buf_key_len, "RSAPublicKeyFromBuf() len");
100    TEST_EQ(key->n0inv, 0xF00D2345, "RSAPublicKeyFromBuf() n0inv");
101    TEST_PTR_NEQ(key->n, NULL, "RSAPublicKeyFromBuf() n ptr");
102    TEST_EQ(((uint8_t*)key->n)[0], 100, "RSAPublicKeyFromBuf() n start");
103    TEST_EQ(((uint8_t*)key->n)[key_len - 1], 101,
104            "RSAPublicKeyFromBuf() n end");
105    TEST_PTR_NEQ(key->rr, NULL, "RSAPublicKeyFromBuf() rr ptr");
106    TEST_EQ(((uint8_t*)key->rr)[0], 120, "RSAPublicKeyFromBuf() rr start");
107    TEST_EQ(((uint8_t*)key->rr)[key_len - 1], 121,
108            "RSAPublicKeyFromBuf() rr end");
109    RSAPublicKeyFree(key);
110
111    /* Underflow and overflow */
112    TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 - 1), NULL,
113                "RSAPublicKeyFromBuf() underflow");
114    TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL,
115                "RSAPublicKeyFromBuf() overflow");
116
117    /* Invalid key length in buffer */
118    *buf_key_len = key_len / sizeof(uint32_t) + 1;
119    TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL,
120                "RSAPublicKeyFromBuf() invalid key length");
121
122    /* Valid key length in buffer, but for some other length key */
123    *buf_key_len = (RSA1024NUMBYTES << ((i + 1) & 3)) / sizeof(uint32_t);
124    TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL,
125                "RSAPublicKeyFromBuf() key length for wrong key");
126  }
127  free(buf);
128}
129
130/* Test verifying binary */
131static void TestVerifyBinary(void) {
132  RSAPublicKey key;
133  uint8_t keybuf[8 + 2 * RSA1024NUMBYTES];
134  uint32_t* keybuf_len = (uint32_t*)keybuf;
135  uint8_t buf[120];
136  uint8_t sig[4];
137
138  *keybuf_len = RSA1024NUMBYTES / sizeof(uint32_t);
139
140  /* Successful verification */
141  ResetMocks();
142  TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, 0),
143          1, "RSAVerifyBinary_f() success");
144  /* Successful verification using key blob */
145  TEST_EQ(RSAVerifyBinary_f(keybuf, NULL, buf, sizeof(buf), sig, 0),
146          1, "RSAVerifyBinary_f() success with keyblob");
147
148  /* Invalid algorithm */
149  ResetMocks();
150  TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, kNumAlgorithms),
151          0, "RSAVerifyBinary_f() invalid algorithm");
152  /* Must have either a key or a key blob */
153  ResetMocks();
154  TEST_EQ(RSAVerifyBinary_f(NULL, NULL, buf, sizeof(buf), sig, kNumAlgorithms),
155          0, "RSAVerifyBinary_f() no key or key_blob");
156  /* Wrong algorithm for key buffer (so key buffer is wrong size) */
157  ResetMocks();
158  TEST_EQ(RSAVerifyBinary_f(keybuf, NULL, buf, sizeof(buf), sig, 3),
159          0, "RSAVerifyBinary_f() wrong alg for key blob");
160
161  /* Simulate failed verification */
162  ResetMocks();
163  mock_rsaverify_retval = 0;
164  TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, 0),
165          0, "RSAVerifyBinary_f() bad verify");
166}
167
168/* Test verifying binary with digest */
169static void TestVerifyBinaryWithDigest(void) {
170  RSAPublicKey key;
171  uint8_t keybuf[8 + 2 * RSA1024NUMBYTES];
172  uint32_t* keybuf_len = (uint32_t*)keybuf;
173  uint8_t digest[120];
174  uint8_t sig[4];
175
176  *keybuf_len = RSA1024NUMBYTES / sizeof(uint32_t);
177
178  /* Successful verification */
179  ResetMocks();
180  TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, 0),
181          1, "RSAVerifyBinaryWithDigest_f() success");
182  /* Successful verification using key blob */
183  TEST_EQ(RSAVerifyBinaryWithDigest_f(keybuf, NULL, digest, sig, 0),
184          1, "RSAVerifyBinaryWithDigest_f() success with keyblob");
185
186  /* Invalid algorithm */
187  ResetMocks();
188  TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, kNumAlgorithms),
189          0, "RSAVerifyBinaryWithDigest_f() invalid algorithm");
190  /* Must have either a key or a key blob */
191  ResetMocks();
192  TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, NULL, digest, sig, kNumAlgorithms),
193          0, "RSAVerifyBinaryWithDigest_f() no key or key_blob");
194  /* Wrong algorithm for key buffer (so key buffer is wrong size) */
195  ResetMocks();
196  TEST_EQ(RSAVerifyBinaryWithDigest_f(keybuf, NULL, digest, sig, 3),
197          0, "RSAVerifyBinaryWithDigest_f() wrong alg for key blob");
198
199  /* Simulate failed verification */
200  ResetMocks();
201  mock_rsaverify_retval = 0;
202  TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, 0),
203          0, "RSAVerifyBinaryWithDigest_f() bad verify");
204}
205
206int main(int argc, char* argv[]) {
207  int error_code = 0;
208
209  /* Run tests */
210  TestUtils();
211  TestKeyFromBuffer();
212  TestVerifyBinary();
213  TestVerifyBinaryWithDigest();
214
215  if (!gTestSuccess)
216    error_code = 255;
217
218  return error_code;
219}
220