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
39 __RCSID("$Heimdal: test_rsa.c 20466 2007-04-20 08:29:05Z lha $"
55 static int version_flag
;
57 static int time_keygen
;
58 static char *time_key
;
59 static int key_blinding
= 1;
64 static struct getargs args
[] = {
65 { "loops", 0, arg_integer
, &loops
,
66 "number of loops", "loops" },
67 { "id", 0, arg_string
, &id_flag
,
68 "selects the engine id", "engine-id" },
69 { "time-keygen", 0, arg_flag
, &time_keygen
,
70 "time rsa generation", NULL
},
71 { "time-key", 0, arg_string
, &time_key
,
72 "rsa key file", NULL
},
73 { "key-blinding", 0, arg_negative_flag
, &key_blinding
,
74 "key blinding", NULL
},
75 { "key", 0, arg_string
, &rsa_key
,
76 "rsa key file", NULL
},
77 { "version", 0, arg_flag
, &version_flag
,
78 "print version", NULL
},
79 { "help", 0, arg_flag
, &help_flag
,
88 check_rsa(const unsigned char *in
, size_t len
, RSA
*rsa
, int padding
)
90 unsigned char *res
, *res2
;
93 res
= malloc(RSA_size(rsa
));
95 errx(1, "res: ENOMEM");
97 res2
= malloc(RSA_size(rsa
));
99 errx(1, "res2: ENOMEM");
103 keylen
= RSA_private_encrypt(len
, in
, res
, rsa
, padding
);
105 errx(1, "failed to private encrypt: %d %d", (int)len
, (int)keylen
);
107 if (keylen
> RSA_size(rsa
))
108 errx(1, "keylen > RSA_size(rsa)");
110 keylen
= RSA_public_decrypt(keylen
, res
, res2
, rsa
, padding
);
112 errx(1, "failed to public decrypt: %d", (int)keylen
);
115 errx(1, "output buffer not same length: %d", (int)keylen
);
117 if (memcmp(res2
, in
, len
) != 0)
118 errx(1, "string not the same after decryption");
122 keylen
= RSA_public_encrypt(len
, in
, res
, rsa
, padding
);
124 errx(1, "failed to public encrypt: %d", (int)keylen
);
126 if (keylen
> RSA_size(rsa
))
127 errx(1, "keylen > RSA_size(rsa)");
129 keylen
= RSA_private_decrypt(keylen
, res
, res2
, rsa
, padding
);
131 errx(1, "failed to private decrypt: %d", (int)keylen
);
134 errx(1, "output buffer not same length: %d", (int)keylen
);
136 if (memcmp(res2
, in
, len
) != 0)
137 errx(1, "string not the same after decryption");
144 cb_func(int a
, int b
, BN_GENCB
*c
)
150 read_key(ENGINE
*engine
, const char *rsa_key
)
152 unsigned char buf
[1024 * 4];
153 const unsigned char *p
;
158 f
= fopen(rsa_key
, "r");
160 err(1, "could not open file %s", rsa_key
);
162 size
= fread(buf
, 1, sizeof(buf
), f
);
165 err(1, "failed to read file %s", rsa_key
);
166 if (size
== sizeof(buf
))
167 err(1, "key too long in file %s!", rsa_key
);
170 rsa
= d2i_RSAPrivateKey(NULL
, &p
, size
);
172 err(1, "failed to parse key in file %s", rsa_key
);
174 RSA_set_method(rsa
, ENGINE_get_RSA(engine
));
177 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
189 arg_printusage (args
,
190 sizeof(args
)/sizeof(*args
),
197 main(int argc
, char **argv
)
199 ENGINE
*engine
= NULL
;
203 setprogname(argv
[0]);
205 if(getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &idx
))
219 OpenSSL_add_all_algorithms();
222 OpenSSL_add_all_algorithms();
223 ENGINE_load_builtin_engines();
224 engine
= ENGINE_by_id("builtin");
226 engine
= ENGINE_by_dso(argv
[0], id_flag
);
229 errx(1, "ENGINE_by_dso failed");
231 if (ENGINE_get_RSA(engine
) == NULL
)
234 printf("rsa %s\n", ENGINE_get_RSA(engine
)->name
);
236 if (RAND_status() != 1)
237 errx(77, "no functional random device, refusing to run tests");
240 struct timeval tv1
, tv2
;
244 rsa
= RSA_new_method(engine
);
246 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
249 BN_set_word(e
, 0x10001);
251 gettimeofday(&tv1
, NULL
);
253 for (i
= 0; i
< num
; i
++) {
254 rsa
= RSA_new_method(engine
);
255 if (RSA_generate_key_ex(rsa
, 1024, e
, NULL
) != 1)
256 errx(1, "RSA_generate_key_ex");
260 gettimeofday(&tv2
, NULL
);
261 timevalsub(&tv2
, &tv1
);
263 printf("time %lu.%06lu\n",
264 (unsigned long)tv2
.tv_sec
,
265 (unsigned long)tv2
.tv_usec
);
268 ENGINE_finish(engine
);
276 struct timeval tv1
, tv2
;
279 rsa
= read_key(engine
, time_key
);
281 p
= emalloc(num
* size
);
283 RAND_bytes(p
, num
* size
);
285 gettimeofday(&tv1
, NULL
);
286 for (i
= 0; i
< num
; i
++)
287 check_rsa(p
+ (i
* size
), size
, rsa
, RSA_PKCS1_PADDING
);
288 gettimeofday(&tv2
, NULL
);
290 timevalsub(&tv2
, &tv1
);
292 printf("time %lu.%06lu\n",
293 (unsigned long)tv2
.tv_sec
,
294 (unsigned long)tv2
.tv_usec
);
297 ENGINE_finish(engine
);
303 rsa
= read_key(engine
, rsa_key
);
306 * Assuming that you use the RSA key in the distribution, this
307 * test will generate a signature have a starting zero and thus
308 * will generate a checksum that is 127 byte instead of the
309 * checksum that is 128 byte (like the key).
312 const unsigned char sha1
[20] = {
313 0x6d, 0x33, 0xf9, 0x40, 0x75, 0x5b, 0x4e, 0xc5, 0x90, 0x35,
314 0x48, 0xab, 0x75, 0x02, 0x09, 0x76, 0x9a, 0xb4, 0x7d, 0x6b
317 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
320 for (i
= 0; i
< 128; i
++) {
321 unsigned char sha1
[20];
323 RAND_bytes(sha1
, sizeof(sha1
));
324 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
326 for (i
= 0; i
< 128; i
++) {
327 unsigned char des3
[21];
329 RAND_bytes(des3
, sizeof(des3
));
330 check_rsa(des3
, sizeof(des3
), rsa
, RSA_PKCS1_PADDING
);
332 for (i
= 0; i
< 128; i
++) {
333 unsigned char aes
[32];
335 RAND_bytes(aes
, sizeof(aes
));
336 check_rsa(aes
, sizeof(aes
), rsa
, RSA_PKCS1_PADDING
);
342 for (i
= 0; i
< loops
; i
++) {
347 rsa
= RSA_new_method(engine
);
349 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
352 BN_set_word(e
, 0x10001);
354 BN_GENCB_set(&cb
, cb_func
, NULL
);
356 RAND_bytes(&n
, sizeof(n
));
360 if (RSA_generate_key_ex(rsa
, n
, e
, &cb
) != 1)
361 errx(1, "RSA_generate_key_ex");
365 for (j
= 0; j
< 8; j
++) {
366 unsigned char sha1
[20];
367 RAND_bytes(sha1
, sizeof(sha1
));
368 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
374 ENGINE_finish(engine
);