1 /* $NetBSD: test_rsa.c,v 1.1.1.2 2014/04/24 12:45:30 pettai Exp $ */
4 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #include <krb5/roken.h>
41 #include <krb5/getarg.h>
50 static int version_flag
;
52 static int time_keygen
;
53 static char *time_key
;
54 static int key_blinding
= 1;
59 static struct getargs args
[] = {
60 { "loops", 0, arg_integer
, &loops
,
61 "number of loops", "loops" },
62 { "id", 0, arg_string
, &id_flag
,
63 "selects the engine id", "engine-id" },
64 { "time-keygen", 0, arg_flag
, &time_keygen
,
65 "time rsa generation", NULL
},
66 { "time-key", 0, arg_string
, &time_key
,
67 "rsa key file", NULL
},
68 { "key-blinding", 0, arg_negative_flag
, &key_blinding
,
69 "key blinding", NULL
},
70 { "key", 0, arg_string
, &rsa_key
,
71 "rsa key file", NULL
},
72 { "version", 0, arg_flag
, &version_flag
,
73 "print version", NULL
},
74 { "help", 0, arg_flag
, &help_flag
,
83 check_rsa(const unsigned char *in
, size_t len
, RSA
*rsa
, int padding
)
85 unsigned char *res
, *res2
;
89 res
= malloc(RSA_size(rsa
));
91 errx(1, "res: ENOMEM");
93 res2
= malloc(RSA_size(rsa
));
95 errx(1, "res2: ENOMEM");
99 keylen
= RSA_private_encrypt(len
, in
, res
, rsa
, padding
);
101 errx(1, "failed to private encrypt: %d %d", (int)len
, (int)keylen
);
103 if (keylen
> RSA_size(rsa
))
104 errx(1, "keylen > RSA_size(rsa)");
106 keylen
= RSA_public_decrypt(keylen
, res
, res2
, rsa
, padding
);
108 errx(1, "failed to public decrypt: %d", (int)keylen
);
111 errx(1, "output buffer not same length: %d", (int)keylen
);
113 if (memcmp(res2
, in
, len
) != 0)
114 errx(1, "string not the same after decryption");
118 keylen
= RSA_public_encrypt(len
, in
, res
, rsa
, padding
);
120 errx(1, "failed to public encrypt: %d", (int)keylen
);
122 if (keylen
> RSA_size(rsa
))
123 errx(1, "keylen > RSA_size(rsa)");
125 keylen
= RSA_private_decrypt(keylen
, res
, res2
, rsa
, padding
);
127 errx(1, "failed to private decrypt: %d", (int)keylen
);
130 errx(1, "output buffer not same length: %d", (int)keylen
);
132 if (memcmp(res2
, in
, len
) != 0)
133 errx(1, "string not the same after decryption");
137 if (RSA_sign(NID_sha1
, in
, len
, res
, &len2
, rsa
) != 1)
138 errx(1, "RSA_sign failed");
140 if (RSA_verify(NID_sha1
, in
, len
, res
, len2
, rsa
) != 1)
141 errx(1, "RSA_verify failed");
148 cb_func(int a
, int b
, BN_GENCB
*c
)
154 read_key(ENGINE
*engine
, const char *rsa_key
)
156 unsigned char buf
[1024 * 4];
157 const unsigned char *p
;
162 f
= fopen(rsa_key
, "rb");
164 err(1, "could not open file %s", rsa_key
);
167 size
= fread(buf
, 1, sizeof(buf
), f
);
170 err(1, "failed to read file %s", rsa_key
);
171 if (size
== sizeof(buf
))
172 err(1, "key too long in file %s!", rsa_key
);
175 rsa
= d2i_RSAPrivateKey(NULL
, &p
, size
);
177 err(1, "failed to parse key in file %s", rsa_key
);
179 RSA_set_method(rsa
, ENGINE_get_RSA(engine
));
182 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
194 arg_printusage (args
,
195 sizeof(args
)/sizeof(*args
),
202 main(int argc
, char **argv
)
204 ENGINE
*engine
= NULL
;
208 setprogname(argv
[0]);
210 if(getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &idx
))
224 OpenSSL_add_all_algorithms();
226 ENGINE_load_openssl();
228 ENGINE_load_builtin_engines();
231 engine
= ENGINE_by_id("builtin");
233 engine
= ENGINE_by_id(argv
[0]);
235 engine
= ENGINE_by_dso(argv
[0], id_flag
);
238 errx(1, "ENGINE_by_dso failed");
240 if (ENGINE_get_RSA(engine
) == NULL
)
243 printf("rsa %s\n", ENGINE_get_RSA(engine
)->name
);
245 if (RAND_status() != 1)
246 errx(77, "no functional random device, refusing to run tests");
249 struct timeval tv1
, tv2
;
252 rsa
= RSA_new_method(engine
);
254 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
257 BN_set_word(e
, 0x10001);
259 printf("running keygen with %d loops\n", loops
);
261 gettimeofday(&tv1
, NULL
);
263 for (i
= 0; i
< loops
; i
++) {
264 rsa
= RSA_new_method(engine
);
265 if (RSA_generate_key_ex(rsa
, 1024, e
, NULL
) != 1)
266 errx(1, "RSA_generate_key_ex");
270 gettimeofday(&tv2
, NULL
);
271 timevalsub(&tv2
, &tv1
);
273 printf("time %lu.%06lu\n",
274 (unsigned long)tv2
.tv_sec
,
275 (unsigned long)tv2
.tv_usec
);
278 ENGINE_finish(engine
);
285 struct timeval tv1
, tv2
;
288 if (strcmp(time_key
, "generate") == 0) {
291 rsa
= RSA_new_method(engine
);
293 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
296 BN_set_word(e
, 0x10001);
298 if (RSA_generate_key_ex(rsa
, 1024, e
, NULL
) != 1)
299 errx(1, "RSA_generate_key_ex");
301 rsa
= read_key(engine
, time_key
);
304 p
= emalloc(loops
* size
);
306 RAND_bytes(p
, loops
* size
);
308 gettimeofday(&tv1
, NULL
);
309 for (i
= 0; i
< loops
; i
++)
310 check_rsa(p
+ (i
* size
), size
, rsa
, RSA_PKCS1_PADDING
);
311 gettimeofday(&tv2
, NULL
);
313 timevalsub(&tv2
, &tv1
);
315 printf("time %lu.%06lu\n",
316 (unsigned long)tv2
.tv_sec
,
317 (unsigned long)tv2
.tv_usec
);
320 ENGINE_finish(engine
);
326 rsa
= read_key(engine
, rsa_key
);
329 * Assuming that you use the RSA key in the distribution, this
330 * test will generate a signature have a starting zero and thus
331 * will generate a checksum that is 127 byte instead of the
332 * checksum that is 128 byte (like the key).
335 const unsigned char sha1
[20] = {
336 0x6d, 0x33, 0xf9, 0x40, 0x75, 0x5b, 0x4e, 0xc5, 0x90, 0x35,
337 0x48, 0xab, 0x75, 0x02, 0x09, 0x76, 0x9a, 0xb4, 0x7d, 0x6b
340 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
343 for (i
= 0; i
< 128; i
++) {
344 unsigned char sha1
[20];
346 RAND_bytes(sha1
, sizeof(sha1
));
347 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
349 for (i
= 0; i
< 128; i
++) {
350 unsigned char des3
[21];
352 RAND_bytes(des3
, sizeof(des3
));
353 check_rsa(des3
, sizeof(des3
), rsa
, RSA_PKCS1_PADDING
);
355 for (i
= 0; i
< 128; i
++) {
356 unsigned char aes
[32];
358 RAND_bytes(aes
, sizeof(aes
));
359 check_rsa(aes
, sizeof(aes
), rsa
, RSA_PKCS1_PADDING
);
365 for (i
= 0; i
< loops
; i
++) {
370 rsa
= RSA_new_method(engine
);
372 rsa
->flags
|= RSA_FLAG_NO_BLINDING
;
375 BN_set_word(e
, 0x10001);
377 BN_GENCB_set(&cb
, cb_func
, NULL
);
379 RAND_bytes(&n
, sizeof(n
));
383 if (RSA_generate_key_ex(rsa
, n
, e
, &cb
) != 1)
384 errx(1, "RSA_generate_key_ex");
388 for (j
= 0; j
< 8; j
++) {
389 unsigned char sha1
[20];
390 RAND_bytes(sha1
, sizeof(sha1
));
391 check_rsa(sha1
, sizeof(sha1
), rsa
, RSA_PKCS1_PADDING
);
397 ENGINE_finish(engine
);