OpenDNSSEC-libhsm  1.4.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 #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, hsm_prompt_pin);
195  if (result) {
196  fprintf(stderr, "hsm_open() returned %d\n", result);
197  exit(-1);
198  }
199 
200  /* Create HSM context */
201  ctx = hsm_create_context();
202  if (! ctx) {
203  fprintf(stderr, "hsm_create_context() returned error\n");
204  exit(-1);
205  }
206 
207  /* Generate a temporary key */
208  fprintf(stderr, "Generating temporary key...\n");
209  key = hsm_generate_rsa_key(ctx, repository, keysize);
210  if (key) {
211  char *id = hsm_get_key_id(ctx, key);
212  fprintf(stderr, "Temporary key created: %s\n", id);
213  free(id);
214  } else {
215  fprintf(stderr, "Could not generate a key pair in repository \"%s\"\n", repository);
216  exit(-1);
217  }
218 
219  /* Prepare threads */
220  pthread_attr_init(&thread_attr);
221  pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
222 
223  for (n=0; n<threads; n++) {
224  sign_arg_array[n].id = n;
225  sign_arg_array[n].ctx = hsm_create_context();
226  if (! sign_arg_array[n].ctx) {
227  fprintf(stderr, "hsm_create_context() returned error\n");
228  exit(-1);
229  }
230  sign_arg_array[n].key = key;
231  sign_arg_array[n].iterations = iterations;
232  }
233 
234  fprintf(stderr, "Signing %d RRsets with %s using %d %s...\n",
235  iterations, algoname, threads, (threads > 1 ? "threads" : "thread"));
236  gettimeofday(&start, NULL);
237 
238  /* Create threads for signing */
239  for (n=0; n<threads; n++) {
240  result = pthread_create(&thread_array[n], &thread_attr,
241  sign, (void *) &sign_arg_array[n]);
242  if (result) {
243  fprintf(stderr, "pthread_create() returned %d\n", result);
244  exit(EXIT_FAILURE);
245  }
246  }
247 
248  /* Wait for threads to finish */
249  for (n=0; n<threads; n++) {
250  result = pthread_join(thread_array[n], &thread_status);
251  if (result) {
252  fprintf(stderr, "pthread_join() returned %d\n", result);
253  exit(EXIT_FAILURE);
254  }
255  }
256 
257  gettimeofday(&end, NULL);
258  fprintf(stderr, "Signing done.\n");
259 
260  /* Report results */
261  end.tv_sec -= start.tv_sec;
262  end.tv_usec-= start.tv_usec;
263  elapsed =(double)(end.tv_sec)+(double)(end.tv_usec)*.000001;
264  speed = iterations / elapsed * threads;
265  printf("%d %s, %d signatures per thread, %.2f sig/s (RSA %d bits)\n",
266  threads, (threads > 1 ? "threads" : "thread"), iterations,
267  speed, keysize);
268 
269  /* Delete temporary key */
270  fprintf(stderr, "Deleting temporary key...\n");
271  result = hsm_remove_key(ctx, key);
272  if (result) {
273  fprintf(stderr, "hsm_remove_key() returned %d\n", result);
274  exit(-1);
275  }
276 
277  /* Clean up */
278  hsm_destroy_context(ctx);
279  (void) hsm_close();
280  if (config) free(config);
281 
282  return 0;
283 }
char * hsm_get_key_id(hsm_ctx_t *ctx, const hsm_key_t *key)
Definition: libhsm.c:2657
const char * error_action
Definition: libhsm.h:122
const char * algoname
Definition: hsmspeed.c:42
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition: libhsm.c:2222
hsm_key_t * key
Definition: hsmspeed.c:50
void usage()
Definition: hsmspeed.c:55
ldns_rdf * owner
Definition: libhsmdns.h:47
int hsm_close()
Definition: libhsm.c:2133
ldns_rr * hsm_get_dnskey(hsm_ctx_t *ctx, const hsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition: libhsm.c:2970
void hsm_destroy_context(hsm_ctx_t *ctx)
Definition: libhsm.c:2196
int hsm_open(const char *config, char *(pin_callback)(unsigned int, const char *, unsigned int))
Definition: libhsm.c:1979
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:2205
ldns_algorithm algorithm
Definition: libhsmdns.h:37
char * progname
Definition: hsmspeed.c:45
char error_message[HSM_ERROR_MSGSIZE]
Definition: libhsm.h:125
#define HSMSPEED_THREADS_MAX
Definition: hsmspeed.c:38
int hsm_remove_key(hsm_ctx_t *ctx, hsm_key_t *key)
Definition: libhsm.c:2609
char * optarg
hsm_ctx_t * hsm_create_context()
Definition: libhsm.c:2140
hsm_ctx_t * ctx
Definition: hsmspeed.c:49
ldns_algorithm algorithm
Definition: hsmspeed.c:41
unsigned int id
Definition: hsmspeed.c:48
hsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2324
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:2749