xref: /minix3/external/bsd/bind/dist/bin/tests/pkcs11/benchmarks/privrsa.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1 /*	$NetBSD: privrsa.c,v 1.1.1.4 2014/12/10 03:34:28 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * Portions copyright (c) 2008 Nominet UK.  All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  */
42 
43 /* Id */
44 
45 /* privrsa [-m module] [-s $slot] [-p pin] [-t] [-n count] */
46 
47 /*! \file */
48 
49 #include <config.h>
50 
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <time.h>
55 #include <unistd.h>
56 
57 #include <isc/commandline.h>
58 #include <isc/print.h>
59 #include <isc/result.h>
60 #include <isc/types.h>
61 
62 #include <pk11/pk11.h>
63 #include <pk11/result.h>
64 
65 #if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
66 #define getpassphrase(x)	getpass(x)
67 #endif
68 
69 #ifndef HAVE_CLOCK_GETTIME
70 #ifndef CLOCK_REALTIME
71 #define CLOCK_REALTIME 0
72 #endif
73 
74 int
clock_gettime(int32_t id,struct timespec * tp)75 clock_gettime(int32_t id, struct timespec *tp)
76 {
77 	struct timeval tv;
78 	int result;
79 
80 	result = gettimeofday(&tv, NULL);
81 	if (result)
82 		return (result);
83 	tp->tv_sec = tv.tv_sec;
84 	tp->tv_nsec = (long) tv.tv_usec * 1000;
85 	return (result);
86 }
87 #endif
88 
89 CK_BYTE modulus[] = {
90 	0x00, 0xb7, 0x9c, 0x1f, 0x05, 0xa3, 0xc2, 0x99,
91 	0x44, 0x82, 0x20, 0x78, 0x43, 0x7f, 0x5f, 0x3b,
92 	0x10, 0xd7, 0x9e, 0x61, 0x42, 0xd2, 0x7a, 0x90,
93 	0x50, 0x8a, 0x99, 0x33, 0xe7, 0xca, 0xc8, 0x5f,
94 	0x16, 0x1c, 0x56, 0xf8, 0xc1, 0x06, 0x2f, 0x96,
95 	0xe7, 0x54, 0xf2, 0x85, 0x89, 0x41, 0x36, 0xf5,
96 	0x4c, 0xa4, 0x0d, 0x62, 0xd3, 0x42, 0x51, 0x6b,
97 	0x9f, 0xdc, 0x36, 0xcb, 0xad, 0x56, 0xf4, 0xbd,
98 	0x2a, 0x60, 0x33, 0xb1, 0x7a, 0x99, 0xad, 0x08,
99 	0x9f, 0x95, 0xe8, 0xe5, 0x14, 0xd9, 0x68, 0x79,
100 	0xca, 0x4e, 0x72, 0xeb, 0xfb, 0x2c, 0xf1, 0x45,
101 	0xd3, 0x33, 0x65, 0xe7, 0xc5, 0x11, 0xdd, 0xe7,
102 	0x09, 0x83, 0x13, 0xd5, 0x17, 0x1b, 0xf4, 0xbd,
103 	0x49, 0xdd, 0x8a, 0x3c, 0x3c, 0xf7, 0xa1, 0x5d,
104 	0x7b, 0xb4, 0xd3, 0x80, 0x25, 0xf4, 0x05, 0x8f,
105 	0xbc, 0x2c, 0x2a, 0x47, 0xff, 0xd1, 0xc8, 0x34,
106 	0xbf
107 };
108 CK_BYTE pubexp[] = { 0x01, 0x00, 0x01 };
109 CK_BYTE privexp[] = {
110 	0x00, 0xae, 0x02, 0xf1, 0x47, 0xa8, 0x07, 0x02,
111 	0xb8, 0xf1, 0xd6, 0x92, 0x03, 0xee, 0x50, 0x33,
112 	0xab, 0x67, 0x9e, 0x3b, 0xb1, 0x57, 0xc7, 0x3e,
113 	0xc4, 0x86, 0x46, 0x61, 0xf1, 0xf8, 0xb6, 0x63,
114 	0x9f, 0x91, 0xe6, 0x3f, 0x44, 0xb8, 0x77, 0x1b,
115 	0xbe, 0x4c, 0x3c, 0xb8, 0x9f, 0xf7, 0x45, 0x7d,
116 	0xbf, 0x4f, 0xef, 0x3b, 0xcc, 0xda, 0x1a, 0x4e,
117 	0x34, 0xa8, 0x40, 0xea, 0x51, 0x72, 0x8a, 0xea,
118 	0x47, 0x06, 0x04, 0xd0, 0x62, 0x31, 0xa0, 0x6c,
119 	0x09, 0x60, 0xf9, 0xc7, 0x95, 0x88, 0x4a, 0xd7,
120 	0x19, 0xce, 0x89, 0x08, 0x87, 0x14, 0xef, 0xcc,
121 	0x0a, 0xef, 0x72, 0xb9, 0x21, 0xf5, 0xf0, 0xcd,
122 	0x6d, 0xe5, 0xfa, 0x15, 0x7f, 0xae, 0x33, 0x9f,
123 	0x26, 0xac, 0x2e, 0x52, 0x02, 0x07, 0xfb, 0x1d,
124 	0x4b, 0xec, 0x9a, 0x6b, 0x3b, 0x26, 0x1f, 0x52,
125 	0xfc, 0x47, 0xf8, 0x66, 0x33, 0xfa, 0x50, 0x6c,
126 	0x41
127 };
128 CK_BYTE prime1[] = {
129 	0x00, 0xe8, 0x98, 0xeb, 0xa1, 0xf0, 0xce, 0xde,
130 	0xc2, 0x74, 0x01, 0x18, 0x2b, 0xd3, 0x8f, 0x58,
131 	0xcd, 0xe9, 0x8e, 0x97, 0xbe, 0xfe, 0xe8, 0x6f,
132 	0xd6, 0x0c, 0x0a, 0x47, 0xf8, 0x56, 0x84, 0x36,
133 	0x15, 0xe6, 0x75, 0x1c, 0x69, 0x48, 0x8b, 0xf5,
134 	0x0f, 0x84, 0xd2, 0x60, 0x8b, 0xa2, 0x2a, 0xa1,
135 	0xeb, 0xed, 0xbe, 0x2d, 0xe9, 0x41, 0x0b, 0xed,
136 	0x17, 0x7c, 0xd3, 0xa6, 0x35, 0x6e, 0xa6, 0xd8,
137 	0x21
138 };
139 CK_BYTE prime2[] = {
140 	0x00, 0xca, 0x15, 0x6a, 0x43, 0x5e, 0x83, 0xc9,
141 	0x09, 0xeb, 0x14, 0x1e, 0x46, 0x46, 0x97, 0xfa,
142 	0xfa, 0x3c, 0x61, 0x7e, 0xc1, 0xf8, 0x8c, 0x5e,
143 	0xcb, 0xbf, 0xe4, 0xb9, 0x78, 0x7f, 0x4f, 0xab,
144 	0x82, 0x15, 0x53, 0xaa, 0x04, 0xee, 0x11, 0x21,
145 	0x2e, 0x23, 0x08, 0xa0, 0x14, 0x6d, 0x3a, 0x88,
146 	0xe6, 0xf8, 0xbe, 0x61, 0x38, 0x99, 0xca, 0x36,
147 	0x0d, 0x3e, 0x42, 0x0f, 0x63, 0x4d, 0x73, 0xf0,
148 	0xdf
149 };
150 CK_BYTE exp_1[] = {
151 	0x66, 0x2d, 0xb7, 0x65, 0xbe, 0x99, 0xc2, 0x35,
152 	0xfe, 0x2b, 0xf4, 0xe8, 0x5b, 0xd9, 0xdf, 0x13,
153 	0x26, 0x04, 0xe4, 0x18, 0x9d, 0x76, 0x92, 0x9a,
154 	0x9f, 0x53, 0x6c, 0xe6, 0x65, 0x6b, 0x53, 0x2f,
155 	0x2f, 0xbc, 0x46, 0xac, 0xe1, 0x97, 0xca, 0x21,
156 	0xf5, 0x21, 0x4e, 0x14, 0x49, 0x3b, 0x1d, 0x42,
157 	0xbd, 0x80, 0x0c, 0x3f, 0x29, 0xba, 0x09, 0x7f,
158 	0x85, 0xf0, 0x9c, 0x55, 0x60, 0xb4, 0x9e, 0xc1
159 };
160 CK_BYTE exp_2[] = {
161 	0x00, 0x87, 0x22, 0x74, 0xf1, 0xe2, 0x15, 0x3c,
162 	0x6d, 0xde, 0x7e, 0x90, 0x94, 0x2c, 0x06, 0xdb,
163 	0xb5, 0x54, 0x85, 0x59, 0xcf, 0x7a, 0x56, 0xdb,
164 	0xd9, 0x62, 0x54, 0x20, 0x56, 0xdc, 0xc3, 0xb9,
165 	0x0b, 0xff, 0x18, 0xf8, 0x7b, 0xdd, 0x7b, 0x24,
166 	0xf6, 0x06, 0x45, 0x71, 0x4e, 0xd7, 0x90, 0x2a,
167 	0x16, 0x52, 0x46, 0x75, 0x1a, 0xf5, 0x74, 0x8c,
168 	0x5a, 0xa4, 0xc4, 0x66, 0x27, 0xe0, 0x96, 0x64,
169 	0x7f
170 };
171 CK_BYTE coeff[] = {
172 	0x00, 0xd0, 0x1f, 0xb3, 0x47, 0x40, 0x93, 0x8b,
173 	0x99, 0xd7, 0xb5, 0xc6, 0x09, 0x82, 0x65, 0x94,
174 	0x9d, 0x56, 0x0a, 0x05, 0x55, 0x7d, 0x93, 0x04,
175 	0xa4, 0x26, 0xee, 0x42, 0x86, 0xa3, 0xf1, 0xd5,
176 	0x7a, 0x42, 0x84, 0x3c, 0x21, 0x96, 0x9a, 0xd9,
177 	0x36, 0xd4, 0x62, 0x01, 0xb0, 0x8b, 0x77, 0xe5,
178 	0xcc, 0x1b, 0xd2, 0x12, 0xd2, 0x9c, 0x89, 0x67,
179 	0x0c, 0x00, 0x09, 0x56, 0x8c, 0x33, 0x57, 0xf9,
180 	0x8c
181 };
182 
183 char label[16];
184 
185 static CK_BBOOL truevalue = TRUE;
186 static CK_BBOOL falsevalue = FALSE;
187 
188 int
main(int argc,char * argv[])189 main(int argc, char *argv[]) {
190 	isc_result_t result;
191 	CK_RV rv;
192 	CK_SLOT_ID slot = 0;
193 	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
194 	CK_OBJECT_HANDLE *hKey;
195 	CK_OBJECT_CLASS kClass = CKO_PRIVATE_KEY;
196 	CK_KEY_TYPE kType = CKK_RSA;
197 	CK_ATTRIBUTE kTemplate[] =
198 	{
199 		{ CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) },
200 		{ CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) },
201 		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
202 		{ CKA_PRIVATE, &truevalue, (CK_ULONG) sizeof(truevalue) },
203 		{ CKA_LABEL, (CK_BYTE_PTR) label, (CK_ULONG) sizeof(label) },
204 		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
205 		{ CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) },
206 		{ CKA_PUBLIC_EXPONENT, pubexp, (CK_ULONG) sizeof(pubexp) },
207 		{ CKA_PRIVATE_EXPONENT, privexp, (CK_ULONG) sizeof(privexp) },
208 		{ CKA_PRIME_1, prime1, (CK_ULONG) sizeof(prime1) },
209 		{ CKA_PRIME_2, prime2, (CK_ULONG) sizeof(prime2) },
210 		{ CKA_EXPONENT_1, exp_1, (CK_ULONG) sizeof(exp_1) },
211 		{ CKA_EXPONENT_2, exp_2, (CK_ULONG) sizeof(exp_2) },
212 		{ CKA_COEFFICIENT, coeff, (CK_ULONG) sizeof(coeff) }
213 	};
214 	pk11_context_t pctx;
215 	pk11_optype_t op_type = OP_RSA;
216 	char *lib_name = NULL;
217 	char *pin = NULL;
218 	int error = 0;
219 	int c, errflg = 0;
220 	int ontoken  = 0;
221 	unsigned int count = 1000;
222 	unsigned int i;
223 	struct timespec starttime;
224 	struct timespec endtime;
225 
226 	while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) {
227 		switch (c) {
228 		case 'm':
229 			lib_name = isc_commandline_argument;
230 			break;
231 		case 's':
232 			slot = atoi(isc_commandline_argument);
233 			op_type = OP_ANY;
234 			break;
235 		case 'p':
236 			pin = isc_commandline_argument;
237 			break;
238 		case 't':
239 			ontoken = 1;
240 			break;
241 		case 'n':
242 			count = atoi(isc_commandline_argument);
243 			break;
244 		case ':':
245 			fprintf(stderr,
246 				"Option -%c requires an operand\n",
247 				isc_commandline_option);
248 			errflg++;
249 			break;
250 		case '?':
251 		default:
252 			fprintf(stderr, "Unrecognised option: -%c\n",
253 				isc_commandline_option);
254 			errflg++;
255 		}
256 	}
257 
258 	if (errflg) {
259 		fprintf(stderr, "Usage:\n");
260 		fprintf(stderr,
261 			"\tprivrsa [-m module] [-s slot] [-p pin] "
262 			"[-t] [-n count]\n");
263 		exit(1);
264 	}
265 
266 	pk11_result_register();
267 
268 	/* Allocate hanles */
269 	hKey = (CK_SESSION_HANDLE *)
270 		malloc(count * sizeof(CK_SESSION_HANDLE));
271 	if (hKey == NULL) {
272 		perror("malloc");
273 		exit(1);
274 	}
275 	for (i = 0; i < count; i++)
276 		hKey[i] = CK_INVALID_HANDLE;
277 
278 	/* Initialize the CRYPTOKI library */
279 	if (lib_name != NULL)
280 		pk11_set_lib_name(lib_name);
281 
282 	if (pin == NULL)
283 		pin = getpassphrase("Enter Pin: ");
284 
285 	result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE,
286 				  ISC_TRUE, (const char *) pin, slot);
287 	if ((result != ISC_R_SUCCESS) &&
288 	    (result != PK11_R_NORANDOMSERVICE) &&
289 	    (result != PK11_R_NODIGESTSERVICE) &&
290 	    (result != PK11_R_NOAESSERVICE)) {
291 		fprintf(stderr, "Error initializing PKCS#11: %s\n",
292 			isc_result_totext(result));
293 		free(hKey);
294 		exit(1);
295 	}
296 
297 	if (pin != NULL)
298 		memset(pin, 0, strlen((char *)pin));
299 
300 	hSession = pctx.session;
301 
302 	if (ontoken)
303 		kTemplate[2].pValue = &truevalue;
304 
305 	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
306 		perror("clock_gettime(start)");
307 		goto exit_objects;
308 	}
309 
310 	for (i = 0; i < count; i++) {
311 		(void) snprintf(label, sizeof(label), "obj%u", i);
312 		kTemplate[4].ulValueLen = strlen(label);
313 		rv = pkcs_C_CreateObject(hSession, kTemplate, 14, &hKey[i]);
314 		if (rv != CKR_OK) {
315 			fprintf(stderr,
316 				"C_CreateObject[%u]: Error = 0x%.8lX\n",
317 				i, rv);
318 			error = 1;
319 			if (i == 0)
320 				goto exit_objects;
321 			break;
322 		}
323 	}
324 
325 	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
326 		perror("clock_gettime(end)");
327 		goto exit_objects;
328 	}
329 
330 	endtime.tv_sec -= starttime.tv_sec;
331 	endtime.tv_nsec -= starttime.tv_nsec;
332 	while (endtime.tv_nsec < 0) {
333 		endtime.tv_sec -= 1;
334 		endtime.tv_nsec += 1000000000;
335 	}
336 	printf("%u private RSA keys in %ld.%09lds\n", i,
337 	       endtime.tv_sec, endtime.tv_nsec);
338 	if (i > 0)
339 		printf("%g private RSA keys/s\n",
340 		       1024 * i / ((double) endtime.tv_sec +
341 				   (double) endtime.tv_nsec / 1000000000.));
342 
343     exit_objects:
344 	for (i = 0; i < count; i++) {
345 		/* Destroy objects */
346 		if (hKey[i] == CK_INVALID_HANDLE)
347 			continue;
348 		rv = pkcs_C_DestroyObject(hSession, hKey[i]);
349 		if ((rv != CKR_OK) && !errflg) {
350 			fprintf(stderr,
351 				"C_DestroyObject[%u]: Error = 0x%.8lX\n",
352 				i, rv);
353 			errflg = 1;
354 		}
355 	}
356 
357 	free(hKey);
358 
359 	pk11_return_session(&pctx);
360 	(void) pk11_finalize();
361 
362 	exit(error);
363 }
364