2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 static int version_flag
;
56 static int time_keygen
;
57 static char *time_key
;
58 static int key_blinding
= 1;
63 static struct getargs args
[] = {
64 { "loops", 0, arg_integer
, &loops
,
65 "number of loops", "loops" },
66 { "id", 0, arg_string
, &id_flag
,
67 "selects the engine id", "engine-id" },
68 { "time-keygen", 0, arg_flag
, &time_keygen
,
69 "time rsa generation", NULL
},
70 { "time-key", 0, arg_string
, &time_key
,
71 "rsa key file", NULL
},
72 { "key-blinding", 0, arg_negative_flag
, &key_blinding
,
73 "key blinding", NULL
},
74 { "key", 0, arg_string
, &rsa_key
,
75 "rsa key file", NULL
},
76 { "version", 0, arg_flag
, &version_flag
,
77 "print version", NULL
},
78 { "help", 0, arg_flag
, &help_flag
,
87 check_rsa(const unsigned char *in
, size_t len
, RSA
*rsa
, int padding
)
89 unsigned char *res
, *res2
;
92 res
= malloc(RSA_size(rsa
));
94 errx(1, "res: ENOMEM");
96 res2
= malloc(RSA_size(rsa
));
98 errx(1, "res2: ENOMEM");
102 keylen
= RSA_private_encrypt(len
, in
, res
, rsa
, padding
);
104 errx(1, "failed to private encrypt: %d %d", (int)len
, (int)keylen
);
106 if (keylen
> RSA_size(rsa
))
107 errx(1, "keylen > RSA_size(rsa)");
109 keylen
= RSA_public_decrypt(keylen
, res
, res2
, rsa
, padding
);
111 errx(1, "failed to public decrypt: %d", (int)keylen
);
114 errx(1, "output buffer not same length: %d", (int)keylen
);
116 if (memcmp(res2
, in
, len
) != 0)
117 errx(1, "string not the same after decryption");
121 keylen
= RSA_public_encrypt(len
, in
, res
, rsa
, padding
);
123 errx(1, "failed to public encrypt: %d", (int)keylen
);
125 if (keylen
> RSA_size(rsa
))
126 errx(1, "keylen > RSA_size(rsa)");
128 keylen
= RSA_private_decrypt(keylen
, res
, res2
, rsa
, padding
);
130 errx(1, "failed to private decrypt: %d", (int)keylen
);
133 errx(1, "output buffer not same length: %d", (int)keylen
);
135 if (memcmp(res2
, in
, len
) != 0)
136 errx(1, "string not the same after decryption");
143 cb_func(int a
, int b
, BN_GENCB
*c
)
149 read_key(ENGINE
*engine
, const char *rsa_key
)
151 unsigned char buf
[1024 * 4];
152 const unsigned char *p
;
157 f
= fopen(rsa_key
, "r");
159 err(1, "could not open file %s", rsa_key
);
161 size
= fread(buf
, 1, sizeof(buf
), f
);
164 err(1, "failed to read file %s", rsa_key
);
165 if (size
== sizeof(buf
))
166 err(1, "key too long in file %s!", rsa_key
);
169 rsa
= d2i_RSAPrivateKey(NULL
, &p
, size
);
171 err(1, "failed to parse key in file %s", rsa_key
);
173 RSA_set_method(rsa
, ENGINE_get_RSA(engine
));
176 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
188 arg_printusage (args
,
189 sizeof(args
)/sizeof(*args
),
196 main(int argc
, char **argv
)
198 ENGINE
*engine
= NULL
;
202 setprogname(argv
[0]);
204 if(getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &idx
))
218 OpenSSL_add_all_algorithms();
221 OpenSSL_add_all_algorithms();
222 ENGINE_load_builtin_engines();
223 engine
= ENGINE_by_id("builtin");
225 engine
= ENGINE_by_dso(argv
[0], id_flag
);
228 errx(1, "ENGINE_by_dso failed");
230 if (ENGINE_get_RSA(engine
) == NULL
)
233 printf("rsa %s\n", ENGINE_get_RSA(engine
)->name
);
235 if (RAND_status() != 1)
236 errx(77, "no functional random device, refusing to run tests");
239 struct timeval tv1
, tv2
;
243 rsa
= RSA_new_method(engine
);
245 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
248 BN_set_word(e
, 0x10001);
250 gettimeofday(&tv1
, NULL
);
252 for (i
= 0; i
< num
; i
++) {
253 rsa
= RSA_new_method(engine
);
254 if (RSA_generate_key_ex(rsa
, 1024, e
, NULL
) != 1)
255 errx(1, "RSA_generate_key_ex");
259 gettimeofday(&tv2
, NULL
);
260 timevalsub(&tv2
, &tv1
);
262 printf("time %lu.%06lu\n",
263 (unsigned long)tv2
.tv_sec
,
264 (unsigned long)tv2
.tv_usec
);
267 ENGINE_finish(engine
);
275 struct timeval tv1
, tv2
;
278 rsa
= read_key(engine
, time_key
);
280 p
= emalloc(num
* size
);
282 RAND_bytes(p
, num
* size
);
284 gettimeofday(&tv1
, NULL
);
285 for (i
= 0; i
< num
; i
++)
286 check_rsa(p
+ (i
* size
), size
, rsa
, RSA_PKCS1_PADDING
);
287 gettimeofday(&tv2
, NULL
);
289 timevalsub(&tv2
, &tv1
);
291 printf("time %lu.%06lu\n",
292 (unsigned long)tv2
.tv_sec
,
293 (unsigned long)tv2
.tv_usec
);
296 ENGINE_finish(engine
);
302 rsa
= read_key(engine
, rsa_key
);
305 * Assuming that you use the RSA key in the distribution, this
306 * test will generate a signature have a starting zero and thus
307 * will generate a checksum that is 127 byte instead of the
308 * checksum that is 128 byte (like the key).
311 const unsigned char sha1
[20] = {
312 0x6d, 0x33, 0xf9, 0x40, 0x75, 0x5b, 0x4e, 0xc5, 0x90, 0x35,
313 0x48, 0xab, 0x75, 0x02, 0x09, 0x76, 0x9a, 0xb4, 0x7d, 0x6b
316 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
319 for (i
= 0; i
< 128; i
++) {
320 unsigned char sha1
[20];
322 RAND_bytes(sha1
, sizeof(sha1
));
323 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
325 for (i
= 0; i
< 128; i
++) {
326 unsigned char des3
[21];
328 RAND_bytes(des3
, sizeof(des3
));
329 check_rsa(des3
, sizeof(des3
), rsa
, RSA_PKCS1_PADDING
);
331 for (i
= 0; i
< 128; i
++) {
332 unsigned char aes
[32];
334 RAND_bytes(aes
, sizeof(aes
));
335 check_rsa(aes
, sizeof(aes
), rsa
, RSA_PKCS1_PADDING
);
341 for (i
= 0; i
< loops
; i
++) {
346 rsa
= RSA_new_method(engine
);
348 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
351 BN_set_word(e
, 0x10001);
353 BN_GENCB_set(&cb
, cb_func
, NULL
);
355 RAND_bytes(&n
, sizeof(n
));
359 if (RSA_generate_key_ex(rsa
, n
, e
, &cb
) != 1)
360 errx(1, "RSA_generate_key_ex");
364 for (j
= 0; j
< 8; j
++) {
365 unsigned char sha1
[20];
366 RAND_bytes(sha1
, sizeof(sha1
));
367 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
373 ENGINE_finish(engine
);