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
48 static int version_flag
;
50 static int time_keygen
;
51 static char *time_key
;
52 static int key_blinding
= 1;
57 static struct getargs args
[] = {
58 { "loops", 0, arg_integer
, &loops
,
59 "number of loops", "loops" },
60 { "id", 0, arg_string
, &id_flag
,
61 "selects the engine id", "engine-id" },
62 { "time-keygen", 0, arg_flag
, &time_keygen
,
63 "time rsa generation", NULL
},
64 { "time-key", 0, arg_string
, &time_key
,
65 "rsa key file", NULL
},
66 { "key-blinding", 0, arg_negative_flag
, &key_blinding
,
67 "key blinding", NULL
},
68 { "key", 0, arg_string
, &rsa_key
,
69 "rsa key file", NULL
},
70 { "version", 0, arg_flag
, &version_flag
,
71 "print version", NULL
},
72 { "help", 0, arg_flag
, &help_flag
,
81 check_rsa(const unsigned char *in
, size_t len
, RSA
*rsa
, int padding
)
83 unsigned char *res
, *res2
;
87 res
= malloc(RSA_size(rsa
));
89 errx(1, "res: ENOMEM");
91 res2
= malloc(RSA_size(rsa
));
93 errx(1, "res2: ENOMEM");
97 keylen
= RSA_private_encrypt(len
, in
, res
, rsa
, padding
);
99 errx(1, "failed to private encrypt: %d %d", (int)len
, (int)keylen
);
101 if (keylen
> RSA_size(rsa
))
102 errx(1, "keylen > RSA_size(rsa)");
104 keylen
= RSA_public_decrypt(keylen
, res
, res2
, rsa
, padding
);
106 errx(1, "failed to public decrypt: %d", (int)keylen
);
109 errx(1, "output buffer not same length: %d", (int)keylen
);
111 if (memcmp(res2
, in
, len
) != 0)
112 errx(1, "string not the same after decryption");
116 keylen
= RSA_public_encrypt(len
, in
, res
, rsa
, padding
);
118 errx(1, "failed to public encrypt: %d", (int)keylen
);
120 if (keylen
> RSA_size(rsa
))
121 errx(1, "keylen > RSA_size(rsa)");
123 keylen
= RSA_private_decrypt(keylen
, res
, res2
, rsa
, padding
);
125 errx(1, "failed to private decrypt: %d", (int)keylen
);
128 errx(1, "output buffer not same length: %d", (int)keylen
);
130 if (memcmp(res2
, in
, len
) != 0)
131 errx(1, "string not the same after decryption");
135 if (RSA_sign(NID_sha1
, in
, len
, res
, &len2
, rsa
) != 1)
136 errx(1, "RSA_sign failed");
138 if (RSA_verify(NID_sha1
, in
, len
, res
, len2
, rsa
) != 1)
139 errx(1, "RSA_verify failed");
146 cb_func(int a
, int b
, BN_GENCB
*c
)
152 read_key(ENGINE
*engine
, const char *keyfile
)
154 unsigned char buf
[1024 * 4];
155 const unsigned char *p
;
160 f
= fopen(keyfile
, "rb");
162 err(1, "could not open file %s", keyfile
);
165 size
= fread(buf
, 1, sizeof(buf
), f
);
168 err(1, "failed to read file %s", keyfile
);
169 if (size
== sizeof(buf
))
170 err(1, "key too long in file %s!", keyfile
);
173 rsa
= d2i_RSAPrivateKey(NULL
, &p
, size
);
175 err(1, "failed to parse key in file %s", keyfile
);
177 RSA_set_method(rsa
, ENGINE_get_RSA(engine
));
180 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
192 arg_printusage (args
,
193 sizeof(args
)/sizeof(*args
),
200 main(int argc
, char **argv
)
202 ENGINE
*engine
= NULL
;
206 setprogname(argv
[0]);
208 if(getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &idx
))
222 OpenSSL_add_all_algorithms();
224 ENGINE_load_openssl();
226 ENGINE_load_builtin_engines();
229 engine
= ENGINE_by_id("builtin");
231 engine
= ENGINE_by_id(argv
[0]);
233 engine
= ENGINE_by_dso(argv
[0], id_flag
);
236 errx(1, "ENGINE_by_dso failed");
238 if (ENGINE_get_RSA(engine
) == NULL
)
241 printf("rsa %s\n", ENGINE_get_RSA(engine
)->name
);
243 if (RAND_status() != 1)
244 errx(77, "no functional random device, refusing to run tests");
247 struct timeval tv1
, tv2
;
250 rsa
= RSA_new_method(engine
);
252 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
255 BN_set_word(e
, 0x10001);
257 printf("running keygen with %d loops\n", loops
);
259 gettimeofday(&tv1
, NULL
);
261 for (i
= 0; i
< loops
; i
++) {
262 rsa
= RSA_new_method(engine
);
263 if (RSA_generate_key_ex(rsa
, 1024, e
, NULL
) != 1)
264 errx(1, "RSA_generate_key_ex");
268 gettimeofday(&tv2
, NULL
);
269 timevalsub(&tv2
, &tv1
);
271 printf("time %lu.%06lu\n",
272 (unsigned long)tv2
.tv_sec
,
273 (unsigned long)tv2
.tv_usec
);
276 ENGINE_finish(engine
);
283 struct timeval tv1
, tv2
;
286 if (strcmp(time_key
, "generate") == 0) {
289 rsa
= RSA_new_method(engine
);
291 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
294 BN_set_word(e
, 0x10001);
296 if (RSA_generate_key_ex(rsa
, 1024, e
, NULL
) != 1)
297 errx(1, "RSA_generate_key_ex");
299 rsa
= read_key(engine
, time_key
);
302 p
= emalloc(loops
* size
);
304 RAND_bytes(p
, loops
* size
);
306 gettimeofday(&tv1
, NULL
);
307 for (i
= 0; i
< loops
; i
++)
308 check_rsa(p
+ (i
* size
), size
, rsa
, RSA_PKCS1_PADDING
);
309 gettimeofday(&tv2
, NULL
);
311 timevalsub(&tv2
, &tv1
);
313 printf("time %lu.%06lu\n",
314 (unsigned long)tv2
.tv_sec
,
315 (unsigned long)tv2
.tv_usec
);
318 ENGINE_finish(engine
);
324 rsa
= read_key(engine
, rsa_key
);
327 * Assuming that you use the RSA key in the distribution, this
328 * test will generate a signature have a starting zero and thus
329 * will generate a checksum that is 127 byte instead of the
330 * checksum that is 128 byte (like the key).
333 const unsigned char sha1
[20] = {
334 0x6d, 0x33, 0xf9, 0x40, 0x75, 0x5b, 0x4e, 0xc5, 0x90, 0x35,
335 0x48, 0xab, 0x75, 0x02, 0x09, 0x76, 0x9a, 0xb4, 0x7d, 0x6b
338 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
341 for (i
= 0; i
< 128; i
++) {
342 unsigned char sha1
[20];
344 RAND_bytes(sha1
, sizeof(sha1
));
345 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
347 for (i
= 0; i
< 128; i
++) {
348 unsigned char des3
[21];
350 RAND_bytes(des3
, sizeof(des3
));
351 check_rsa(des3
, sizeof(des3
), rsa
, RSA_PKCS1_PADDING
);
353 for (i
= 0; i
< 128; i
++) {
354 unsigned char aes
[32];
356 RAND_bytes(aes
, sizeof(aes
));
357 check_rsa(aes
, sizeof(aes
), rsa
, RSA_PKCS1_PADDING
);
363 for (i
= 0; i
< loops
; i
++) {
368 rsa
= RSA_new_method(engine
);
370 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
373 BN_set_word(e
, 0x10001);
375 BN_GENCB_set(&cb
, cb_func
, NULL
);
377 RAND_bytes(&n
, sizeof(n
));
381 if (RSA_generate_key_ex(rsa
, n
, e
, &cb
) != 1)
382 errx(1, "RSA_generate_key_ex");
386 for (j
= 0; j
< 8; j
++) {
387 unsigned char sha1
[20];
388 RAND_bytes(sha1
, sizeof(sha1
));
389 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
395 ENGINE_finish(engine
);