/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/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 Fri Jul 11 17:59:46 2008 for Mobile-C by  doxygen 1.5.4