OpenDNSSEC-libhsm  1.4.5
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 PTHREAD_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 }
121 
122 
123 int
124 main (int argc, char *argv[])
125 {
126  int result;
127 
128  hsm_ctx_t *ctx = NULL;
129  hsm_key_t *key = NULL;
130  unsigned int keysize = 1024;
131  unsigned int iterations = 1;
132  unsigned int threads = 1;
133 
134  static struct timeval start,end;
135 
136  char *config = NULL;
137  const char *repository = NULL;
138 
139  sign_arg_t sign_arg_array[PTHREAD_THREADS_MAX];
140 
141  pthread_t thread_array[PTHREAD_THREADS_MAX];
142  pthread_attr_t thread_attr;
143  void *thread_status;
144 
145  int ch;
146  unsigned int n;
147  double elapsed, speed;
148 
149  progname = argv[0];
150 
151  while ((ch = getopt(argc, argv, "c:i:r:s:t:")) != -1) {
152  switch (ch) {
153  case 'c':
154  config = strdup(optarg);
155  break;
156  case 'i':
157  iterations = atoi(optarg);
158  break;
159  case 'r':
160  repository = strdup(optarg);
161  break;
162  case 's':
163  keysize = atoi(optarg);
164  break;
165  case 't':
166  threads = atoi(optarg);
167  break;
168  default:
169  usage();
170  exit(1);
171  }
172  }
173 
174  if (!repository) {
175  usage();
176  exit(1);
177  }
178 
179 #if 0
180  if (!config) {
181  usage();
182  exit(1);
183  }
184 #endif
185 
186  /* Open HSM library */
187  fprintf(stderr, "Opening HSM Library...\n");
188  result = hsm_open(config, hsm_prompt_pin);
189  if (result) {
190  fprintf(stderr, "hsm_open() returned %d\n", result);
191  exit(-1);
192  }
193 
194  /* Create HSM context */
195  ctx = hsm_create_context();
196  if (! ctx) {
197  fprintf(stderr, "hsm_create_context() returned error\n");
198  exit(-1);
199  }
200 
201  /* Generate a temporary key */
202  fprintf(stderr, "Generating temporary key...\n");
203  key = hsm_generate_rsa_key(ctx, repository, keysize);
204  if (key) {
205  char *id = hsm_get_key_id(ctx, key);
206  fprintf(stderr, "Temporary key created: %s\n", id);
207  free(id);
208  } else {
209  fprintf(stderr, "Could not generate a key pair in repository \"%s\"\n", repository);
210  exit(-1);
211  }
212 
213  /* Prepare threads */
214  pthread_attr_init(&thread_attr);
215  pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
216 
217  for (n=0; n<threads; n++) {
218  sign_arg_array[n].id = n;
219  sign_arg_array[n].ctx = hsm_create_context();
220  if (! sign_arg_array[n].ctx) {
221  fprintf(stderr, "hsm_create_context() returned error\n");
222  exit(-1);
223  }
224  sign_arg_array[n].key = key;
225  sign_arg_array[n].iterations = iterations;
226  }
227 
228  fprintf(stderr, "Signing %d RRsets with %s using %d %s...\n",
229  iterations, algoname, threads, (threads > 1 ? "threads" : "thread"));
230  gettimeofday(&start, NULL);
231 
232  /* Create threads for signing */
233  for (n=0; n<threads; n++) {
234  result = pthread_create(&thread_array[n], &thread_attr,
235  sign, (void *) &sign_arg_array[n]);
236  if (result) {
237  fprintf(stderr, "pthread_create() returned %d\n", result);
238  exit(EXIT_FAILURE);
239  }
240  }
241 
242  /* Wait for threads to finish */
243  for (n=0; n<threads; n++) {
244  result = pthread_join(thread_array[n], &thread_status);
245  if (result) {
246  fprintf(stderr, "pthread_join() returned %d\n", result);
247  exit(EXIT_FAILURE);
248  }
249  }
250 
251  gettimeofday(&end, NULL);
252  fprintf(stderr, "Signing done.\n");
253 
254  /* Report results */
255  end.tv_sec -= start.tv_sec;
256  end.tv_usec-= start.tv_usec;
257  elapsed =(double)(end.tv_sec)+(double)(end.tv_usec)*.000001;
258  speed = iterations / elapsed * threads;
259  printf("%d %s, %d signatures per thread, %.2f sig/s (RSA %d bits)\n",
260  threads, (threads > 1 ? "threads" : "thread"), iterations,
261  speed, keysize);
262 
263  /* Delete temporary key */
264  fprintf(stderr, "Deleting temporary key...\n");
265  result = hsm_remove_key(ctx, key);
266  if (result) {
267  fprintf(stderr, "hsm_remove_key() returned %d\n", result);
268  exit(-1);
269  }
270 
271  /* Clean up */
272  hsm_destroy_context(ctx);
273  (void) hsm_close();
274  if (config) free(config);
275 
276  return 0;
277 }
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
#define PTHREAD_THREADS_MAX
Definition: hsmspeed.c:38
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:2964
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:124
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
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:2746