OpenDNSSEC-libhsm  1.3.16
hsmspeed.c
Go to the documentation of this file.
1 /*
2  * $Id: hsmspeed.c 3620 2010-07-27 07:58:00Z rb $
3  *
4  * Copyright (c) 2009 Nominet UK.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "config.h"
30 
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <pthread.h>
36 
37 #include <libhsm.h>
38 #include <libhsmdns.h>
39 
40 #define PTHREAD_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 void
58 {
59  fprintf(stderr,
60  "usage: %s "
61  "[-c config] -r repository [-i iterations] [-s keysize] [-t threads]\n",
62  progname);
63 }
64 
65 void *
66 sign (void *arg)
67 {
68  hsm_ctx_t *ctx = NULL;
69  hsm_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",
105  ctx->error_message,
106  ctx->error_action
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);
117  hsm_destroy_context(ctx);
118 
119  fprintf(stderr, "Signer thread #%d done.\n", sign_arg->id);
120 
121  pthread_exit(NULL);
122 }
123 
124 
125 int
126 main (int argc, char *argv[])
127 {
128  int result;
129 
130  hsm_ctx_t *ctx = NULL;
131  hsm_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[PTHREAD_THREADS_MAX];
142 
143  pthread_t thread_array[PTHREAD_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 0
182  if (!config) {
183  usage();
184  exit(1);
185  }
186 #endif
187 
188  /* Open HSM library */
189  fprintf(stderr, "Opening HSM Library...\n");
190  result = hsm_open(config, hsm_prompt_pin, NULL);
191  if (result) {
192  fprintf(stderr, "hsm_open() returned %d\n", result);
193  exit(-1);
194  }
195 
196  /* Create HSM context */
197  ctx = hsm_create_context();
198  if (! ctx) {
199  fprintf(stderr, "hsm_create_context() returned error\n");
200  exit(-1);
201  }
202 
203  /* Generate a temporary key */
204  fprintf(stderr, "Generating temporary key...\n");
205  key = hsm_generate_rsa_key(ctx, repository, keysize);
206  if (key) {
207  char *id = hsm_get_key_id(ctx, key);
208  fprintf(stderr, "Temporary key created: %s\n", id);
209  free(id);
210  } else {
211  fprintf(stderr, "Could not generate a key pair in repository \"%s\"\n", repository);
212  exit(-1);
213  }
214 
215  /* Prepare threads */
216  pthread_attr_init(&thread_attr);
217  pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
218 
219  for (n=0; n<threads; n++) {
220  sign_arg_array[n].id = n;
221  sign_arg_array[n].ctx = hsm_create_context();
222  if (! sign_arg_array[n].ctx) {
223  fprintf(stderr, "hsm_create_context() returned error\n");
224  exit(-1);
225  }
226  sign_arg_array[n].key = key;
227  sign_arg_array[n].iterations = iterations;
228  }
229 
230  fprintf(stderr, "Signing %d RRsets with %s using %d %s...\n",
231  iterations, algoname, threads, (threads > 1 ? "threads" : "thread"));
232  gettimeofday(&start, NULL);
233 
234  /* Create threads for signing */
235  for (n=0; n<threads; n++) {
236  result = pthread_create(&thread_array[n], &thread_attr,
237  sign, (void *) &sign_arg_array[n]);
238  if (result) {
239  fprintf(stderr, "pthread_create() returned %d\n", result);
240  exit(EXIT_FAILURE);
241  }
242  }
243 
244  /* Wait for threads to finish */
245  for (n=0; n<threads; n++) {
246  result = pthread_join(thread_array[n], &thread_status);
247  if (result) {
248  fprintf(stderr, "pthread_join() returned %d\n", result);
249  exit(EXIT_FAILURE);
250  }
251  }
252 
253  gettimeofday(&end, NULL);
254  fprintf(stderr, "Signing done.\n");
255 
256  /* Report results */
257  end.tv_sec -= start.tv_sec;
258  end.tv_usec-= start.tv_usec;
259  elapsed =(double)(end.tv_sec)+(double)(end.tv_usec)*.000001;
260  speed = iterations / elapsed * threads;
261  printf("%d %s, %d signatures per thread, %.2f sig/s (RSA %d bits)\n",
262  threads, (threads > 1 ? "threads" : "thread"), iterations,
263  speed, keysize);
264 
265  /* Delete temporary key */
266  fprintf(stderr, "Deleting temporary key...\n");
267  result = hsm_remove_key(ctx, key);
268  if (result) {
269  fprintf(stderr, "hsm_remove_key() returned %d\n", result);
270  exit(-1);
271  }
272 
273  /* Clean up */
274  hsm_destroy_context(ctx);
275  (void) hsm_close();
276  if (config) free(config);
277 
278  return 0;
279 }
char * hsm_get_key_id(hsm_ctx_t *ctx, const hsm_key_t *key)
Definition: libhsm.c:2197
char * hsm_prompt_pin(const char *repository, void *data)
Definition: libhsm.c:1855
const char * error_action
Definition: libhsm.h:105
char * progname
Definition: hsmcheck.c:40
const char * algoname
Definition: hsmspeed.c:44
void hsm_sign_params_free(hsm_sign_params_t *params)
Definition: libhsm.c:1961
hsm_key_t * key
Definition: hsmspeed.c:52
ldns_rdf * owner
Definition: libhsmdns.h:49
#define PTHREAD_THREADS_MAX
Definition: hsmspeed.c:40
int hsm_close()
Definition: libhsm.c:1872
ldns_rr * hsm_get_dnskey(hsm_ctx_t *ctx, const hsm_key_t *key, const hsm_sign_params_t *sign_params)
Definition: libhsm.c:2497
void hsm_destroy_context(hsm_ctx_t *ctx)
Definition: libhsm.c:1935
int hsm_open(const char *config, char *(pin_callback)(const char *repository, void *), void *data)
Definition: libhsm.c:1716
char * optarg
unsigned int iterations
Definition: hsmspeed.c:53
void usage()
Definition: hsmcheck.c:43
uint16_t keytag
Definition: libhsmdns.h:47
int main(int argc, char *argv[])
Definition: hsmcheck.c:49
hsm_sign_params_t * hsm_sign_params_new()
Definition: libhsm.c:1944
ldns_algorithm algorithm
Definition: libhsmdns.h:39
char error_message[HSM_ERROR_MSGSIZE]
Definition: libhsm.h:108
int hsm_remove_key(hsm_ctx_t *ctx, hsm_key_t *key)
Definition: libhsm.c:2149
hsm_ctx_t * hsm_create_context()
Definition: libhsm.c:1879
hsm_ctx_t * ctx
Definition: hsmspeed.c:51
ldns_algorithm algorithm
Definition: hsmspeed.c:43
unsigned int id
Definition: hsmspeed.c:50
hsm_key_t * hsm_generate_rsa_key(hsm_ctx_t *ctx, const char *repository, unsigned long keysize)
Definition: libhsm.c:2063
void * sign(void *arg)
Definition: hsmspeed.c:66
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:2279