OpenDNSSEC-libhsm 2.1.10
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
46extern char *optarg;
47char *progname = NULL;
48
49typedef struct {
50 unsigned int id;
53 unsigned int iterations;
55
56static void
57usage ()
58{
59 fprintf(stderr,
60 "usage: %s "
61 "[-c config] -r repository [-i iterations] [-s keysize] [-t threads]\n",
62 progname);
63}
64
65static void *
66sign (void *arg)
67{
68 hsm_ctx_t *ctx = NULL;
69 libhsm_key_t *key = NULL;
70
71 size_t i;
72 unsigned int iterations = 0;
73
74 ldns_rr_list *rrset;
75 ldns_rr *rr, *sig, *dnskey_rr;
76 ldns_status status;
77 hsm_sign_params_t *sign_params;
78
79 sign_arg_t *sign_arg = arg;
80
81 ctx = sign_arg->ctx;
82 key = sign_arg->key;
83 iterations = sign_arg->iterations;
84
85 fprintf(stderr, "Signer thread #%d started...\n", sign_arg->id);
86
87 /* Prepare dummy RRset for signing */
88 rrset = ldns_rr_list_new();
89 status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 123.123.123.123", 0, NULL, NULL);
90 if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr);
91 status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 124.124.124.124", 0, NULL, NULL);
92 if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr);
93 sign_params = hsm_sign_params_new();
94 sign_params->algorithm = algorithm;
95 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "opendnssec.se.");
96 dnskey_rr = hsm_get_dnskey(ctx, key, sign_params);
97 sign_params->keytag = ldns_calc_keytag(dnskey_rr);
98
99 /* Do some signing */
100 for (i=0; i<iterations; i++) {
101 sig = hsm_sign_rrset(ctx, rrset, key, sign_params);
102 if (! sig) {
103 fprintf(stderr,
104 "hsm_sign_rrset() returned error: %s in %s\n",
107 );
108 break;
109 }
110 ldns_rr_free(sig);
111 }
112
113 /* Clean up */
114 ldns_rr_list_deep_free(rrset);
115 hsm_sign_params_free(sign_params);
116 ldns_rr_free(dnskey_rr);
118
119 fprintf(stderr, "Signer thread #%d done.\n", sign_arg->id);
120
121 pthread_exit(NULL);
122 return NULL;
123}
124
125
126int
127main (int argc, char *argv[])
128{
129 int result;
130
131 hsm_ctx_t *ctx = NULL;
132 libhsm_key_t *key = NULL;
133 unsigned int keysize = 1024;
134 unsigned int iterations = 1;
135 unsigned int threads = 1;
136
137 static struct timeval start,end;
138
139 char *config = NULL;
140 const char *repository = NULL;
141
142 sign_arg_t sign_arg_array[HSMSPEED_THREADS_MAX];
143
144 pthread_t thread_array[HSMSPEED_THREADS_MAX];
145 pthread_attr_t thread_attr;
146 void *thread_status;
147
148 int ch;
149 unsigned int n;
150 double elapsed, speed;
151
152 progname = argv[0];
153
154 while ((ch = getopt(argc, argv, "c:i:r:s:t:")) != -1) {
155 switch (ch) {
156 case 'c':
157 config = strdup(optarg);
158 break;
159 case 'i':
160 iterations = atoi(optarg);
161 break;
162 case 'r':
163 repository = strdup(optarg);
164 break;
165 case 's':
166 keysize = atoi(optarg);
167 break;
168 case 't':
169 threads = atoi(optarg);
170 break;
171 default:
172 usage();
173 exit(1);
174 }
175 }
176
177 if (!repository) {
178 usage();
179 exit(1);
180 }
181
182 if (threads > HSMSPEED_THREADS_MAX) {
183 fprintf(stderr, "Number of threads specified over max, force using %d threads!\n", HSMSPEED_THREADS_MAX);
184 threads = HSMSPEED_THREADS_MAX;
185 }
186
187#if 0
188 if (!config) {
189 usage();
190 exit(1);
191 }
192#endif
193
194 /* Open HSM library */
195 fprintf(stderr, "Opening HSM Library...\n");
196 result = hsm_open2(parse_conf_repositories(config?config:HSM_DEFAULT_CONFIG), hsm_prompt_pin);
197 if (result != HSM_OK) {
198 char* error = hsm_get_error(NULL);
199 if (error != NULL) {
200 fprintf(stderr,"%s\n", error);
201 free(error);
202 }
203 exit(-1);
204 }
205
206 /* Create HSM context */
208 if (! ctx) {
209 fprintf(stderr, "hsm_create_context() returned error\n");
210 exit(-1);
211 }
212
213 /* Generate a temporary key */
214 fprintf(stderr, "Generating temporary key...\n");
215 key = hsm_generate_rsa_key(ctx, repository, keysize);
216 if (key) {
217 char *id = hsm_get_key_id(ctx, key);
218 fprintf(stderr, "Temporary key created: %s\n", id);
219 free(id);
220 } else {
221 fprintf(stderr, "Could not generate a key pair in repository \"%s\"\n", repository);
222 exit(-1);
223 }
224
225 /* Prepare threads */
226 pthread_attr_init(&thread_attr);
227 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
228
229 for (n=0; n<threads; n++) {
230 sign_arg_array[n].id = n;
231 sign_arg_array[n].ctx = hsm_create_context();
232 if (! sign_arg_array[n].ctx) {
233 fprintf(stderr, "hsm_create_context() returned error\n");
234 exit(-1);
235 }
236 sign_arg_array[n].key = key;
237 sign_arg_array[n].iterations = iterations;
238 }
239
240 fprintf(stderr, "Signing %d RRsets with %s using %d %s...\n",
241 iterations, algoname, threads, (threads > 1 ? "threads" : "thread"));
242 gettimeofday(&start, NULL);
243
244 /* Create threads for signing */
245 for (n=0; n<threads; n++) {
246 result = pthread_create(&thread_array[n], &thread_attr,
247 sign, (void *) &sign_arg_array[n]);
248 if (result) {
249 fprintf(stderr, "pthread_create() returned %d\n", result);
250 exit(EXIT_FAILURE);
251 }
252 }
253
254 /* Wait for threads to finish */
255 for (n=0; n<threads; n++) {
256 result = pthread_join(thread_array[n], &thread_status);
257 if (result) {
258 fprintf(stderr, "pthread_join() returned %d\n", result);
259 exit(EXIT_FAILURE);
260 }
261 }
262
263 gettimeofday(&end, NULL);
264 fprintf(stderr, "Signing done.\n");
265
266 /* Report results */
267 end.tv_sec -= start.tv_sec;
268 end.tv_usec-= start.tv_usec;
269 elapsed =(double)(end.tv_sec)+(double)(end.tv_usec)*.000001;
270 speed = iterations / elapsed * threads;
271 printf("%d %s, %d signatures per thread, %.2f sig/s (RSA %d bits)\n",
272 threads, (threads > 1 ? "threads" : "thread"), iterations,
273 speed, keysize);
274
275 /* Delete temporary key */
276 fprintf(stderr, "Deleting temporary key...\n");
277 result = hsm_remove_key(ctx, key);
278 if (result) {
279 fprintf(stderr, "hsm_remove_key() returned %d\n", result);
280 exit(-1);
281 }
282
283 /* Clean up */
285 (void) hsm_close();
286 if (config) free(config);
287
288 return 0;
289}
ldns_algorithm algorithm
Definition: hsmspeed.c:43
int main(int argc, char *argv[])
Definition: hsmspeed.c:127
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:47
#define HSMSPEED_THREADS_MAX
Definition: hsmspeed.c:40
char * optarg
hsm_ctx_t * ctx
Definition: hsmutil.c:48
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:3252
char * hsm_get_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3512
libhsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2644
hsm_sign_params_t * hsm_sign_params_new()
Definition: libhsm.c:2539
char * hsm_get_key_id(hsm_ctx_t *ctx, const libhsm_key_t *key)
Definition: libhsm.c:3157
int hsm_open2(hsm_repository_t *rlist, char *(pin_callback)(unsigned int, const char *, unsigned int))
Definition: libhsm.c:2388
ldns_rr * hsm_get_dnskey(hsm_ctx_t *ctx, const libhsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition: libhsm.c:3365
void hsm_close()
Definition: libhsm.c:2455
int hsm_remove_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition: libhsm.c:3118
void hsm_destroy_context(hsm_ctx_t *ctx)
Definition: libhsm.c:2530
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition: libhsm.c:2556
hsm_ctx_t * hsm_create_context()
Definition: libhsm.c:2465
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:50
unsigned int iterations
Definition: hsmspeed.c:53
libhsm_key_t * key
Definition: hsmspeed.c:52
hsm_ctx_t * ctx
Definition: hsmspeed.c:51