OpenDNSSEC-libhsm 1.2.1
|
00001 /* 00002 * $Id: hsmspeed.c 4294 2011-01-13 19:58:29Z jakob $ 00003 * 00004 * Copyright (c) 2009 Nominet UK. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00017 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00019 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00020 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00021 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00022 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00023 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00024 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00025 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00026 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00029 #include "config.h" 00030 00031 #include <stdio.h> 00032 #include <string.h> 00033 #include <stdlib.h> 00034 #include <unistd.h> 00035 #include <pthread.h> 00036 00037 #include <libhsm.h> 00038 #include <libhsmdns.h> 00039 00040 #define PTHREAD_THREADS_MAX 2048 00041 00042 /* Algorithm identifier and name */ 00043 ldns_algorithm algorithm = LDNS_RSASHA1; 00044 const char *algoname = "RSA/SHA1"; 00045 00046 extern char *optarg; 00047 char *progname = NULL; 00048 00049 typedef struct { 00050 unsigned int id; 00051 hsm_ctx_t *ctx; 00052 hsm_key_t *key; 00053 unsigned int iterations; 00054 } sign_arg_t; 00055 00056 void 00057 usage () 00058 { 00059 fprintf(stderr, 00060 "usage: %s " 00061 "[-c config] -r repository [-i iterations] [-s keysize] [-t threads]\n", 00062 progname); 00063 } 00064 00065 void * 00066 sign (void *arg) 00067 { 00068 hsm_ctx_t *ctx = NULL; 00069 hsm_key_t *key = NULL; 00070 00071 size_t i; 00072 unsigned int iterations = 0; 00073 00074 ldns_rr_list *rrset; 00075 ldns_rr *rr, *sig, *dnskey_rr; 00076 ldns_status status; 00077 hsm_sign_params_t *sign_params; 00078 00079 sign_arg_t *sign_arg = arg; 00080 00081 ctx = sign_arg->ctx; 00082 key = sign_arg->key; 00083 iterations = sign_arg->iterations; 00084 00085 fprintf(stderr, "Signer thread #%d started...\n", sign_arg->id); 00086 00087 /* Prepare dummy RRset for signing */ 00088 rrset = ldns_rr_list_new(); 00089 status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 123.123.123.123", 0, NULL, NULL); 00090 if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); 00091 status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 124.124.124.124", 0, NULL, NULL); 00092 if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); 00093 sign_params = hsm_sign_params_new(); 00094 sign_params->algorithm = algorithm; 00095 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "opendnssec.se."); 00096 dnskey_rr = hsm_get_dnskey(ctx, key, sign_params); 00097 sign_params->keytag = ldns_calc_keytag(dnskey_rr); 00098 00099 /* Do some signing */ 00100 for (i=0; i<iterations; i++) { 00101 sig = hsm_sign_rrset(ctx, rrset, key, sign_params); 00102 if (! sig) { 00103 fprintf(stderr, 00104 "hsm_sign_rrset() returned error: %s in %s\n", 00105 ctx->error_message, 00106 ctx->error_action 00107 ); 00108 break; 00109 } 00110 ldns_rr_free(sig); 00111 } 00112 00113 /* Clean up */ 00114 ldns_rr_list_deep_free(rrset); 00115 hsm_sign_params_free(sign_params); 00116 ldns_rr_free(dnskey_rr); 00117 hsm_destroy_context(ctx); 00118 00119 fprintf(stderr, "Signer thread #%d done.\n", sign_arg->id); 00120 00121 pthread_exit(NULL); 00122 } 00123 00124 00125 int 00126 main (int argc, char *argv[]) 00127 { 00128 int result; 00129 00130 hsm_ctx_t *ctx = NULL; 00131 hsm_key_t *key = NULL; 00132 unsigned int keysize = 1024; 00133 unsigned int iterations = 1; 00134 unsigned int threads = 1; 00135 00136 static struct timeval start,end; 00137 00138 char *config = NULL; 00139 const char *repository = NULL; 00140 00141 sign_arg_t sign_arg_array[PTHREAD_THREADS_MAX]; 00142 00143 pthread_t thread_array[PTHREAD_THREADS_MAX]; 00144 pthread_attr_t thread_attr; 00145 void *thread_status; 00146 00147 int ch; 00148 unsigned int n; 00149 double elapsed, speed; 00150 00151 progname = argv[0]; 00152 00153 while ((ch = getopt(argc, argv, "c:i:r:s:t:")) != -1) { 00154 switch (ch) { 00155 case 'c': 00156 config = strdup(optarg); 00157 break; 00158 case 'i': 00159 iterations = atoi(optarg); 00160 break; 00161 case 'r': 00162 repository = strdup(optarg); 00163 break; 00164 case 's': 00165 keysize = atoi(optarg); 00166 break; 00167 case 't': 00168 threads = atoi(optarg); 00169 break; 00170 default: 00171 usage(); 00172 exit(1); 00173 } 00174 } 00175 00176 if (!repository) { 00177 usage(); 00178 exit(1); 00179 } 00180 00181 #if 0 00182 if (!config) { 00183 usage(); 00184 exit(1); 00185 } 00186 #endif 00187 00188 /* Open HSM library */ 00189 fprintf(stderr, "Opening HSM Library...\n"); 00190 result = hsm_open(config, hsm_prompt_pin, NULL); 00191 if (result) { 00192 fprintf(stderr, "hsm_open() returned %d\n", result); 00193 exit(-1); 00194 } 00195 00196 /* Create HSM context */ 00197 ctx = hsm_create_context(); 00198 if (! ctx) { 00199 fprintf(stderr, "hsm_create_context() returned error\n"); 00200 exit(-1); 00201 } 00202 00203 /* Generate a temporary key */ 00204 fprintf(stderr, "Generating temporary key...\n"); 00205 key = hsm_generate_rsa_key(ctx, repository, keysize); 00206 if (key) { 00207 char *id = hsm_get_key_id(ctx, key); 00208 fprintf(stderr, "Temporary key created: %s\n", id); 00209 free(id); 00210 } else { 00211 fprintf(stderr, "Could not generate a key pair in repository \"%s\"\n", repository); 00212 exit(-1); 00213 } 00214 00215 /* Prepare threads */ 00216 pthread_attr_init(&thread_attr); 00217 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); 00218 00219 for (n=0; n<threads; n++) { 00220 sign_arg_array[n].id = n; 00221 sign_arg_array[n].ctx = hsm_create_context(); 00222 if (! sign_arg_array[n].ctx) { 00223 fprintf(stderr, "hsm_create_context() returned error\n"); 00224 exit(-1); 00225 } 00226 sign_arg_array[n].key = key; 00227 sign_arg_array[n].iterations = iterations; 00228 } 00229 00230 fprintf(stderr, "Signing %d RRsets with %s using %d %s...\n", 00231 iterations, algoname, threads, (threads > 1 ? "threads" : "thread")); 00232 gettimeofday(&start, NULL); 00233 00234 /* Create threads for signing */ 00235 for (n=0; n<threads; n++) { 00236 result = pthread_create(&thread_array[n], &thread_attr, 00237 sign, (void *) &sign_arg_array[n]); 00238 if (result) { 00239 fprintf(stderr, "pthread_create() returned %d\n", result); 00240 exit(EXIT_FAILURE); 00241 } 00242 } 00243 00244 /* Wait for threads to finish */ 00245 for (n=0; n<threads; n++) { 00246 result = pthread_join(thread_array[n], &thread_status); 00247 if (result) { 00248 fprintf(stderr, "pthread_join() returned %d\n", result); 00249 exit(EXIT_FAILURE); 00250 } 00251 } 00252 00253 gettimeofday(&end, NULL); 00254 fprintf(stderr, "Signing done.\n"); 00255 00256 /* Report results */ 00257 end.tv_sec -= start.tv_sec; 00258 end.tv_usec-= start.tv_usec; 00259 elapsed =(double)(end.tv_sec)+(double)(end.tv_usec)*.000001; 00260 speed = iterations / elapsed * threads; 00261 printf("%d %s, %d signatures per thread, %.2f sig/s (RSA %d bits)\n", 00262 threads, (threads > 1 ? "threads" : "thread"), iterations, 00263 speed, keysize); 00264 00265 /* Delete temporary key */ 00266 fprintf(stderr, "Deleting temporary key...\n"); 00267 result = hsm_remove_key(ctx, key); 00268 if (result) { 00269 fprintf(stderr, "hsm_remove_key() returned %d\n", result); 00270 exit(-1); 00271 } 00272 00273 /* Clean up */ 00274 hsm_destroy_context(ctx); 00275 (void) hsm_close(); 00276 if (config) free(config); 00277 00278 return 0; 00279 }