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