No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / hcrypto / test_rsa.c
blob5e12bd7cf887ec44b24e333099b76e4fd526c86f
1 /*
2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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
31 * SUCH DAMAGE.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 #ifdef RCSID
39 __RCSID("$Heimdal: test_rsa.c 20466 2007-04-20 08:29:05Z lha $"
40 "$NetBSD$");
41 #endif
43 #include <stdio.h>
45 #include <roken.h>
46 #include <getarg.h>
48 #include <engine.h>
49 #include <evp.h>
55 static int version_flag;
56 static int help_flag;
57 static int time_keygen;
58 static char *time_key;
59 static int key_blinding = 1;
60 static char *rsa_key;
61 static char *id_flag;
62 static int loops = 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,
80 NULL, NULL }
87 static void
88 check_rsa(const unsigned char *in, size_t len, RSA *rsa, int padding)
90 unsigned char *res, *res2;
91 int keylen;
93 res = malloc(RSA_size(rsa));
94 if (res == NULL)
95 errx(1, "res: ENOMEM");
97 res2 = malloc(RSA_size(rsa));
98 if (res2 == NULL)
99 errx(1, "res2: ENOMEM");
101 /* signing */
103 keylen = RSA_private_encrypt(len, in, res, rsa, padding);
104 if (keylen <= 0)
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);
111 if (keylen <= 0)
112 errx(1, "failed to public decrypt: %d", (int)keylen);
114 if (keylen != len)
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");
120 /* encryption */
122 keylen = RSA_public_encrypt(len, in, res, rsa, padding);
123 if (keylen <= 0)
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);
130 if (keylen <= 0)
131 errx(1, "failed to private decrypt: %d", (int)keylen);
133 if (keylen != len)
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");
139 free(res);
140 free(res2);
143 static int
144 cb_func(int a, int b, BN_GENCB *c)
146 return 1;
149 static RSA *
150 read_key(ENGINE *engine, const char *rsa_key)
152 unsigned char buf[1024 * 4];
153 const unsigned char *p;
154 size_t size;
155 RSA *rsa;
156 FILE *f;
158 f = fopen(rsa_key, "r");
159 if (f == NULL)
160 err(1, "could not open file %s", rsa_key);
162 size = fread(buf, 1, sizeof(buf), f);
163 fclose(f);
164 if (size == 0)
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);
169 p = buf;
170 rsa = d2i_RSAPrivateKey(NULL, &p, size);
171 if (rsa == NULL)
172 err(1, "failed to parse key in file %s", rsa_key);
174 RSA_set_method(rsa, ENGINE_get_RSA(engine));
176 if (!key_blinding)
177 rsa->flags |= RSA_FLAG_NO_BLINDING;
179 return rsa;
186 static void
187 usage (int ret)
189 arg_printusage (args,
190 sizeof(args)/sizeof(*args),
191 NULL,
192 "filename.so");
193 exit (ret);
197 main(int argc, char **argv)
199 ENGINE *engine = NULL;
200 int i, j, idx = 0;
201 RSA *rsa;
203 setprogname(argv[0]);
205 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &idx))
206 usage(1);
208 if (help_flag)
209 usage(0);
211 if(version_flag){
212 print_version(NULL);
213 exit(0);
216 argc -= idx;
217 argv += idx;
219 OpenSSL_add_all_algorithms();
221 if (argc == 0) {
222 OpenSSL_add_all_algorithms();
223 ENGINE_load_builtin_engines();
224 engine = ENGINE_by_id("builtin");
225 } else {
226 engine = ENGINE_by_dso(argv[0], id_flag);
228 if (engine == NULL)
229 errx(1, "ENGINE_by_dso failed");
231 if (ENGINE_get_RSA(engine) == NULL)
232 return 77;
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");
239 if (time_keygen) {
240 struct timeval tv1, tv2;
241 const int num = 10;
242 BIGNUM *e;
244 rsa = RSA_new_method(engine);
245 if (!key_blinding)
246 rsa->flags |= RSA_FLAG_NO_BLINDING;
248 e = BN_new();
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");
257 RSA_free(rsa);
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);
267 BN_free(e);
268 ENGINE_finish(engine);
270 return 0;
273 if (time_key) {
274 const int size = 20;
275 const int num = 128;
276 struct timeval tv1, tv2;
277 unsigned char *p;
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);
296 RSA_free(rsa);
297 ENGINE_finish(engine);
299 return 0;
302 if (rsa_key) {
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);
339 RSA_free(rsa);
342 for (i = 0; i < loops; i++) {
343 BN_GENCB cb;
344 BIGNUM *e;
345 unsigned int n;
347 rsa = RSA_new_method(engine);
348 if (!key_blinding)
349 rsa->flags |= RSA_FLAG_NO_BLINDING;
351 e = BN_new();
352 BN_set_word(e, 0x10001);
354 BN_GENCB_set(&cb, cb_func, NULL);
356 RAND_bytes(&n, sizeof(n));
357 n &= 0x1ff;
358 n += 1024;
360 if (RSA_generate_key_ex(rsa, n, e, &cb) != 1)
361 errx(1, "RSA_generate_key_ex");
363 BN_free(e);
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);
371 RSA_free(rsa);
374 ENGINE_finish(engine);
376 return 0;