bignum: make mpi_init() and mpi_free() accept a single argument
[tropicssl.git] / library / rsa.c
blobc17fa924d80d33e930987f0b177e4c3520e5bf7f
1 /*
2 * The RSA public-key cryptosystem
4 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
6 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * * Neither the names of PolarSSL or XySSL 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
38 * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
39 * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
42 #include "tropicssl/config.h"
44 #if defined(TROPICSSL_RSA_C)
46 #include "tropicssl/rsa.h"
48 #include <stdlib.h>
49 #include <string.h>
50 #include <stdio.h>
53 * Initialize an RSA context
55 void rsa_init(rsa_context * ctx,
56 int padding, int hash_id, int (*f_rng) (void *), void *p_rng)
58 memset(ctx, 0, sizeof(rsa_context));
60 ctx->padding = padding;
61 ctx->hash_id = hash_id;
63 ctx->f_rng = f_rng;
64 ctx->p_rng = p_rng;
67 #if defined(TROPICSSL_GENPRIME)
70 * Generate an RSA keypair
72 int rsa_gen_key(rsa_context * ctx, int nbits, int exponent)
74 int ret;
75 mpi P1, Q1, H, G;
77 if (ctx->f_rng == NULL || nbits < 128 || exponent < 3)
78 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
80 mpi_init(&P1); mpi_init(&Q1); mpi_init(&H); mpi_init(&G);
83 * find primes P and Q with Q < P so that:
84 * GCD( E, (P-1)*(Q-1) ) == 1
86 MPI_CHK(mpi_lset(&ctx->E, exponent));
88 do {
89 MPI_CHK(mpi_gen_prime(&ctx->P, (nbits + 1) >> 1, 0,
90 ctx->f_rng, ctx->p_rng));
92 MPI_CHK(mpi_gen_prime(&ctx->Q, (nbits + 1) >> 1, 0,
93 ctx->f_rng, ctx->p_rng));
95 if (mpi_cmp_mpi(&ctx->P, &ctx->Q) < 0)
96 mpi_swap(&ctx->P, &ctx->Q);
98 if (mpi_cmp_mpi(&ctx->P, &ctx->Q) == 0)
99 continue;
101 MPI_CHK(mpi_mul_mpi(&ctx->N, &ctx->P, &ctx->Q));
102 if (mpi_msb(&ctx->N) != nbits)
103 continue;
105 MPI_CHK(mpi_sub_int(&P1, &ctx->P, 1));
106 MPI_CHK(mpi_sub_int(&Q1, &ctx->Q, 1));
107 MPI_CHK(mpi_mul_mpi(&H, &P1, &Q1));
108 MPI_CHK(mpi_gcd(&G, &ctx->E, &H));
109 } while (mpi_cmp_int(&G, 1) != 0);
112 * D = E^-1 mod ((P-1)*(Q-1))
113 * DP = D mod (P - 1)
114 * DQ = D mod (Q - 1)
115 * QP = Q^-1 mod P
117 MPI_CHK(mpi_inv_mod(&ctx->D, &ctx->E, &H));
118 MPI_CHK(mpi_mod_mpi(&ctx->DP, &ctx->D, &P1));
119 MPI_CHK(mpi_mod_mpi(&ctx->DQ, &ctx->D, &Q1));
120 MPI_CHK(mpi_inv_mod(&ctx->QP, &ctx->Q, &ctx->P));
122 ctx->len = (mpi_msb(&ctx->N) + 7) >> 3;
124 cleanup:
126 mpi_free(&G); mpi_free(&H); mpi_free(&Q1); mpi_free(&P1);
128 if (ret != 0) {
129 rsa_free(ctx);
130 return (TROPICSSL_ERR_RSA_KEY_GEN_FAILED | ret);
133 return (0);
136 #endif
139 * Check a public RSA key
141 int rsa_check_pubkey(const rsa_context * ctx)
143 if ((ctx->N.p[0] & 1) == 0 || (ctx->E.p[0] & 1) == 0)
144 return (TROPICSSL_ERR_RSA_KEY_CHECK_FAILED);
146 if (mpi_msb(&ctx->N) < 128 || mpi_msb(&ctx->N) > 4096)
147 return (TROPICSSL_ERR_RSA_KEY_CHECK_FAILED);
149 if (mpi_msb(&ctx->E) < 2 || mpi_msb(&ctx->E) > 64)
150 return (TROPICSSL_ERR_RSA_KEY_CHECK_FAILED);
152 return (0);
156 * Check a private RSA key
158 int rsa_check_privkey(const rsa_context * ctx)
160 int ret;
161 mpi PQ, DE, P1, Q1, H, I, G;
163 if ((ret = rsa_check_pubkey(ctx)) != 0)
164 return (ret);
166 mpi_init(&PQ); mpi_init(&DE); mpi_init(&P1); mpi_init(&Q1);
167 mpi_init(&H); mpi_init(&I); mpi_init(&G);
169 MPI_CHK(mpi_mul_mpi(&PQ, &ctx->P, &ctx->Q));
170 MPI_CHK(mpi_mul_mpi(&DE, &ctx->D, &ctx->E));
171 MPI_CHK(mpi_sub_int(&P1, &ctx->P, 1));
172 MPI_CHK(mpi_sub_int(&Q1, &ctx->Q, 1));
173 MPI_CHK(mpi_mul_mpi(&H, &P1, &Q1));
174 MPI_CHK(mpi_mod_mpi(&I, &DE, &H));
175 MPI_CHK(mpi_gcd(&G, &ctx->E, &H));
177 if (mpi_cmp_mpi(&PQ, &ctx->N) == 0 &&
178 mpi_cmp_int(&I, 1) == 0 && mpi_cmp_int(&G, 1) == 0) {
179 mpi_free(&G); mpi_free(&I); mpi_free(&H); mpi_free(&Q1);
180 mpi_free(&P1); mpi_free(&DE); mpi_free(&PQ);
181 return (0);
184 cleanup:
186 mpi_free(&G); mpi_free(&I); mpi_free(&H); mpi_free(&Q1);
187 mpi_free(&P1); mpi_free(&DE); mpi_free(&PQ);
188 return (TROPICSSL_ERR_RSA_KEY_CHECK_FAILED | ret);
192 * Do an RSA public key operation
194 int rsa_public(rsa_context * ctx, const unsigned char *input, unsigned char *output)
196 int ret, olen;
197 mpi T;
199 mpi_init(&T);
201 MPI_CHK(mpi_read_binary(&T, input, ctx->len));
203 if (mpi_cmp_mpi(&T, &ctx->N) >= 0) {
204 mpi_free(&T);
205 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
208 olen = ctx->len;
209 MPI_CHK(mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
210 MPI_CHK(mpi_write_binary(&T, output, olen));
212 cleanup:
214 mpi_free(&T);
216 if (ret != 0)
217 return (TROPICSSL_ERR_RSA_PUBLIC_FAILED | ret);
219 return (0);
223 * Do an RSA private key operation
225 int rsa_private(rsa_context * ctx, const unsigned char *input, unsigned char *output)
227 int ret, olen;
228 mpi T, T1, T2;
230 mpi_init(&T); mpi_init(&T1); mpi_init(&T2);
232 MPI_CHK(mpi_read_binary(&T, input, ctx->len));
234 if (mpi_cmp_mpi(&T, &ctx->N) >= 0) {
235 mpi_free(&T);
236 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
238 #if 0
239 MPI_CHK(mpi_exp_mod(&T, &T, &ctx->D, &ctx->N, &ctx->RN));
240 #else
242 * faster decryption using the CRT
244 * T1 = input ^ dP mod P
245 * T2 = input ^ dQ mod Q
247 MPI_CHK(mpi_exp_mod(&T1, &T, &ctx->DP, &ctx->P, &ctx->RP));
248 MPI_CHK(mpi_exp_mod(&T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ));
251 * T = (T1 - T2) * (Q^-1 mod P) mod P
253 MPI_CHK(mpi_sub_mpi(&T, &T1, &T2));
254 MPI_CHK(mpi_mul_mpi(&T1, &T, &ctx->QP));
255 MPI_CHK(mpi_mod_mpi(&T, &T1, &ctx->P));
258 * output = T2 + T * Q
260 MPI_CHK(mpi_mul_mpi(&T1, &T, &ctx->Q));
261 MPI_CHK(mpi_add_mpi(&T, &T2, &T1));
262 #endif
264 olen = ctx->len;
265 MPI_CHK(mpi_write_binary(&T, output, olen));
267 cleanup:
269 mpi_free(&T); mpi_free(&T1); mpi_free(&T2);
271 if (ret != 0)
272 return (TROPICSSL_ERR_RSA_PRIVATE_FAILED | ret);
274 return (0);
278 * Add the message padding, then do an RSA operation
280 int rsa_pkcs1_encrypt(rsa_context * ctx,
281 int mode, int ilen,
282 const unsigned char *input,
283 unsigned char *output)
285 int nb_pad, olen;
286 unsigned char *p = output;
288 olen = ctx->len;
290 switch (ctx->padding) {
291 case RSA_PKCS_V15:
293 if (ilen < 0 || olen < ilen + 11)
294 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
296 nb_pad = olen - 3 - ilen;
298 *p++ = 0;
299 *p++ = RSA_CRYPT;
301 while (nb_pad-- > 0) {
302 do {
303 *p = (unsigned char)rand();
304 } while (*p == 0);
305 p++;
307 *p++ = 0;
308 memcpy(p, input, ilen);
309 break;
311 default:
313 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
316 return ((mode == RSA_PUBLIC)
317 ? rsa_public(ctx, output, output)
318 : rsa_private(ctx, output, output));
322 * Do an RSA operation, then remove the message padding
324 int rsa_pkcs1_decrypt(rsa_context * ctx,
325 int mode, int *olen,
326 const unsigned char *input,
327 unsigned char *output,
328 int output_max_len)
330 int ret, ilen;
331 unsigned char *p;
332 unsigned char buf[512];
334 ilen = ctx->len;
336 if (ilen < 16 || ilen > (int)sizeof(buf))
337 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
339 ret = (mode == RSA_PUBLIC)
340 ? rsa_public(ctx, input, buf)
341 : rsa_private(ctx, input, buf);
343 if (ret != 0)
344 return (ret);
346 p = buf;
348 switch (ctx->padding) {
349 case RSA_PKCS_V15:
351 if (*p++ != 0 || *p++ != RSA_CRYPT)
352 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
354 while (*p != 0) {
355 if (p >= buf + ilen - 1)
356 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
357 p++;
359 p++;
360 break;
362 default:
364 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
367 if (ilen - (int)(p - buf) > output_max_len)
368 return (TROPICSSL_ERR_RSA_OUTPUT_TO_LARGE);
370 *olen = ilen - (int)(p - buf);
371 memcpy(output, p, *olen);
373 return (0);
377 * Do an RSA operation to sign the message digest
379 int rsa_pkcs1_sign(rsa_context * ctx,
380 int mode,
381 int hash_id,
382 int hashlen,
383 const unsigned char *hash,
384 unsigned char *sig)
386 int nb_pad, olen;
387 unsigned char *p = sig;
389 olen = ctx->len;
391 switch (ctx->padding) {
392 case RSA_PKCS_V15:
394 switch (hash_id) {
395 case RSA_RAW:
396 nb_pad = olen - 3 - hashlen;
397 break;
399 case RSA_MD2:
400 case RSA_MD4:
401 case RSA_MD5:
402 nb_pad = olen - 3 - 34;
403 break;
405 case RSA_SHA1:
406 nb_pad = olen - 3 - 35;
407 break;
409 default:
410 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
413 if (nb_pad < 8)
414 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
416 *p++ = 0;
417 *p++ = RSA_SIGN;
418 memset(p, 0xFF, nb_pad);
419 p += nb_pad;
420 *p++ = 0;
421 break;
423 default:
425 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
428 switch (hash_id) {
429 case RSA_RAW:
430 memcpy(p, hash, hashlen);
431 break;
433 case RSA_MD2:
434 memcpy(p, ASN1_HASH_MDX, 18);
435 memcpy(p + 18, hash, 16);
436 p[13] = 2;
437 break;
439 case RSA_MD4:
440 memcpy(p, ASN1_HASH_MDX, 18);
441 memcpy(p + 18, hash, 16);
442 p[13] = 4;
443 break;
445 case RSA_MD5:
446 memcpy(p, ASN1_HASH_MDX, 18);
447 memcpy(p + 18, hash, 16);
448 p[13] = 5;
449 break;
451 case RSA_SHA1:
452 memcpy(p, ASN1_HASH_SHA1, 15);
453 memcpy(p + 15, hash, 20);
454 break;
456 default:
457 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
460 return ((mode == RSA_PUBLIC)
461 ? rsa_public(ctx, sig, sig)
462 : rsa_private(ctx, sig, sig));
466 * Do an RSA operation and check the message digest
468 int rsa_pkcs1_verify(rsa_context * ctx,
469 int mode,
470 int hash_id,
471 int hashlen,
472 const unsigned char *hash,
473 const unsigned char *sig)
475 int ret, len, siglen;
476 unsigned char *p, c;
477 unsigned char buf[512];
479 siglen = ctx->len;
481 if (siglen < 16 || siglen > (int)sizeof(buf))
482 return (TROPICSSL_ERR_RSA_BAD_INPUT_DATA);
484 ret = (mode == RSA_PUBLIC)
485 ? rsa_public(ctx, sig, buf)
486 : rsa_private(ctx, sig, buf);
488 if (ret != 0)
489 return (ret);
491 p = buf;
493 switch (ctx->padding) {
494 case RSA_PKCS_V15:
496 if (*p++ != 0 || *p++ != RSA_SIGN)
497 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
499 while (*p != 0) {
500 if (p >= buf + siglen - 1 || *p != 0xFF)
501 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
502 p++;
504 p++;
505 break;
507 default:
509 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
512 len = siglen - (int)(p - buf);
514 if (len == 34) {
515 c = p[13];
516 p[13] = 0;
518 if (memcmp(p, ASN1_HASH_MDX, 18) != 0)
519 return (TROPICSSL_ERR_RSA_VERIFY_FAILED);
521 if ((c == 2 && hash_id == RSA_MD2) ||
522 (c == 4 && hash_id == RSA_MD4) ||
523 (c == 5 && hash_id == RSA_MD5)) {
524 if (memcmp(p + 18, hash, 16) == 0)
525 return (0);
526 else
527 return (TROPICSSL_ERR_RSA_VERIFY_FAILED);
531 if (len == 35 && hash_id == RSA_SHA1) {
532 if (memcmp(p, ASN1_HASH_SHA1, 15) == 0 &&
533 memcmp(p + 15, hash, 20) == 0)
534 return (0);
535 else
536 return (TROPICSSL_ERR_RSA_VERIFY_FAILED);
539 if (len == hashlen && hash_id == RSA_RAW) {
540 if (memcmp(p, hash, hashlen) == 0)
541 return (0);
542 else
543 return (TROPICSSL_ERR_RSA_VERIFY_FAILED);
546 return (TROPICSSL_ERR_RSA_INVALID_PADDING);
550 * Free the components of an RSA key
552 void rsa_free(rsa_context * ctx)
554 mpi_free(&ctx->RQ); mpi_free(&ctx->RP); mpi_free(&ctx->RN);
555 mpi_free(&ctx->QP); mpi_free(&ctx->DQ); mpi_free(&ctx->DP);
556 mpi_free(&ctx->Q); mpi_free(&ctx->P); mpi_free(&ctx->D);
557 mpi_free(&ctx->E); mpi_free(&ctx->N);
560 #if defined(TROPICSSL_SELF_TEST)
562 #include "tropicssl/sha1.h"
565 * Example RSA-1024 keypair, for test purposes
567 #define KEY_LEN 128
569 #define RSA_N "9292758453063D803DD603D5E777D788" \
570 "8ED1D5BF35786190FA2F23EBC0848AEA" \
571 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
572 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
573 "93A89813FBF3C4F8066D2D800F7C38A8" \
574 "1AE31942917403FF4946B0A83D3D3E05" \
575 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
576 "5E94BB77B07507233A0BC7BAC8F90F79"
578 #define RSA_E "10001"
580 #define RSA_D "24BF6185468786FDD303083D25E64EFC" \
581 "66CA472BC44D253102F8B4A9D3BFA750" \
582 "91386C0077937FE33FA3252D28855837" \
583 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
584 "DF79C5CE07EE72C7F123142198164234" \
585 "CABB724CF78B8173B9F880FC86322407" \
586 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
587 "071513A1E85B5DFA031F21ECAE91A34D"
589 #define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
590 "2C01CAD19EA484A87EA4377637E75500" \
591 "FCB2005C5C7DD6EC4AC023CDA285D796" \
592 "C3D9E75E1EFC42488BB4F1D13AC30A57"
594 #define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
595 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
596 "910E4168387E3C30AA1E00C339A79508" \
597 "8452DD96A9A5EA5D9DCA68DA636032AF"
599 #define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
600 "3C94D22288ACD763FD8E5600ED4A702D" \
601 "F84198A5F06C2E72236AE490C93F07F8" \
602 "3CC559CD27BC2D1CA488811730BB5725"
604 #define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
605 "D8AAEA56749EA28623272E4F7D0592AF" \
606 "7C1F1313CAC9471B5C523BFE592F517B" \
607 "407A1BD76C164B93DA2D32A383E58357"
609 #define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
610 "F38D18D2B2F0E2DD275AA977E2BF4411" \
611 "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
612 "A74206CEC169D74BF5A8C50D6F48EA08"
614 #define PT_LEN 24
615 #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
616 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
619 * Checkup routine
621 int rsa_self_test(int verbose)
623 int len;
624 rsa_context rsa;
625 unsigned char sha1sum[20];
626 unsigned char rsa_plaintext[PT_LEN];
627 unsigned char rsa_decrypted[PT_LEN];
628 unsigned char rsa_ciphertext[KEY_LEN];
630 memset(&rsa, 0, sizeof(rsa_context));
632 rsa.len = KEY_LEN;
633 mpi_read_string(&rsa.N, 16, RSA_N);
634 mpi_read_string(&rsa.E, 16, RSA_E);
635 mpi_read_string(&rsa.D, 16, RSA_D);
636 mpi_read_string(&rsa.P, 16, RSA_P);
637 mpi_read_string(&rsa.Q, 16, RSA_Q);
638 mpi_read_string(&rsa.DP, 16, RSA_DP);
639 mpi_read_string(&rsa.DQ, 16, RSA_DQ);
640 mpi_read_string(&rsa.QP, 16, RSA_QP);
642 if (verbose != 0)
643 printf(" RSA key validation: ");
645 if (rsa_check_pubkey(&rsa) != 0 || rsa_check_privkey(&rsa) != 0) {
646 if (verbose != 0)
647 printf("failed\n");
649 return (1);
652 if (verbose != 0)
653 printf("passed\n PKCS#1 encryption : ");
655 memcpy(rsa_plaintext, RSA_PT, PT_LEN);
657 if (rsa_pkcs1_encrypt(&rsa, RSA_PUBLIC, PT_LEN,
658 rsa_plaintext, rsa_ciphertext) != 0) {
659 if (verbose != 0)
660 printf("failed\n");
662 return (1);
665 if (verbose != 0)
666 printf("passed\n PKCS#1 decryption : ");
668 if (rsa_pkcs1_decrypt(&rsa, RSA_PRIVATE, &len,
669 rsa_ciphertext, rsa_decrypted,
670 sizeof(rsa_decrypted)) != 0) {
671 if (verbose != 0)
672 printf("failed\n");
674 return (1);
677 if (memcmp(rsa_decrypted, rsa_plaintext, len) != 0) {
678 if (verbose != 0)
679 printf("failed\n");
681 return (1);
684 if (verbose != 0)
685 printf("passed\n PKCS#1 data sign : ");
687 sha1(rsa_plaintext, PT_LEN, sha1sum);
689 if (rsa_pkcs1_sign(&rsa, RSA_PRIVATE, RSA_SHA1, 20,
690 sha1sum, rsa_ciphertext) != 0) {
691 if (verbose != 0)
692 printf("failed\n");
694 return (1);
697 if (verbose != 0)
698 printf("passed\n PKCS#1 sig. verify: ");
700 if (rsa_pkcs1_verify(&rsa, RSA_PUBLIC, RSA_SHA1, 20,
701 sha1sum, rsa_ciphertext) != 0) {
702 if (verbose != 0)
703 printf("failed\n");
705 return (1);
708 if (verbose != 0)
709 printf("passed\n\n");
711 rsa_free(&rsa);
713 return (0);
716 #endif
718 #endif