/home/dko/projects/mobilec/trunk/src/security/xyssl-0.9/library/rsa.c

Go to the documentation of this file.
00001 /*
00002  * The RSA public-key cryptosystem
00003  *
00004  * Copyright (C) 2006-2007 Christophe Devine
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 /*
00021  * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
00022  *
00023  * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
00024  * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
00025  */
00026 
00027 #include "xyssl/config.h"
00028 
00029 #if defined(XYSSL_RSA_C)
00030 
00031 #include "xyssl/rsa.h"
00032 
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <stdio.h>
00036 
00037 /*
00038  * Initialize an RSA context
00039  */
00040 void rsa_init( rsa_context *ctx,
00041 int padding,
00042 int hash_id,
00043 int (*f_rng)(void *),
00044 void *p_rng )
00045 {
00046 memset( ctx, 0, sizeof( rsa_context ) );
00047 
00048 ctx->padding = padding;
00049 ctx->hash_id = hash_id;
00050 
00051 ctx->f_rng = f_rng;
00052 ctx->p_rng = p_rng;
00053 }
00054 
00055 #if defined(XYSSL_GENPRIME)
00056 
00057 /*
00058  * Generate an RSA keypair
00059  */
00060 int rsa_gen_key( rsa_context *ctx, int nbits, int exponent )
00061 {
00062 int ret;
00063 mpi P1, Q1, H, G;
00064 
00065 if( ctx->f_rng == NULL || nbits < 128 || exponent < 3 )
00066 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00067 
00068 mpi_init( &P1, &Q1, &H, &G, NULL );
00069 
00070 /*
00071  * find primes P and Q with Q < P so that:
00072  * GCD( E, (P-1)*(Q-1) ) == 1
00073  */
00074 MPI_CHK( mpi_lset( &ctx->E, exponent ) );
00075 
00076 do
00077 {
00078 MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0, 
00079 ctx->f_rng, ctx->p_rng ) );
00080 
00081 MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
00082 ctx->f_rng, ctx->p_rng ) );
00083 
00084 if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
00085 mpi_swap( &ctx->P, &ctx->Q );
00086 
00087 if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
00088 continue;
00089 
00090 MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
00091 if( mpi_msb( &ctx->N ) != nbits )
00092 continue;
00093 
00094 MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
00095 MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
00096 MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
00097 MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
00098 }
00099 while( mpi_cmp_int( &G, 1 ) != 0 );
00100 
00101 /*
00102  * D = E^-1 mod ((P-1)*(Q-1))
00103  * DP = D mod (P - 1)
00104  * DQ = D mod (Q - 1)
00105  * QP = Q^-1 mod P
00106  */
00107 MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
00108 MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
00109 MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
00110 MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
00111 
00112 ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
00113 
00114 cleanup:
00115 
00116 mpi_free( &G, &H, &Q1, &P1, NULL );
00117 
00118 if( ret != 0 )
00119 {
00120 rsa_free( ctx );
00121 return( XYSSL_ERR_RSA_KEY_GEN_FAILED | ret );
00122 }
00123 
00124 return( 0 ); 
00125 }
00126 
00127 #endif
00128 
00129 /*
00130  * Check a public RSA key
00131  */
00132 int rsa_check_pubkey( rsa_context *ctx )
00133 {
00134 if( ( ctx->N.p[0] & 1 ) == 0 || 
00135 ( ctx->E.p[0] & 1 ) == 0 )
00136 return( XYSSL_ERR_RSA_KEY_CHECK_FAILED );
00137 
00138 if( mpi_msb( &ctx->N ) < 128 ||
00139 mpi_msb( &ctx->N ) > 4096 )
00140 return( XYSSL_ERR_RSA_KEY_CHECK_FAILED );
00141 
00142 if( mpi_msb( &ctx->E ) < 2 ||
00143 mpi_msb( &ctx->E ) > 64 )
00144 return( XYSSL_ERR_RSA_KEY_CHECK_FAILED );
00145 
00146 return( 0 );
00147 }
00148 
00149 /*
00150  * Check a private RSA key
00151  */
00152 int rsa_check_privkey( rsa_context *ctx )
00153 {
00154 int ret;
00155 mpi PQ, DE, P1, Q1, H, I, G;
00156 
00157 if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
00158 return( ret );
00159 
00160 mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, NULL );
00161 
00162 MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
00163 MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
00164 MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
00165 MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
00166 MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
00167 MPI_CHK( mpi_mod_mpi( &I, &DE, &H ) );
00168 MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
00169 
00170 if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
00171 mpi_cmp_int( &I, 1 ) == 0 &&
00172 mpi_cmp_int( &G, 1 ) == 0 )
00173 {
00174 mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
00175 return( 0 );
00176 }
00177 
00178 cleanup:
00179 
00180 mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
00181 return( XYSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
00182 }
00183 
00184 /*
00185  * Do an RSA public key operation
00186  */
00187 int rsa_public( rsa_context *ctx,
00188 unsigned char *input,
00189 unsigned char *output )
00190 {
00191 int ret, olen;
00192 mpi T;
00193 
00194 mpi_init( &T, NULL );
00195 
00196 MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
00197 
00198 if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
00199 {
00200 mpi_free( &T, NULL );
00201 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00202 }
00203 
00204 olen = ctx->len;
00205 MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
00206 MPI_CHK( mpi_write_binary( &T, output, olen ) );
00207 
00208 cleanup:
00209 
00210 mpi_free( &T, NULL );
00211 
00212 if( ret != 0 )
00213 return( XYSSL_ERR_RSA_PUBLIC_FAILED | ret );
00214 
00215 return( 0 );
00216 }
00217 
00218 /*
00219  * Do an RSA private key operation
00220  */
00221 int rsa_private( rsa_context *ctx,
00222 unsigned char *input,
00223 unsigned char *output )
00224 {
00225 int ret, olen;
00226 mpi T, T1, T2;
00227 
00228 mpi_init( &T, &T1, &T2, NULL );
00229 
00230 MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
00231 
00232 if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
00233 {
00234 mpi_free( &T, NULL );
00235 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00236 }
00237 
00238 #if 0
00239 MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
00240 #else
00241 /*
00242  * faster decryption using the CRT
00243  *
00244  * T1 = input ^ dP mod P
00245  * T2 = input ^ dQ mod Q
00246  */
00247 MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
00248 MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
00249 
00250 /*
00251  * T = (T1 - T2) * (Q^-1 mod P) mod P
00252  */
00253 MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
00254 MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
00255 MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
00256 
00257 /*
00258  * output = T2 + T * Q
00259  */
00260 MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
00261 MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
00262 #endif
00263 
00264 olen = ctx->len;
00265 MPI_CHK( mpi_write_binary( &T, output, olen ) );
00266 
00267 cleanup:
00268 
00269 mpi_free( &T, &T1, &T2, NULL );
00270 
00271 if( ret != 0 )
00272 return( XYSSL_ERR_RSA_PRIVATE_FAILED | ret );
00273 
00274 return( 0 );
00275 }
00276 
00277 /*
00278  * Add the message padding, then do an RSA operation
00279  */
00280 int rsa_pkcs1_encrypt( rsa_context *ctx,
00281 int mode, int ilen,
00282 unsigned char *input,
00283 unsigned char *output )
00284 {
00285 int nb_pad, olen;
00286 unsigned char *p = output;
00287 
00288 olen = ctx->len;
00289 
00290 switch( ctx->padding )
00291 {
00292 case RSA_PKCS_V15:
00293 
00294 if( ilen < 0 || olen < ilen + 11 )
00295 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00296 
00297 nb_pad = olen - 3 - ilen;
00298 
00299 *p++ = 0;
00300 *p++ = RSA_CRYPT;
00301 
00302 while( nb_pad-- > 0 )
00303 {
00304 do {
00305 *p = (unsigned char) rand();
00306 } while( *p == 0 );
00307 p++;
00308 }
00309 *p++ = 0;
00310 memcpy( p, input, ilen );
00311 break;
00312 
00313 default:
00314 
00315 return( XYSSL_ERR_RSA_INVALID_PADDING );
00316 }
00317 
00318 return( ( mode == RSA_PUBLIC )
00319 ? rsa_public( ctx, output, output )
00320 : rsa_private( ctx, output, output ) );
00321 }
00322 
00323 /*
00324  * Do an RSA operation, then remove the message padding
00325  */
00326 int rsa_pkcs1_decrypt( rsa_context *ctx,
00327 int mode, int *olen,
00328 unsigned char *input,
00329 unsigned char *output )
00330 {
00331 int ret, ilen;
00332 unsigned char *p;
00333 unsigned char buf[512];
00334 
00335 ilen = ctx->len;
00336 
00337 if( ilen < 16 || ilen > (int) sizeof( buf ) )
00338 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00339 
00340 ret = ( mode == RSA_PUBLIC )
00341 ? rsa_public( ctx, input, buf )
00342 : rsa_private( ctx, input, buf );
00343 
00344 if( ret != 0 )
00345 return( ret );
00346 
00347 p = buf;
00348 
00349 switch( ctx->padding )
00350 {
00351 case RSA_PKCS_V15:
00352 
00353 if( *p++ != 0 || *p++ != RSA_CRYPT )
00354 return( XYSSL_ERR_RSA_INVALID_PADDING );
00355 
00356 while( *p != 0 )
00357 {
00358 if( p >= buf + ilen - 1 )
00359 return( XYSSL_ERR_RSA_INVALID_PADDING );
00360 p++;
00361 }
00362 p++;
00363 break;
00364 
00365 default:
00366 
00367 return( XYSSL_ERR_RSA_INVALID_PADDING );
00368 }
00369 
00370 *olen = ilen - (int)(p - buf);
00371 memcpy( output, p, *olen );
00372 
00373 return( 0 );
00374 }
00375 
00376 /*
00377  * Do an RSA operation to sign the message digest
00378  */
00379 int rsa_pkcs1_sign( rsa_context *ctx,
00380 int mode,
00381 int hash_id,
00382 int hashlen,
00383 unsigned char *hash,
00384 unsigned char *sig )
00385 {
00386 int nb_pad, olen;
00387 unsigned char *p = sig;
00388 
00389 olen = ctx->len;
00390 
00391 switch( ctx->padding )
00392 {
00393 case RSA_PKCS_V15:
00394 
00395 switch( hash_id )
00396 {
00397 case RSA_RAW:
00398 nb_pad = olen - 3 - hashlen;
00399 break;
00400 
00401 case RSA_MD2:
00402 case RSA_MD4:
00403 case RSA_MD5:
00404 nb_pad = olen - 3 - 34;
00405 break;
00406 
00407 case RSA_SHA1:
00408 nb_pad = olen - 3 - 35;
00409 break;
00410 
00411 default:
00412 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00413 }
00414 
00415 if( nb_pad < 8 )
00416 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00417 
00418 *p++ = 0;
00419 *p++ = RSA_SIGN;
00420 memset( p, 0xFF, nb_pad );
00421 p += nb_pad;
00422 *p++ = 0;
00423 break;
00424 
00425 default:
00426 
00427 return( XYSSL_ERR_RSA_INVALID_PADDING );
00428 }
00429 
00430 switch( hash_id )
00431 {
00432 case RSA_RAW:
00433 memcpy( p, hash, hashlen );
00434 break;
00435 
00436 case RSA_MD2:
00437 memcpy( p, ASN1_HASH_MDX, 18 );
00438 memcpy( p + 18, hash, 16 );
00439 p[13] = 2; break;
00440 
00441 case RSA_MD4:
00442 memcpy( p, ASN1_HASH_MDX, 18 );
00443 memcpy( p + 18, hash, 16 );
00444 p[13] = 4; break;
00445 
00446 case RSA_MD5:
00447 memcpy( p, ASN1_HASH_MDX, 18 );
00448 memcpy( p + 18, hash, 16 );
00449 p[13] = 5; break;
00450 
00451 case RSA_SHA1:
00452 memcpy( p, ASN1_HASH_SHA1, 15 );
00453 memcpy( p + 15, hash, 20 );
00454 break;
00455 
00456 default:
00457 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00458 }
00459 
00460 return( ( mode == RSA_PUBLIC )
00461 ? rsa_public( ctx, sig, sig )
00462 : rsa_private( ctx, sig, sig ) );
00463 }
00464 
00465 /*
00466  * Do an RSA operation and check the message digest
00467  */
00468 int rsa_pkcs1_verify( rsa_context *ctx,
00469 int mode,
00470 int hash_id,
00471 int hashlen,
00472 unsigned char *hash,
00473 unsigned char *sig )
00474 {
00475 int ret, len, siglen;
00476 unsigned char *p, c;
00477 unsigned char buf[512];
00478 
00479 siglen = ctx->len;
00480 
00481 if( siglen < 16 || siglen > (int) sizeof( buf ) )
00482 return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
00483 
00484 ret = ( mode == RSA_PUBLIC )
00485 ? rsa_public( ctx, sig, buf )
00486 : rsa_private( ctx, sig, buf );
00487 
00488 if( ret != 0 )
00489 return( ret );
00490 
00491 p = buf;
00492 
00493 switch( ctx->padding )
00494 {
00495 case RSA_PKCS_V15:
00496 
00497 if( *p++ != 0 || *p++ != RSA_SIGN )
00498 return( XYSSL_ERR_RSA_INVALID_PADDING );
00499 
00500 while( *p != 0 )
00501 {
00502 if( p >= buf + siglen - 1 || *p != 0xFF )
00503 return( XYSSL_ERR_RSA_INVALID_PADDING );
00504 p++;
00505 }
00506 p++;
00507 break;
00508 
00509 default:
00510 
00511 return( XYSSL_ERR_RSA_INVALID_PADDING );
00512 }
00513 
00514 len = siglen - (int)( p - buf );
00515 
00516 if( len == 34 )
00517 {
00518 c = p[13];
00519 p[13] = 0;
00520 
00521 if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
00522 return( XYSSL_ERR_RSA_VERIFY_FAILED );
00523 
00524 if( ( c == 2 && hash_id == RSA_MD2 ) ||
00525 ( c == 4 && hash_id == RSA_MD4 ) ||
00526 ( c == 5 && hash_id == RSA_MD5 ) )
00527 {
00528 if( memcmp( p + 18, hash, 16 ) == 0 ) 
00529 return( 0 );
00530 else
00531 return( XYSSL_ERR_RSA_VERIFY_FAILED );
00532 }
00533 }
00534 
00535 if( len == 35 && hash_id == RSA_SHA1 )
00536 {
00537 if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
00538 memcmp( p + 15, hash, 20 ) == 0 )
00539 return( 0 );
00540 else
00541 return( XYSSL_ERR_RSA_VERIFY_FAILED );
00542 }
00543 
00544 if( len == hashlen && hash_id == RSA_RAW )
00545 {
00546 if( memcmp( p, hash, hashlen ) == 0 )
00547 return( 0 );
00548 else
00549 return( XYSSL_ERR_RSA_VERIFY_FAILED );
00550 }
00551 
00552 return( XYSSL_ERR_RSA_INVALID_PADDING );
00553 }
00554 
00555 /*
00556  * Free the components of an RSA key
00557  */
00558 void rsa_free( rsa_context *ctx )
00559 {
00560 mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
00561 &ctx->QP, &ctx->DQ, &ctx->DP,
00562 &ctx->Q, &ctx->P, &ctx->D,
00563 &ctx->E, &ctx->N, NULL );
00564 }
00565 
00566 #if defined(XYSSL_SELF_TEST)
00567 
00568 #include "xyssl/sha1.h"
00569 
00570 /*
00571  * Example RSA-1024 keypair, for test purposes
00572  */
00573 #define KEY_LEN 128
00574 
00575 #define RSA_N "9292758453063D803DD603D5E777D788" \
00576  "8ED1D5BF35786190FA2F23EBC0848AEA" \
00577  "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
00578  "7130B9CED7ACDF54CFC7555AC14EEBAB" \
00579  "93A89813FBF3C4F8066D2D800F7C38A8" \
00580  "1AE31942917403FF4946B0A83D3D3E05" \
00581  "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
00582  "5E94BB77B07507233A0BC7BAC8F90F79"
00583 
00584 #define RSA_E "10001"
00585 
00586 #define RSA_D "24BF6185468786FDD303083D25E64EFC" \
00587  "66CA472BC44D253102F8B4A9D3BFA750" \
00588  "91386C0077937FE33FA3252D28855837" \
00589  "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
00590  "DF79C5CE07EE72C7F123142198164234" \
00591  "CABB724CF78B8173B9F880FC86322407" \
00592  "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
00593  "071513A1E85B5DFA031F21ECAE91A34D"
00594 
00595 #define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
00596  "2C01CAD19EA484A87EA4377637E75500" \
00597  "FCB2005C5C7DD6EC4AC023CDA285D796" \
00598  "C3D9E75E1EFC42488BB4F1D13AC30A57"
00599 
00600 #define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
00601  "E211C2B9E5DB1ED0BF61D0D9899620F4" \
00602  "910E4168387E3C30AA1E00C339A79508" \
00603  "8452DD96A9A5EA5D9DCA68DA636032AF"
00604 
00605 #define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
00606  "3C94D22288ACD763FD8E5600ED4A702D" \
00607  "F84198A5F06C2E72236AE490C93F07F8" \
00608  "3CC559CD27BC2D1CA488811730BB5725"
00609 
00610 #define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
00611  "D8AAEA56749EA28623272E4F7D0592AF" \
00612  "7C1F1313CAC9471B5C523BFE592F517B" \
00613  "407A1BD76C164B93DA2D32A383E58357"
00614 
00615 #define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
00616  "F38D18D2B2F0E2DD275AA977E2BF4411" \
00617  "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
00618  "A74206CEC169D74BF5A8C50D6F48EA08"
00619 
00620 #define PT_LEN 24
00621 #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
00622  "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
00623 
00624 /*
00625  * Checkup routine
00626  */
00627 int rsa_self_test( int verbose )
00628 {
00629 int len;
00630 rsa_context rsa;
00631 unsigned char sha1sum[20];
00632 unsigned char rsa_plaintext[PT_LEN];
00633 unsigned char rsa_decrypted[PT_LEN];
00634 unsigned char rsa_ciphertext[KEY_LEN];
00635 
00636 memset( &rsa, 0, sizeof( rsa_context ) );
00637 
00638 rsa.len = KEY_LEN;
00639 mpi_read_string( &rsa.N , 16, RSA_N );
00640 mpi_read_string( &rsa.E , 16, RSA_E );
00641 mpi_read_string( &rsa.D , 16, RSA_D );
00642 mpi_read_string( &rsa.P , 16, RSA_P );
00643 mpi_read_string( &rsa.Q , 16, RSA_Q );
00644 mpi_read_string( &rsa.DP, 16, RSA_DP );
00645 mpi_read_string( &rsa.DQ, 16, RSA_DQ );
00646 mpi_read_string( &rsa.QP, 16, RSA_QP );
00647 
00648 if( verbose != 0 )
00649 printf( " RSA key validation: " );
00650 
00651 if( rsa_check_pubkey( &rsa ) != 0 ||
00652 rsa_check_privkey( &rsa ) != 0 )
00653 {
00654 if( verbose != 0 )
00655 printf( "failed\n" );
00656 
00657 return( 1 );
00658 }
00659 
00660 if( verbose != 0 )
00661 printf( "passed\n PKCS#1 encryption : " );
00662 
00663 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
00664 
00665 if( rsa_pkcs1_encrypt( &rsa, RSA_PUBLIC, PT_LEN,
00666 rsa_plaintext, rsa_ciphertext ) != 0 )
00667 {
00668 if( verbose != 0 )
00669 printf( "failed\n" );
00670 
00671 return( 1 );
00672 }
00673 
00674 if( verbose != 0 )
00675 printf( "passed\n PKCS#1 decryption : " );
00676 
00677 if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
00678 rsa_ciphertext, rsa_decrypted ) != 0 )
00679 {
00680 if( verbose != 0 )
00681 printf( "failed\n" );
00682 
00683 return( 1 );
00684 }
00685 
00686 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
00687 {
00688 if( verbose != 0 )
00689 printf( "failed\n" );
00690 
00691 return( 1 );
00692 }
00693 
00694 if( verbose != 0 )
00695 printf( "passed\n PKCS#1 data sign : " );
00696 
00697 sha1( rsa_plaintext, PT_LEN, sha1sum );
00698 
00699 if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, RSA_SHA1, 20,
00700 sha1sum, rsa_ciphertext ) != 0 )
00701 {
00702 if( verbose != 0 )
00703 printf( "failed\n" );
00704 
00705 return( 1 );
00706 }
00707 
00708 if( verbose != 0 )
00709 printf( "passed\n PKCS#1 sig. verify: " );
00710 
00711 if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, RSA_SHA1, 20,
00712 sha1sum, rsa_ciphertext ) != 0 )
00713 {
00714 if( verbose != 0 )
00715 printf( "failed\n" );
00716 
00717 return( 1 );
00718 }
00719 
00720 if( verbose != 0 )
00721 printf( "passed\n\n" );
00722 
00723 rsa_free( &rsa );
00724 
00725 return( 0 );
00726 }
00727 
00728 #endif
00729 
00730 #endif

Generated on Tue Oct 28 17:03:23 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /