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
;
86 res
= malloc(RSA_size(rsa
));
88 errx(1, "res: ENOMEM");
90 res2
= malloc(RSA_size(rsa
));
92 errx(1, "res2: ENOMEM");
96 keylen
= RSA_private_encrypt(len
, in
, res
, rsa
, padding
);
98 errx(1, "failed to private encrypt: %d %d", (int)len
, (int)keylen
);
100 if (keylen
> RSA_size(rsa
))
101 errx(1, "keylen > RSA_size(rsa)");
103 keylen
= RSA_public_decrypt(keylen
, res
, res2
, rsa
, padding
);
105 errx(1, "failed to public decrypt: %d", (int)keylen
);
108 errx(1, "output buffer not same length: %d", (int)keylen
);
110 if (memcmp(res2
, in
, len
) != 0)
111 errx(1, "string not the same after decryption");
115 keylen
= RSA_public_encrypt(len
, in
, res
, rsa
, padding
);
117 errx(1, "failed to public encrypt: %d", (int)keylen
);
119 if (keylen
> RSA_size(rsa
))
120 errx(1, "keylen > RSA_size(rsa)");
122 keylen
= RSA_private_decrypt(keylen
, res
, res2
, rsa
, padding
);
124 errx(1, "failed to private decrypt: %d", (int)keylen
);
127 errx(1, "output buffer not same length: %d", (int)keylen
);
129 if (memcmp(res2
, in
, len
) != 0)
130 errx(1, "string not the same after decryption");
137 cb_func(int a
, int b
, BN_GENCB
*c
)
143 read_key(ENGINE
*engine
, const char *rsa_key
)
145 unsigned char buf
[1024 * 4];
146 const unsigned char *p
;
151 f
= fopen(rsa_key
, "r");
153 err(1, "could not open file %s", rsa_key
);
156 size
= fread(buf
, 1, sizeof(buf
), f
);
159 err(1, "failed to read file %s", rsa_key
);
160 if (size
== sizeof(buf
))
161 err(1, "key too long in file %s!", rsa_key
);
164 rsa
= d2i_RSAPrivateKey(NULL
, &p
, size
);
166 err(1, "failed to parse key in file %s", rsa_key
);
168 RSA_set_method(rsa
, ENGINE_get_RSA(engine
));
171 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
183 arg_printusage (args
,
184 sizeof(args
)/sizeof(*args
),
191 main(int argc
, char **argv
)
193 ENGINE
*engine
= NULL
;
197 setprogname(argv
[0]);
199 if(getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &idx
))
213 OpenSSL_add_all_algorithms();
216 OpenSSL_add_all_algorithms();
217 ENGINE_load_builtin_engines();
218 engine
= ENGINE_by_id("builtin");
220 engine
= ENGINE_by_dso(argv
[0], id_flag
);
223 errx(1, "ENGINE_by_dso failed");
225 if (ENGINE_get_RSA(engine
) == NULL
)
228 printf("rsa %s\n", ENGINE_get_RSA(engine
)->name
);
230 if (RAND_status() != 1)
231 errx(77, "no functional random device, refusing to run tests");
234 struct timeval tv1
, tv2
;
238 rsa
= RSA_new_method(engine
);
240 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
243 BN_set_word(e
, 0x10001);
245 gettimeofday(&tv1
, NULL
);
247 for (i
= 0; i
< num
; i
++) {
248 rsa
= RSA_new_method(engine
);
249 if (RSA_generate_key_ex(rsa
, 1024, e
, NULL
) != 1)
250 errx(1, "RSA_generate_key_ex");
254 gettimeofday(&tv2
, NULL
);
255 timevalsub(&tv2
, &tv1
);
257 printf("time %lu.%06lu\n",
258 (unsigned long)tv2
.tv_sec
,
259 (unsigned long)tv2
.tv_usec
);
262 ENGINE_finish(engine
);
270 struct timeval tv1
, tv2
;
273 rsa
= read_key(engine
, time_key
);
275 p
= emalloc(num
* size
);
277 RAND_bytes(p
, num
* size
);
279 gettimeofday(&tv1
, NULL
);
280 for (i
= 0; i
< num
; i
++)
281 check_rsa(p
+ (i
* size
), size
, rsa
, RSA_PKCS1_PADDING
);
282 gettimeofday(&tv2
, NULL
);
284 timevalsub(&tv2
, &tv1
);
286 printf("time %lu.%06lu\n",
287 (unsigned long)tv2
.tv_sec
,
288 (unsigned long)tv2
.tv_usec
);
291 ENGINE_finish(engine
);
297 rsa
= read_key(engine
, rsa_key
);
300 * Assuming that you use the RSA key in the distribution, this
301 * test will generate a signature have a starting zero and thus
302 * will generate a checksum that is 127 byte instead of the
303 * checksum that is 128 byte (like the key).
306 const unsigned char sha1
[20] = {
307 0x6d, 0x33, 0xf9, 0x40, 0x75, 0x5b, 0x4e, 0xc5, 0x90, 0x35,
308 0x48, 0xab, 0x75, 0x02, 0x09, 0x76, 0x9a, 0xb4, 0x7d, 0x6b
311 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
314 for (i
= 0; i
< 128; i
++) {
315 unsigned char sha1
[20];
317 RAND_bytes(sha1
, sizeof(sha1
));
318 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
320 for (i
= 0; i
< 128; i
++) {
321 unsigned char des3
[21];
323 RAND_bytes(des3
, sizeof(des3
));
324 check_rsa(des3
, sizeof(des3
), rsa
, RSA_PKCS1_PADDING
);
326 for (i
= 0; i
< 128; i
++) {
327 unsigned char aes
[32];
329 RAND_bytes(aes
, sizeof(aes
));
330 check_rsa(aes
, sizeof(aes
), rsa
, RSA_PKCS1_PADDING
);
336 for (i
= 0; i
< loops
; i
++) {
341 rsa
= RSA_new_method(engine
);
343 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
346 BN_set_word(e
, 0x10001);
348 BN_GENCB_set(&cb
, cb_func
, NULL
);
350 RAND_bytes(&n
, sizeof(n
));
354 if (RSA_generate_key_ex(rsa
, n
, e
, &cb
) != 1)
355 errx(1, "RSA_generate_key_ex");
359 for (j
= 0; j
< 8; j
++) {
360 unsigned char sha1
[20];
361 RAND_bytes(sha1
, sizeof(sha1
));
362 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
368 ENGINE_finish(engine
);