]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/hashTimeLibCrypt/hashTimeLibCrypt.cpp
Security-57031.10.10.tar.gz
[apple/security.git] / SecurityTests / cspxutils / hashTimeLibCrypt / hashTimeLibCrypt.cpp
1 /*
2 * hashTimeLibCrypt.cpp - measure performance of libcrypt digest ops.
3 *
4 * Thjis is obsolete; hashTime does this a lot better,a dn it also measures raw
5 * CommonCrypto and CryptKit versions.
6 */
7
8 #include <openssl/sha.h>
9 #include <openssl/md5.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include "cputime.h"
14 #include "cspwrap.h"
15 #include "common.h"
16 #include "pbkdDigest.h"
17
18 /* enumerate digest algorithms our way */
19 typedef int HT_Alg;
20 enum {
21 HA_MD5 = 0,
22 HA_SHA1
23 };
24
25 #define FIRST_ALG HA_MD5
26 #define LAST_ALG HA_SHA1
27
28 static void usage(char **argv)
29 {
30 printf("Usage: %s [option ...]\n", argv[0]);
31 printf("Options:\n");
32 printf(" t=testspec; default=all\n");
33 printf(" test specs: c digest context setup/teardown\n");
34 printf(" b basic single block digest\n");
35 printf(" d digest lots of data\n");
36 printf(" l=loops (only valid if testspec is given)\n");
37 exit(1);
38 }
39
40 /* passed to each test */
41 typedef struct {
42 unsigned loops;
43 bool isSha;
44 } TestParams;
45
46 /* just digest context setup/teardown */
47 /* returns nonzero on error */
48 static int hashContext(
49 TestParams *params)
50 {
51 unsigned loop;
52 CPUTime startTime;
53 double timeSpentMs;
54 DigestCtx ctx;
55 int rtn;
56
57 startTime = CPUTimeRead();
58 for(loop=0; loop<params->loops; loop++) {
59 rtn = DigestCtxInit(&ctx, params->isSha);
60 if(!rtn) {
61 return -1;
62 }
63 }
64 timeSpentMs = CPUTimeDeltaMs(startTime, CPUTimeRead());
65
66 printf(" context setup/delete : %u ops in %.2f ms; %f ms/op\n",
67 params->loops, timeSpentMs, timeSpentMs / (double)params->loops);
68 return 0;
69 }
70
71 /* Minimal init/digest/final */
72 #define BASIC_BLOCK_SIZE 64 // to digest in bytes
73 #define MAX_DIGEST_SIZE 20 // we provide, no malloc below CSSM
74
75 static int hashBasic(
76 TestParams *params)
77 {
78 unsigned loop;
79 CPUTime startTime;
80 double timeSpentMs;
81 uint8 ptext[BASIC_BLOCK_SIZE];
82 uint8 digest[MAX_DIGEST_SIZE];
83 DigestCtx ctx;
84 int rtn;
85
86 /* random data, const thru the loops */
87 appGetRandomBytes(ptext, BASIC_BLOCK_SIZE);
88
89 /* start critical timing loop */
90 startTime = CPUTimeRead();
91 for(loop=0; loop<params->loops; loop++) {
92 rtn = DigestCtxInit(&ctx, params->isSha);
93 if(!rtn) {
94 return -1;
95 }
96 rtn = DigestCtxUpdate(&ctx, ptext, BASIC_BLOCK_SIZE);
97 if(!rtn) {
98 return -1;
99 }
100 rtn = DigestCtxFinal(&ctx, digest);
101 if(!rtn) {
102 return -1;
103 }
104 }
105 DigestCtxFree(&ctx);
106 timeSpentMs = CPUTimeDeltaMs(startTime, CPUTimeRead());
107 printf(" Digest one %u byte block : %u ops in %.2f ms; %f ms/op\n",
108 BASIC_BLOCK_SIZE, params->loops,
109 timeSpentMs, timeSpentMs / (double)params->loops);
110 return 0;
111 }
112
113 /* Lots of data */
114 #define PTEXT_SIZE 1000 // to digest in bytes
115 #define INNER_LOOPS 1000
116
117 static int hashDataRate(
118 TestParams *params)
119 {
120 unsigned loop;
121 unsigned iloop;
122 CPUTime startTime;
123 double timeSpent, timeSpentMs;
124 uint8 ptext[PTEXT_SIZE];
125 uint8 digest[MAX_DIGEST_SIZE];
126 DigestCtx ctx;
127 int rtn;
128
129 /* random data, const thru the loops */
130 appGetRandomBytes(ptext, PTEXT_SIZE);
131
132 /* start critical timing loop */
133 startTime = CPUTimeRead();
134 for(loop=0; loop<params->loops; loop++) {
135 rtn = DigestCtxInit(&ctx, params->isSha);
136 if(!rtn) {
137 return -1;
138 }
139 for(iloop=0; iloop<INNER_LOOPS; iloop++) {
140 rtn = DigestCtxUpdate(&ctx, ptext, PTEXT_SIZE);
141 if(!rtn) {
142 return -1;
143 }
144 }
145 rtn = DigestCtxFinal(&ctx, digest);
146 if(!rtn) {
147 return -1;
148 }
149 }
150 timeSpentMs = CPUTimeDeltaMs(startTime, CPUTimeRead());
151 timeSpent = timeSpentMs / 1000.0;
152
153 float bytesPerLoop = INNER_LOOPS * PTEXT_SIZE;
154 float totalBytes = params->loops * bytesPerLoop;
155
156 /* careful, KByte = 1024, ms = 1/1000 */
157 printf(" Digest %.0f bytes : %u ops in %.2f ms; %f ms/op, %.0f KBytes/s\n",
158 bytesPerLoop, params->loops,
159 timeSpentMs, timeSpentMs / (double)params->loops,
160 ((float)totalBytes / 1024.0) / timeSpent);
161 return 0;
162 }
163
164
165 typedef int (*testRunFcn)(TestParams *testParams);
166
167 /*
168 * Static declaration of a test
169 */
170 typedef struct {
171 const char *testName;
172 unsigned loops;
173 testRunFcn run;
174 char testSpec; // for t=xxx cmd line opt
175 } TestDefs;
176
177 static TestDefs testDefs[] =
178 {
179 { "Digest context setup/teardown",
180 100000,
181 hashContext,
182 'c',
183 },
184 { "Basic single block digest",
185 100000,
186 hashBasic,
187 'b',
188 },
189 { "Large data digest",
190 1000,
191 hashDataRate,
192 'd',
193 },
194 };
195
196 static void algToAlgId(
197 HT_Alg alg,
198 bool *isSha,
199 const char **algStr)
200 {
201 switch(alg) {
202 case HA_MD5:
203 *isSha = false;
204 *algStr = "MD5";
205 break;
206 case HA_SHA1:
207 *isSha = true;
208 *algStr = "SHA1";
209 break;
210 default:
211 printf("***algToAlgId screwup\n");
212 exit(1);
213 }
214 }
215
216 #define NUM_TESTS (sizeof(testDefs) / sizeof(testDefs[0]))
217
218 int main(int argc, char **argv)
219 {
220 TestParams testParams;
221 TestDefs *testDef;
222 int rtn;
223 int arg;
224 char *argp;
225 unsigned cmdLoops = 0; // can be specified in cmd line
226 // if not, use TestDefs.loops
227 char testSpec = '\0'; // allows specification of one test
228 // otherwise run all
229 HT_Alg alg;
230 const char *algStr;
231
232 for(arg=1; arg<argc; arg++) {
233 argp = argv[arg];
234 switch(argp[0]) {
235 case 't':
236 testSpec = argp[2];
237 break;
238 case 'l':
239 cmdLoops = atoi(&argp[2]);
240 break;
241 default:
242 usage(argv);
243 }
244 }
245
246 for(unsigned testNum=0; testNum<NUM_TESTS; testNum++) {
247 testDef = &testDefs[testNum];
248
249 if(testSpec && (testDef->testSpec != testSpec)) {
250 continue;
251 }
252 printf("%s:\n", testDef->testName);
253 if(cmdLoops) {
254 /* user specified */
255 testParams.loops = cmdLoops;
256 }
257 else {
258 /* default */
259 testParams.loops = testDef->loops;
260 }
261 for(alg=FIRST_ALG; alg<=LAST_ALG; alg++) {
262 algToAlgId(alg, &testParams.isSha, &algStr);
263 printf(" === %s ===\n", algStr);
264 rtn = testDef->run(&testParams);
265 if(rtn) {
266 printf("Test returned error\n");
267 exit(1);
268 }
269 }
270 }
271 return 0;
272 }