📄 rsa.cpp
字号:
* Returns 0 if successful, or ERR_RSA_DECRYPT_FAILED
*/
int rsa_pkcs1_decrypt( rsa_context *ctx,
uchar *input, uint ilen,
uchar *output, uint *olen )
{
uchar *p, tmp[512];
if( ilen != ctx->len || ilen < 48 || ilen > 512 )
return( ERR_RSA_DECRYPT_FAILED );
if( rsa_private( ctx, input, ilen, tmp, ilen ) != 0 )
return( ERR_RSA_DECRYPT_FAILED );
p = tmp;
if( *p++ != 0 || *p++ != RSA_CRYPT )
return( ERR_RSA_DECRYPT_FAILED );
while( *p != 0 )
{
if( p >= tmp + ilen - 1 )
return( ERR_RSA_DECRYPT_FAILED );
p++;
}
p++;
if( *olen < ilen - (uint)(p - tmp) )
return( ERR_RSA_DECRYPT_FAILED );
*olen = ilen - (uint)(p - tmp);
memcpy( output, p, *olen );
return( 0 );
}
/*
* Perform a private RSA to sign a message digest
*
* ctx points to an RSA private key
* hash buffer holding the message digest
* alg_id must be set to RSA_MD2/4/5 or RSA_SHA1
* sig buffer that will hold the ciphertext
* siglen must be the same as the modulus size
* (for example, 128 if RSA-1024 is used)
*
* Returns 0 if successful, or ERR_RSA_SIGN_FAILED
*/
int rsa_pkcs1_sign( rsa_context *ctx,
uchar *hash, int alg_id,
uchar *sig, uint siglen )
{
int nb_pad;
uchar *p = sig;
if( siglen != ctx->len || siglen < 48 )
return( ERR_RSA_SIGN_FAILED );
switch( alg_id )
{
case RSA_MD2:
case RSA_MD4:
case RSA_MD5:
nb_pad = siglen - 3 - 34;
break;
case RSA_SHA1:
nb_pad = siglen - 3 - 35;
break;
default:
return( ERR_RSA_SIGN_FAILED );
}
if( nb_pad < 8 )
return( ERR_RSA_SIGN_FAILED );
*p++ = 0;
*p++ = RSA_SIGN;
memset( p, 0xFF, nb_pad );
p += nb_pad;
*p++ = 0;
switch( alg_id )
{
case RSA_MD2:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 2; break;
case RSA_MD4:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 4; break;
case RSA_MD5:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 5; break;
case RSA_SHA1:
memcpy( p, ASN1_HASH_SHA1, 15 );
memcpy( p + 15, hash, 20 );
break;
default:
return( ERR_RSA_SIGN_FAILED );
}
if( rsa_private( ctx, sig, siglen, sig, siglen ) != 0 )
return( ERR_RSA_SIGN_FAILED );
return( 0 );
}
/*
* Perform a public RSA and check the message digest.
*
* ctx points to an RSA public key
* hash buffer holding the message digest
* alg_id must be set to RSA_MD{2,4,5} or RSA_SHA1
* sig buffer holding the ciphertext
* siglen must be the same as the modulus size
*
* Returns 0 if successful, or ERR_RSA_VERIFY_FAILED
*/
int rsa_pkcs1_verify( rsa_context *ctx,
uchar *hash, int alg_id,
uchar *sig, uint siglen )
{
int len;
uchar *p, c, tmp[512];
if( siglen != ctx->len || siglen < 48 || siglen > 512 )
return( ERR_RSA_VERIFY_FAILED );
if( rsa_public( ctx, sig, siglen, tmp, siglen ) != 0 )
return( ERR_RSA_VERIFY_FAILED );
p = tmp;
if( *p++ != 0 || *p++ != RSA_SIGN )
return( ERR_RSA_VERIFY_FAILED );
while( *p != 0 )
{
if( p >= tmp + siglen - 1 || *p != 0xFF )
return( ERR_RSA_VERIFY_FAILED );
p++;
}
p++;
len = siglen - (uint)( p - tmp );
if( len == 34 )
{
c = p[13];
p[13] = 0;
if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
return( ERR_RSA_VERIFY_FAILED );
if( ( c == 2 && alg_id == RSA_MD2 ) ||
( c == 4 && alg_id == RSA_MD4 ) ||
( c == 5 && alg_id == RSA_MD5 ) )
{
if( memcmp( p + 18, hash, 16 ) == 0 )
return( 0 );
}
}
if( len == 35 && alg_id == RSA_SHA1 )
{
if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
memcmp( p + 15, hash, 20 ) == 0 )
return( 0 );
}
return( ERR_RSA_VERIFY_FAILED );
}
/*
* Free the components of an RSA key.
*/
void rsa_free( rsa_context *ctx )
{
debug_print(&ctx->N); //32
debug_print(&ctx->E); //1
debug_print(&ctx->D); //32
debug_print(&ctx->P); //16
debug_print(&ctx->Q); //16
debug_print(&ctx->DP); //16
debug_print(&ctx->DQ); //16
debug_print(&ctx->QP); //16
mpi_free( &ctx->N, &ctx->E, &ctx->D,
&ctx->P, &ctx->Q, &ctx->DP,
&ctx->DQ, &ctx->QP, NULL );
}
#ifdef SELF_TEST
#include "md5.h"
uchar plaintext[] =
"\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
"\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD";
#define PTLEN 24
#define CTLEN 128
/*
* Checkup routine
*/
int rsa_self_test( void )
{
uint len;
rsa_context rsa;
uchar md5sum[16];
uchar decrypted[PTLEN];
uchar ciphertext[CTLEN];
memset( &rsa, 0, sizeof( rsa ) );
rsa.len = 128;
mpi_read( &rsa.N , "9292758453063D803DD603D5E777D788" \
"8ED1D5BF35786190FA2F23EBC0848AEA" \
"DDA92CA6C3D80B32C4D109BE0F36D6AE" \
"7130B9CED7ACDF54CFC7555AC14EEBAB" \
"93A89813FBF3C4F8066D2D800F7C38A8" \
"1AE31942917403FF4946B0A83D3D3E05" \
"EE57C6F5F5606FB5D4BC6CD34EE0801A" \
"5E94BB77B07507233A0BC7BAC8F90F79", 16 );
mpi_read( &rsa.E , "10001", 16 );
mpi_read( &rsa.D , "24BF6185468786FDD303083D25E64EFC" \
"66CA472BC44D253102F8B4A9D3BFA750" \
"91386C0077937FE33FA3252D28855837" \
"AE1B484A8A9A45F7EE8C0C634F99E8CD" \
"DF79C5CE07EE72C7F123142198164234" \
"CABB724CF78B8173B9F880FC86322407" \
"AF1FEDFDDE2BEB674CA15F3E81A1521E" \
"071513A1E85B5DFA031F21ECAE91A34D", 16 );
mpi_read( &rsa.P , "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
"2C01CAD19EA484A87EA4377637E75500" \
"FCB2005C5C7DD6EC4AC023CDA285D796" \
"C3D9E75E1EFC42488BB4F1D13AC30A57", 16 );
mpi_read( &rsa.Q , "C000DF51A7C77AE8D7C7370C1FF55B69" \
"E211C2B9E5DB1ED0BF61D0D9899620F4" \
"910E4168387E3C30AA1E00C339A79508" \
"8452DD96A9A5EA5D9DCA68DA636032AF", 16 );
mpi_read( &rsa.DP, "C1ACF567564274FB07A0BBAD5D26E298" \
"3C94D22288ACD763FD8E5600ED4A702D" \
"F84198A5F06C2E72236AE490C93F07F8" \
"3CC559CD27BC2D1CA488811730BB5725", 16 );
mpi_read( &rsa.DQ, "4959CBF6F8FEF750AEE6977C155579C7" \
"D8AAEA56749EA28623272E4F7D0592AF" \
"7C1F1313CAC9471B5C523BFE592F517B" \
"407A1BD76C164B93DA2D32A383E58357", 16 );
mpi_read( &rsa.QP, "9AE7FBC99546432DF71896FC239EADAE" \
"F38D18D2B2F0E2DD275AA977E2BF4411" \
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
"A74206CEC169D74BF5A8C50D6F48EA08", 16 );
printf( " RSA key validation: " );
if( rsa_check_pubkey( &rsa ) != 0 ||
rsa_check_privkey( &rsa ) != 0 )
{
printf( "failed\n" );
return( 1 );
}
printf( "passed\n PKCS#1 encryption : " );
if( rsa_pkcs1_encrypt( &rsa, plaintext, PTLEN,
ciphertext, CTLEN ) != 0 )
{
printf( "failed\n" );
return( 1 );
}
printf( "passed\n PKCS#1 decryption : " );
len = sizeof( decrypted );
if( rsa_pkcs1_decrypt( &rsa, ciphertext, CTLEN,
decrypted, &len ) != 0 ||
memcmp( decrypted, plaintext, len ) != 0 )
{
printf( "failed\n" );
return( 1 );
}
printf( "passed\n PKCS#1 data sign : " );
md5_csum( plaintext, PTLEN, md5sum );
if( rsa_pkcs1_sign( &rsa, md5sum, RSA_MD5,
ciphertext, CTLEN ) != 0 )
{
printf( "failed\n" );
return( 1 );
}
printf( "passed\n PKCS#1 sig. verify: " );
if( rsa_pkcs1_verify( &rsa, md5sum, RSA_MD5,
ciphertext, CTLEN ) != 0 )
{
printf( "failed\n" );
return( 1 );
}
printf( "passed\n\n" );
// add by lyt
rsa_free(&rsa);
//
return( 0 );
}
#else
int rsa_self_test( void )
{
printf( "RSA self-test not available\n\n" );
return( 1 );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -