OpenDNSSEC-libhsm 2.1.13
hsmspeed.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 Nominet UK.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28
29#include <stdio.h>
30#include <string.h>
31#include <stdlib.h>
32#include <unistd.h>
33#include <pthread.h>
34
35#include "libhsm.h"
36#include <libhsmdns.h>
37
38extern hsm_repository_t* parse_conf_repositories(const char* cfgfile);
39
40#define HSMSPEED_THREADS_MAX 2048
41
42/* Algorithm identifier and name */
43ldns_algorithm algorithm = LDNS_RSASHA1;
44const char *algoname = "RSA/SHA1";
45
46char *progname = NULL;
47
48typedef struct {
49 unsigned int id;
52 unsigned int iterations;
54
55static void
56usage ()
57{
58 fprintf(stderr,
59 "usage: %s "
60 "[-c config] -r repository [-i iterations] [-s keysize] [-t threads]\n",
61 progname);
62}
63
64static void *
65sign (void *arg)
66{
67 hsm_ctx_t *ctx = NULL;
68 libhsm_key_t *key = NULL;
69
70 size_t i;
71 unsigned int iterations = 0;
72
73 ldns_rr_list *rrset;
74 ldns_rr *rr, *sig, *dnskey_rr;
75 ldns_status status;
76 hsm_sign_params_t *sign_params;
77
78 sign_arg_t *sign_arg = arg;
79
80 ctx = sign_arg->ctx;
81 key = sign_arg->key;
82 iterations = sign_arg->iterations;
83
84 fprintf(stderr, "Signer thread #%d started...\n", sign_arg->id);
85
86 /* Prepare dummy RRset for signing */
87 rrset = ldns_rr_list_new();
88 status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 123.123.123.123", 0, NULL, NULL);
89 if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr);
90 status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 124.124.124.124", 0, NULL, NULL);
91 if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr);
92 sign_params = hsm_sign_params_new();
93 sign_params->algorithm = algorithm;
94 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "opendnssec.se.");
95 dnskey_rr = hsm_get_dnskey(ctx, key, sign_params);
96 sign_params->keytag = ldns_calc_keytag(dnskey_rr);
97
98 /* Do some signing */
99 for (i=0; i<iterations; i++) {
100 sig = hsm_sign_rrset(ctx, rrset, key, sign_params);
101 if (! sig) {
102 fprintf(stderr,
103 "hsm_sign_rrset() returned error: %s in %s\n",
106 );
107 break;
108 }
109 ldns_rr_free(sig);
110 }
111
112 /* Clean up */
113 ldns_rr_list_deep_free(rrset);
114 hsm_sign_params_free(sign_params);
115 ldns_rr_free(dnskey_rr);
117
118 fprintf(stderr, "Signer thread #%d done.\n", sign_arg->id);
119
120 pthread_exit(NULL);
121 return NULL;
122}
123
124
125int
126main (int argc, char *argv[])
127{
128 int result;
129
130 hsm_ctx_t *ctx = NULL;
131 libhsm_key_t *key = NULL;
132 unsigned int keysize = 1024;
133 unsigned int iterations = 1;
134 unsigned int threads = 1;
135
136 static struct timeval start,end;
137
138 char *config = NULL;
139 const char *repository = NULL;
140
141 sign_arg_t sign_arg_array[HSMSPEED_THREADS_MAX];
142
143 pthread_t thread_array[HSMSPEED_THREADS_MAX];
144 pthread_attr_t thread_attr;
145 void *thread_status;
146
147 int ch;
148 unsigned int n;
149 double elapsed, speed;
150
151 progname = argv[0];
152
153 while ((ch = getopt(argc, argv, "c:i:r:s:t:")) != -1) {
154 switch (ch) {
155 case 'c':
156 config = strdup(optarg);
157 break;
158 case 'i':
159 iterations = atoi(optarg);
160 break;
161 case 'r':
162 repository = strdup(optarg);
163 break;
164 case 's':
165 keysize = atoi(optarg);
166 break;
167 case 't':
168 threads = atoi(optarg);
169 break;
170 default:
171 usage();
172 exit(1);
173 }
174 }
175
176 if (!repository) {
177 usage();
178 exit(1);
179 }
180
181 if (threads > HSMSPEED_THREADS_MAX) {
182 fprintf(stderr, "Number of threads specified over max, force using %d threads!\n", HSMSPEED_THREADS_MAX);
183 threads = HSMSPEED_THREADS_MAX;
184 }
185
186#if 0
187 if (!config) {
188 usage();
189 exit(1);
190 }
191#endif
192
193 /* Open HSM library */
194 fprintf(stderr, "Opening HSM Library...\n");
195 result = hsm_open2(parse_conf_repositories(config?config:HSM_DEFAULT_CONFIG), hsm_prompt_pin);
196 if (result != HSM_OK) {
197 char* error = hsm_get_error(NULL);
198 if (error != NULL) {
199 fprintf(stderr,"%s\n", error);
200 free(error);
201 }
202 exit(-1);
203 }
204
205 /* Create HSM context */
207 if (! ctx) {
208 fprintf(stderr, "hsm_create_context() returned error\n");
209 exit(-1);
210 }
211
212 /* Generate a temporary key */
213 fprintf(stderr, "Generating temporary key...\n");
214 key = hsm_generate_rsa_key(ctx, repository, keysize);
215 if (key) {
216 char *id = hsm_get_key_id(ctx, key);
217 fprintf(stderr, "Temporary key created: %s\n", id);
218 free(id);
219 } else {
220 fprintf(stderr, "Could not generate a key pair in repository \"%s\"\n", repository);
221 exit(-1);
222 }
223
224 /* Prepare threads */
225 pthread_attr_init(&thread_attr);
226 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
227
228 for (n=0; n<threads; n++) {
229 sign_arg_array[n].id = n;
230 sign_arg_array[n].ctx = hsm_create_context();
231 if (! sign_arg_array[n].ctx) {
232 fprintf(stderr, "hsm_create_context() returned error\n");
233 exit(-1);
234 }
235 sign_arg_array[n].key = key;
236 sign_arg_array[n].iterations = iterations;
237 }
238
239 fprintf(stderr, "Signing %d RRsets with %s using %d %s...\n",
240 iterations, algoname, threads, (threads > 1 ? "threads" : "thread"));
241 gettimeofday(&start, NULL);
242
243 /* Create threads for signing */
244 for (n=0; n<threads; n++) {
245 result = pthread_create(&thread_array[n], &thread_attr,
246 sign, (void *) &sign_arg_array[n]);
247 if (result) {
248 fprintf(stderr, "pthread_create() returned %d\n", result);
249 exit(EXIT_FAILURE);
250 }
251 }
252
253 /* Wait for threads to finish */
254 for (n=0; n<threads; n++) {
255 result = pthread_join(thread_array[n], &thread_status);
256 if (result) {
257 fprintf(stderr, "pthread_join() returned %d\n", result);
258 exit(EXIT_FAILURE);
259 }
260 }
261
262 gettimeofday(&end, NULL);
263 fprintf(stderr, "Signing done.\n");
264
265 /* Report results */
266 end.tv_sec -= start.tv_sec;
267 end.tv_usec-= start.tv_usec;
268 elapsed =(double)(end.tv_sec)+(double)(end.tv_usec)*.000001;
269 speed = iterations / elapsed * threads;
270 printf("%d %s, %d signatures per thread, %.2f sig/s (RSA %d bits)\n",
271 threads, (threads > 1 ? "threads" : "thread"), iterations,
272 speed, keysize);
273
274 /* Delete temporary key */
275 fprintf(stderr, "Deleting temporary key...\n");
276 result = hsm_remove_key(ctx, key);
277 if (result) {
278 fprintf(stderr, "hsm_remove_key() returned %d\n", result);
279 exit(-1);
280 }
281
282 /* Clean up */
284 (void) hsm_close();
285 if (config) free(config);
286
287 return 0;
288}
char * optarg
ldns_algorithm algorithm
Definition hsmspeed.c:43
int main(int argc, char *argv[])
Definition hsmspeed.c:126
hsm_repository_t * parse_conf_repositories(const char *cfgfile)
Definition confparser.c:51
const char * algoname
Definition hsmspeed.c:44
char * progname
Definition hsmspeed.c:46
#define HSMSPEED_THREADS_MAX
Definition hsmspeed.c:40
hsm_ctx_t * ctx
Definition hsmutil.c:46
ldns_rr * hsm_sign_rrset(hsm_ctx_t *ctx, const ldns_rr_list *rrset, const libhsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition libhsm.c:3154
char * hsm_get_error(hsm_ctx_t *gctx)
Definition libhsm.c:3414
libhsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition libhsm.c:2550
hsm_sign_params_t * hsm_sign_params_new()
Definition libhsm.c:2448
char * hsm_get_key_id(hsm_ctx_t *ctx, const libhsm_key_t *key)
Definition libhsm.c:3063
int hsm_open2(hsm_repository_t *rlist, char *(pin_callback)(unsigned int, const char *, unsigned int))
Definition libhsm.c:2297
ldns_rr * hsm_get_dnskey(hsm_ctx_t *ctx, const libhsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition libhsm.c:3267
void hsm_close()
Definition libhsm.c:2364
int hsm_remove_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition libhsm.c:3024
void hsm_destroy_context(hsm_ctx_t *ctx)
Definition libhsm.c:2439
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition libhsm.c:2462
hsm_ctx_t * hsm_create_context()
Definition libhsm.c:2374
char * hsm_prompt_pin(unsigned int id, const char *repository, unsigned int mode)
Definition pin.c:228
#define HSM_OK
Definition libhsm.h:65
char error_message[HSM_ERROR_MSGSIZE]
Definition libhsm.h:142
const char * error_action
Definition libhsm.h:139
ldns_algorithm algorithm
Definition libhsmdns.h:36
ldns_rdf * owner
Definition libhsmdns.h:46
uint16_t keytag
Definition libhsmdns.h:44
unsigned int id
Definition hsmspeed.c:49
unsigned int iterations
Definition hsmspeed.c:52
libhsm_key_t * key
Definition hsmspeed.c:51
hsm_ctx_t * ctx
Definition hsmspeed.c:50