fuzz: Add fuzzing boilerplate
[strongswan.git] / scripts / pubkey_speed.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <stdio.h>
17 #include <time.h>
18 #include <library.h>
19 #include <utils/debug.h>
20 #include <credentials/keys/private_key.h>
21
22 void start_timing(struct timespec *start)
23 {
24 clock_gettime(CLOCK_THREAD_CPUTIME_ID, start);
25 }
26
27 double end_timing(struct timespec *start)
28 {
29 struct timespec end;
30
31 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
32 return (end.tv_nsec - start->tv_nsec) / 1000000000.0 +
33 (end.tv_sec - start->tv_sec) * 1.0;
34 }
35
36 static void usage()
37 {
38 printf("usage: pubkey_speed plugins rsa|ecdsa rounds < key\n");
39 exit(1);
40 }
41
42 int main(int argc, char *argv[])
43 {
44 private_key_t *private;
45 public_key_t *public;
46 struct timespec timing;
47 int round, rounds, read;
48 char buf[8096], *pos = buf;
49 key_type_t type = KEY_ANY;
50 signature_scheme_t scheme = SIGN_UNKNOWN;
51 chunk_t keydata, *sigs, data;
52
53 if (argc < 4)
54 {
55 usage();
56 }
57
58 rounds = atoi(argv[3]);
59
60 if (streq(argv[2], "rsa"))
61 {
62 type = KEY_RSA;
63 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
64 }
65 else if (streq(argv[2], "ecdsa"))
66 {
67 type = KEY_ECDSA;
68 }
69 else
70 {
71 usage();
72 }
73
74 library_init(NULL, "pubkey_speed");
75 lib->plugins->load(lib->plugins, argv[1]);
76 atexit(library_deinit);
77
78 keydata = chunk_create(buf, 0);
79 while ((read = fread(pos, 1, sizeof(buf) - (pos - buf), stdin)))
80 {
81 pos += read;
82 keydata.len += read;
83 }
84
85 private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
86 BUILD_BLOB_PEM, keydata, BUILD_END);
87 if (!private)
88 {
89 printf("parsing private key failed.\n");
90 exit(1);
91 }
92 if (type == KEY_ECDSA)
93 {
94 switch (private->get_keysize(private))
95 {
96 case 256:
97 scheme = SIGN_ECDSA_256;
98 break;
99 case 384:
100 scheme = SIGN_ECDSA_384;
101 break;
102 case 521:
103 scheme = SIGN_ECDSA_521;
104 break;
105 default:
106 printf("%d bit ECDSA private key size not supported",
107 private->get_keysize(private));
108 exit(1);
109 }
110 }
111
112 printf("%4d bit %N: ", private->get_keysize(private),
113 key_type_names, type);
114
115 sigs = malloc(sizeof(chunk_t) * rounds);
116
117 data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07);
118 start_timing(&timing);
119 for (round = 0; round < rounds; round++)
120 {
121 if (!private->sign(private, scheme, data, &sigs[round]))
122 {
123 printf("creating signature failed\n");
124 exit(1);
125 }
126 };
127 printf("sign()/s: %8.1f ", rounds / end_timing(&timing));
128
129 public = private->get_public_key(private);
130 if (!public)
131 {
132 printf("extracting public key failed\n");
133 exit(1);
134 }
135 start_timing(&timing);
136 for (round = 0; round < rounds; round++)
137 {
138 if (!public->verify(public, scheme, data, sigs[round]))
139 {
140 printf("signature verification failed\n");
141 exit(1);
142 }
143 }
144 printf("verify()/s: %8.1f\n", rounds / end_timing(&timing));
145 public->destroy(public);
146 private->destroy(private);
147
148 for (round = 0; round < rounds; round++)
149 {
150 free(sigs[round].ptr);
151 }
152 free(sigs);
153 return 0;
154 }