blob: 278cb2961fc784a787333d1e005d7b6e05fa6143 [file] [log] [blame]
Gaurav Shahe268eef2010-03-22 16:02:12 -07001/* Copyright (c) 2010 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 * Timing benchmark for verifying a firmware image.
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10
11#include "file_keys.h"
12#include "firmware_image.h"
13#include "padding.h"
14#include "rsa_utility.h"
15#include "timer_utils.h"
16#include "utility.h"
17
18#define FILE_NAME_SIZE 128
19#define NUM_OPERATIONS 100 /* Number of verify operations to time. */
20#define FIRMWARE_SIZE_SMALL 512000
21#define FIRMWARE_SIZE_MEDIUM 1024000
22#define FIRMWARE_SIZE_LARGE 4096000
23
24uint8_t* GenerateTestFirmwareBlob(int algorithm,
25 int firmware_len,
26 const uint8_t* firmware_sign_key,
27 const char* root_key_file,
28 const char* firmware_sign_key_file) {
29 FirmwareImage* image = FirmwareImageNew();
30 uint8_t* firmware_blob = NULL;
31 uint64_t firmware_blob_len = 0;
32
33 Memcpy(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE);
34 image->firmware_sign_algorithm = algorithm;
35 image->firmware_sign_key = (uint8_t*) Malloc(
36 RSAProcessedKeySize(image->firmware_sign_algorithm));
37 Memcpy(image->firmware_sign_key, firmware_sign_key,
38 RSAProcessedKeySize(image->firmware_sign_algorithm));
39 image->firmware_key_version = 1;
40
41 /* Update correct header length. */
42 image->header_len = GetFirmwareHeaderLen(image);
43
44 /* Calculate SHA-512 digest on header and populate header_checksum. */
45 CalculateFirmwareHeaderChecksum(image, image->header_checksum);
46
47 /* Populate firmware and preamble with dummy data. */
48 image->firmware_version = 1;
49 image->firmware_len = firmware_len;
50 image->preamble_signature = image->firmware_signature = NULL;
51 Memset(image->preamble, 'P', FIRMWARE_PREAMBLE_SIZE);
52 image->firmware_data = Malloc(image->firmware_len);
53 Memset(image->firmware_data, 'F', image->firmware_len);
54
55 if (!AddFirmwareKeySignature(image, root_key_file)) {
56 fprintf(stderr, "Couldn't create key signature.\n");
57 FirmwareImageFree(image);
58 return NULL;
59 }
60
61 if (!AddFirmwareSignature(image, firmware_sign_key_file)) {
62 fprintf(stderr, "Couldn't create firmware and preamble signature.\n");
63 FirmwareImageFree(image);
64 return NULL;
65 }
66 firmware_blob = GetFirmwareBlob(image, &firmware_blob_len);
67 FirmwareImageFree(image);
68 return firmware_blob;
69}
70
71int SpeedTestAlgorithm(int algorithm) {
72 int i, key_size, error_code = 0;
73 ClockTimerState ct;
74 double msecs;
75 uint64_t len;
76 uint8_t* firmware_sign_key = NULL;
77 uint8_t* root_key_blob = NULL;
78 char firmware_sign_key_file[FILE_NAME_SIZE];
79 char file_name[FILE_NAME_SIZE];
80 char* sha_strings[] = { /* Maps algorithm->SHA algorithm. */
81 "sha1", "sha256", "sha512", /* RSA-1024 */
82 "sha1", "sha256", "sha512", /* RSA-2048 */
83 "sha1", "sha256", "sha512", /* RSA-4096 */
84 "sha1", "sha256", "sha512", /* RSA-8192 */
85 };
86 /* Test for three different firmware sizes. */
87 uint8_t* firmware_blob_small = NULL;
88 uint8_t* firmware_blob_medium = NULL;
89 uint8_t* firmware_blob_large = NULL;
90
91 key_size = siglen_map[algorithm] * 8; /* in bits. */
92 snprintf(firmware_sign_key_file, FILE_NAME_SIZE, "testkeys/key_rsa%d.pem",
93 key_size);
94
95 snprintf(file_name, FILE_NAME_SIZE, "testkeys/key_rsa%d.keyb", key_size);
96 firmware_sign_key = BufferFromFile(file_name, &len);
97 if (!firmware_sign_key) {
98 fprintf(stderr, "Couldn't read pre-processed firmware signing key.\n");
99 error_code = 1;
100 goto cleanup;
101 }
102
103 /* Generate test images. */
104 firmware_blob_small = GenerateTestFirmwareBlob(algorithm,
105 FIRMWARE_SIZE_SMALL,
106 firmware_sign_key,
107 "testkeys/key_rsa8192.pem",
108 firmware_sign_key_file);
109 firmware_blob_medium = GenerateTestFirmwareBlob(algorithm,
110 FIRMWARE_SIZE_MEDIUM,
111 firmware_sign_key,
112 "testkeys/key_rsa8192.pem",
113 firmware_sign_key_file);
114 firmware_blob_large = GenerateTestFirmwareBlob(algorithm,
115 FIRMWARE_SIZE_LARGE,
116 firmware_sign_key,
117 "testkeys/key_rsa8192.pem",
118 firmware_sign_key_file);
119 if (!firmware_blob_small || !firmware_blob_medium || !firmware_blob_large) {
120 fprintf(stderr, "Couldn't generate test firmware images.\n");
121 error_code = 1;
122 goto cleanup;
123 }
124
125 root_key_blob = BufferFromFile("testkeys/key_rsa8192.keyb", &len);
126 if (!root_key_blob) {
127 fprintf(stderr, "Couldn't read pre-processed rootkey.\n");
128 error_code = 1;
129 goto cleanup;
130 }
131
132 /* Small.*/
133 StartTimer(&ct);
134 for (i = 0; i < NUM_OPERATIONS; ++i) {
135 if (VERIFY_FIRMWARE_SUCCESS !=
136 VerifyFirmware(root_key_blob, firmware_blob_small, 0))
137 fprintf(stderr, "Warning: Firmware Verification Failed.\n");
138 }
139 StopTimer(&ct);
140 msecs = (float) GetDurationMsecs(&ct) / NUM_OPERATIONS;
141 fprintf(stderr,
142 "# Firmware (Small, Algo = %s):"
143 "\t%.02f ms/verification\n",
144 algo_strings[algorithm], msecs);
145 fprintf(stdout, "ms_firmware_sm_rsa%d_%s:%.02f\n",
146 key_size,
147 sha_strings[algorithm],
148 msecs);
149
150 /* Medium. */
151 StartTimer(&ct);
152 for (i = 0; i < NUM_OPERATIONS; ++i) {
153 if (VERIFY_FIRMWARE_SUCCESS !=
154 VerifyFirmware(root_key_blob, firmware_blob_medium, 0))
155 fprintf(stderr, "Warning: Firmware Verification Failed.\n");
156 }
157 StopTimer(&ct);
158 msecs = (float) GetDurationMsecs(&ct) / NUM_OPERATIONS;
159 fprintf(stderr,
160 "# Firmware (Medium, Algo = %s):"
161 "\t%.02f ms/verification\n",
162 algo_strings[algorithm], msecs);
163 fprintf(stdout, "ms_firmware_med_rsa%d_%s:%.02f\n",
164 key_size,
165 sha_strings[algorithm],
166 msecs);
167
168
169 /* Large */
170 StartTimer(&ct);
171 for (i = 0; i < NUM_OPERATIONS; ++i) {
172 if (VERIFY_FIRMWARE_SUCCESS !=
173 VerifyFirmware(root_key_blob, firmware_blob_large, 0))
174 fprintf(stderr, "Warning: Firmware Verification Failed.\n");
175 }
176 StopTimer(&ct);
177 msecs = (float) GetDurationMsecs(&ct) / NUM_OPERATIONS;
178 fprintf(stderr,
179 "# Firmware (Large, Algorithm = %s):"
180 "\t%.02f ms/verification\n",
181 algo_strings[algorithm], msecs);
182 fprintf(stdout, "ms_firmware_large_rsa%d_%s:%.02f\n",
183 key_size,
184 sha_strings[algorithm],
185 msecs);
186
187 cleanup:
188 Free(root_key_blob);
189 Free(firmware_blob_large);
190 Free(firmware_blob_medium);
191 Free(firmware_blob_small);
192 return error_code;
193}
194
195
196int main(int argc, char* argv[]) {
197 int i, error_code = 0;
198 for (i = 0; i < kNumAlgorithms; ++i) {
199 if (0 != (error_code = SpeedTestAlgorithm(i)))
200 return error_code;
201 }
202 return 0;
203}