OpenDNSSEC-libhsm  2.1.7
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 
38 extern hsm_repository_t* parse_conf_repositories(const char* cfgfile);
39 
40 #define HSMSPEED_THREADS_MAX 2048
41 
42 /* Algorithm identifier and name */
43 ldns_algorithm algorithm = LDNS_RSASHA1;
44 const char *algoname = "RSA/SHA1";
45 
46 extern char *optarg;
47 char *progname = NULL;
48 
49 typedef struct {
50  unsigned int id;
53  unsigned int iterations;
54 } sign_arg_t;
55 
56 static void
57 usage ()
58 {
59  fprintf(stderr,
60  "usage: %s "
61  "[-c config] -r repository [-i iterations] [-s keysize] [-t threads]\n",
62  progname);
63 }
64 
65 static void *
66 sign (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 
126 int
127 main (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
const char * algoname
Definition: hsmspeed.c:44
hsm_repository_t * parse_conf_repositories(const char *cfgfile)
Definition: confparser.c:51
char * progname
Definition: hsmspeed.c:47
#define HSMSPEED_THREADS_MAX
Definition: hsmspeed.c:40
char * optarg
hsm_ctx_t * ctx
Definition: hsmutil.c:48
char * hsm_get_error(hsm_ctx_t *gctx)
Definition: libhsm.c:3502
char * hsm_get_key_id(hsm_ctx_t *ctx, const libhsm_key_t *key)
Definition: libhsm.c:3147
hsm_ctx_t * hsm_create_context()
Definition: libhsm.c:2455
ldns_rr * hsm_get_dnskey(hsm_ctx_t *ctx, const libhsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition: libhsm.c:3355
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:3242
libhsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2634
int hsm_open2(hsm_repository_t *rlist, char *(pin_callback)(unsigned int, const char *, unsigned int))
Definition: libhsm.c:2378
void hsm_close()
Definition: libhsm.c:2445
int hsm_remove_key(hsm_ctx_t *ctx, libhsm_key_t *key)
Definition: libhsm.c:3108
void hsm_destroy_context(hsm_ctx_t *ctx)
Definition: libhsm.c:2520
hsm_sign_params_t * hsm_sign_params_new()
Definition: libhsm.c:2529
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition: libhsm.c:2546
#define HSM_OK
Definition: libhsm.h:65
char * hsm_prompt_pin(unsigned int id, const char *repository, unsigned int mode)
Definition: pin.c:228
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