static int rsa_sign_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { *sig_len = ((rsa_context *) ctx)->len; return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, RSA_PRIVATE, md_alg, (unsigned int) hash_len, hash, sig ) ); }
int rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len, struct key_data *kd) { mpi P1, Q1, H; int r; unsigned char temp[RSA_SIGNATURE_LENGTH]; mpi_init (&P1, &Q1, &H, NULL); rsa_init (&rsa_ctx, RSA_PKCS_V15, 0); rsa_ctx.len = KEY_CONTENT_LEN; mpi_lset (&rsa_ctx.E, 0x10001); mpi_read_binary (&rsa_ctx.P, &kd->data[0], rsa_ctx.len / 2); mpi_read_binary (&rsa_ctx.Q, &kd->data[KEY_CONTENT_LEN/2], rsa_ctx.len / 2); #if 0 /* Using CRT, we don't use N */ mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q); #endif mpi_sub_int (&P1, &rsa_ctx.P, 1); mpi_sub_int (&Q1, &rsa_ctx.Q, 1); mpi_mul_mpi (&H, &P1, &Q1); mpi_inv_mod (&rsa_ctx.D , &rsa_ctx.E, &H); mpi_mod_mpi (&rsa_ctx.DP, &rsa_ctx.D, &P1); mpi_mod_mpi (&rsa_ctx.DQ, &rsa_ctx.D, &Q1); mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P); mpi_free (&P1, &Q1, &H, NULL); DEBUG_INFO ("RSA sign..."); r = rsa_pkcs1_sign (&rsa_ctx, RSA_PRIVATE, SIG_RSA_RAW, msg_len, raw_message, temp); memcpy (output, temp, RSA_SIGNATURE_LENGTH); rsa_free (&rsa_ctx); if (r < 0) { DEBUG_INFO ("fail:"); DEBUG_SHORT (r); return r; } else { res_APDU_size = RSA_SIGNATURE_LENGTH; DEBUG_INFO ("done.\r\n"); GPG_SUCCESS (); return 0; } }
int ctr_rsa_sign_hash(const u8 hash[0x20], u8 signature[0x100], rsakey2048* key) { ctr_rsa_context ctx; u32 result; ctr_rsa_init(&ctx, key); result = rsa_pkcs1_verify(&ctx.rsa, RSA_PUBLIC, SIG_RSA_SHA256, 0x20, hash, (u8*)signature); result = rsa_pkcs1_sign(&ctx.rsa, RSA_PRIVATE, SIG_RSA_SHA256, 0x20, hash, signature); ctr_rsa_free(&ctx); if (result == 0) return 1; else return 0; }
int main( int argc, char *argv[] ) { FILE *f; int ret = 1; rsa_context rsa; entropy_context entropy; ctr_drbg_context ctr_drbg; unsigned char hash[20]; unsigned char buf[POLARSSL_MPI_MAX_SIZE]; char filename[512]; const char *pers = "rsa_sign_pss"; entropy_init( &entropy ); rsa_init( &rsa, RSA_PKCS_V21, POLARSSL_MD_SHA1 ); if( argc != 3 ) { printf( "usage: rsa_sign_pss <key_file> <filename>\n" ); #if defined(_WIN32) printf( "\n" ); #endif goto exit; } printf( "\n . Seeding the random number generator..." ); fflush( stdout ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { printf( " failed\n ! ctr_drbg_init returned %d\n", ret ); goto exit; } printf( "\n . Reading private key from '%s'", argv[1] ); fflush( stdout ); if( ( ret = x509parse_keyfile( &rsa, argv[1], "" ) ) != 0 ) { ret = 1; printf( " failed\n ! Could not open '%s'\n", argv[1] ); goto exit; } /* * Compute the SHA-1 hash of the input file, * then calculate the RSA signature of the hash. */ printf( "\n . Generating the RSA/SHA-1 signature" ); fflush( stdout ); if( ( ret = sha1_file( argv[2], hash ) ) != 0 ) { printf( " failed\n ! Could not open or read %s\n\n", argv[2] ); goto exit; } if( ( ret = rsa_pkcs1_sign( &rsa, ctr_drbg_random, &ctr_drbg, RSA_PRIVATE, SIG_RSA_SHA1, 20, hash, buf ) ) != 0 ) { printf( " failed\n ! rsa_pkcs1_sign returned %d\n\n", ret ); goto exit; } /* * Write the signature into <filename>-sig.txt */ snprintf( filename, 512, "%s.sig", argv[2] ); if( ( f = fopen( filename, "wb+" ) ) == NULL ) { ret = 1; printf( " failed\n ! Could not create %s\n\n", filename ); goto exit; } if( fwrite( buf, 1, rsa.len, f ) != (size_t) rsa.len ) { printf( "failed\n ! fwrite failed\n\n" ); goto exit; } fclose( f ); printf( "\n . Done (created \"%s\")\n\n", filename ); exit: #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
/* * Checkup routine */ int rsa_self_test( int verbose ) { int len; rsa_context rsa; unsigned char sha1sum[20]; unsigned char rsa_plaintext[PT_LEN]; unsigned char rsa_decrypted[PT_LEN]; unsigned char rsa_ciphertext[KEY_LEN]; memset( &rsa, 0, sizeof( rsa_context ) ); rsa.len = KEY_LEN; mpi_read_string( &rsa.N , 16, RSA_N ); mpi_read_string( &rsa.E , 16, RSA_E ); mpi_read_string( &rsa.D , 16, RSA_D ); mpi_read_string( &rsa.P , 16, RSA_P ); mpi_read_string( &rsa.Q , 16, RSA_Q ); mpi_read_string( &rsa.DP, 16, RSA_DP ); mpi_read_string( &rsa.DQ, 16, RSA_DQ ); mpi_read_string( &rsa.QP, 16, RSA_QP ); if( verbose != 0 ) printf( " RSA key validation: " ); if( rsa_check_pubkey( &rsa ) != 0 || rsa_check_privkey( &rsa ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n PKCS#1 encryption : " ); memcpy( rsa_plaintext, RSA_PT, PT_LEN ); if( rsa_pkcs1_encrypt( &rsa, RSA_PUBLIC, PT_LEN, rsa_plaintext, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n PKCS#1 decryption : " ); if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len, rsa_ciphertext, rsa_decrypted, sizeof(rsa_decrypted) ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n PKCS#1 data sign : " ); sha1( rsa_plaintext, PT_LEN, sha1sum ); if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1, 20, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n PKCS#1 sig. verify: " ); if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n\n" ); rsa_free( &rsa ); return( 0 ); }
int main( int argc, char *argv[] ) { FILE *f; int ret, i; rsa_context rsa; unsigned char hash[20]; unsigned char buf[512]; ret = 1; if( argc != 2 ) { printf( "usage: rsa_sign <filename>\n" ); #ifdef WIN32 printf( "\n" ); #endif goto exit; } printf( "\n . Reading private key from rsa_priv.txt" ); fflush( stdout ); if( ( f = fopen( "rsa_priv.txt", "rb" ) ) == NULL ) { ret = 1; printf( " failed\n ! Could not open rsa_priv.txt\n" \ " ! Please run rsa_genkey first\n\n" ); goto exit; } rsa_init( &rsa, RSA_PKCS_V15, 0, NULL, NULL ); if( ( ret = mpi_read_file( &rsa.N , 16, f ) ) != 0 || ( ret = mpi_read_file( &rsa.E , 16, f ) ) != 0 || ( ret = mpi_read_file( &rsa.D , 16, f ) ) != 0 || ( ret = mpi_read_file( &rsa.P , 16, f ) ) != 0 || ( ret = mpi_read_file( &rsa.Q , 16, f ) ) != 0 || ( ret = mpi_read_file( &rsa.DP, 16, f ) ) != 0 || ( ret = mpi_read_file( &rsa.DQ, 16, f ) ) != 0 || ( ret = mpi_read_file( &rsa.QP, 16, f ) ) != 0 ) { printf( " failed\n ! mpi_read_file returned %d\n\n", ret ); goto exit; } rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3; fclose( f ); /* * Compute the SHA-1 hash of the input file, * then calculate the RSA signature of the hash. */ printf( "\n . Generating the RSA/SHA-1 signature" ); fflush( stdout ); if( ( ret = sha1_file( argv[1], hash ) ) != 0 ) { printf( " failed\n ! Could not open or read %s\n\n", argv[1] ); goto exit; } if( ( ret = rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1, 20, hash, buf ) ) != 0 ) { printf( " failed\n ! rsa_pkcs1_sign returned %d\n\n", ret ); goto exit; } /* * Write the signature into <filename>-sig.txt */ memcpy( argv[1] + strlen( argv[1] ), ".sig", 5 ); if( ( f = fopen( argv[1], "wb+" ) ) == NULL ) { ret = 1; printf( " failed\n ! Could not create %s\n\n", argv[1] ); goto exit; } for( i = 0; i < rsa.len; i++ ) fprintf( f, "%02X%s", buf[i], ( i + 1 ) % 16 == 0 ? "\r\n" : " " ); fclose( f ); printf( "\n . Done (created \"%s\")\n\n", argv[1] ); exit: #ifdef WIN32 printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
int main(int argc, char** argv) { int ret; FILE* fp; // Assumes no private key password ret = x509parse_keyfile(&privrsa, (char*)PRIVATEKEYFILE, NULL); if (ret != 0) { printf(" ! x509parse_keyfile returned %d\n\n", ret); return -1; } if (rsa_check_pubkey(&privrsa) != 0 || rsa_check_privkey(&privrsa) != 0) { printf("public/private key validation failed.\n"); return -2; } printf("Private/Public key loaded. Encrypting message.\n"); if (rsa_pkcs1_encrypt(&privrsa, RSA_PUBLIC, strlen(MESSAGE), (unsigned char*)MESSAGE, rsa_ciphertext) != 0) { printf("Encryption of message failed\n"); return -3; } printf("Encryption complete. Output in message.crypt\n"); fp = fopen("message.crypt", "wb"); if (!fp) { printf("Error opening message.crypt\n"); return -4; } fwrite(rsa_ciphertext, 128, 1, fp); fclose(fp); memset(&rsa_ciphertext, 0, sizeof(rsa_ciphertext)); // Now sign the message. sha1((unsigned char*)MESSAGE, strlen(MESSAGE), hash); // for (int i = 0; i < 20; i++) // printf("%02X%s", hash[i], (i + 1) % 16 == 0 ? "\r\n" : " "); // if (rsa_pkcs1_sign(&privrsa, RSA_PRIVATE, RSA_SHA1, 20, hash, rsa_ciphertext) != 0) { if (rsa_pkcs1_sign(&privrsa, RSA_PRIVATE, RSA_SHA1, 20, hash, rsa_ciphertext) != 0) { printf("Signature failed.\n"); return -5; } printf("Signing complete. Output in message.sig\n"); fp = fopen("message.sig", "wb"); if (!fp) { printf("Error opening message.sig\n"); return -4; } fwrite(rsa_ciphertext, 128, 1, fp); fclose(fp); return 0; }
/* * Checkup routine */ int main ( void ) { int len; rsa_context rsa; unsigned char md5sum[16]; unsigned char rsa_plaintext[PTLEN]; unsigned char rsa_decrypted[PTLEN]; unsigned char rsa_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 : " ); memcpy( rsa_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", PTLEN ); len = CTLEN; if( rsa_pkcs1_encrypt( &rsa, rsa_plaintext, PTLEN, rsa_ciphertext, &len ) != 0 ) { printf( "failed\n" ); return( 1 ); } printf( "passed\n PKCS#1 decryption : " ); len = sizeof( rsa_decrypted ); if( rsa_pkcs1_decrypt( &rsa, rsa_ciphertext, CTLEN, rsa_decrypted, &len ) != 0 || memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) { printf( "failed\n" ); return( 1 ); } printf( "passed\n" ); #if 0 md5_csum( rsa_plaintext, PTLEN, md5sum ); if( rsa_pkcs1_sign( &rsa, RSA_MD5, md5sum, 16, rsa_ciphertext, CTLEN ) != 0 ) { printf( "failed\n" ); return( 1 ); } printf( "passed\n PKCS#1 sig. verify: " ); if( rsa_pkcs1_verify( &rsa, RSA_MD5, md5sum, 16, rsa_ciphertext, CTLEN ) != 0 ) { printf( "failed\n" ); return( 1 ); } printf( "passed\n\n" ); #endif rsa_free( &rsa ); return( 0 ); }
/* * Checkup routine */ int rsa_self_test( int verbose ) { int ret = 0; #if defined(POLARSSL_PKCS1_V15) size_t len; rsa_context rsa; unsigned char rsa_plaintext[PT_LEN]; unsigned char rsa_decrypted[PT_LEN]; unsigned char rsa_ciphertext[KEY_LEN]; #if defined(POLARSSL_SHA1_C) unsigned char sha1sum[20]; #endif rsa_init( &rsa, RSA_PKCS_V15, 0 ); rsa.len = KEY_LEN; MPI_CHK( mpi_read_string( &rsa.N , 16, RSA_N ) ); MPI_CHK( mpi_read_string( &rsa.E , 16, RSA_E ) ); MPI_CHK( mpi_read_string( &rsa.D , 16, RSA_D ) ); MPI_CHK( mpi_read_string( &rsa.P , 16, RSA_P ) ); MPI_CHK( mpi_read_string( &rsa.Q , 16, RSA_Q ) ); MPI_CHK( mpi_read_string( &rsa.DP, 16, RSA_DP ) ); MPI_CHK( mpi_read_string( &rsa.DQ, 16, RSA_DQ ) ); MPI_CHK( mpi_read_string( &rsa.QP, 16, RSA_QP ) ); if( verbose != 0 ) polarssl_printf( " RSA key validation: " ); if( rsa_check_pubkey( &rsa ) != 0 || rsa_check_privkey( &rsa ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) polarssl_printf( "passed\n PKCS#1 encryption : " ); memcpy( rsa_plaintext, RSA_PT, PT_LEN ); if( rsa_pkcs1_encrypt( &rsa, myrand, NULL, RSA_PUBLIC, PT_LEN, rsa_plaintext, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) polarssl_printf( "passed\n PKCS#1 decryption : " ); if( rsa_pkcs1_decrypt( &rsa, myrand, NULL, RSA_PRIVATE, &len, rsa_ciphertext, rsa_decrypted, sizeof(rsa_decrypted) ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } #if defined(POLARSSL_SHA1_C) if( verbose != 0 ) polarssl_printf( "passed\n PKCS#1 data sign : " ); sha1( rsa_plaintext, PT_LEN, sha1sum ); if( rsa_pkcs1_sign( &rsa, myrand, NULL, RSA_PRIVATE, POLARSSL_MD_SHA1, 0, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) polarssl_printf( "passed\n PKCS#1 sig. verify: " ); if( rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA1, 0, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) polarssl_printf( "passed\n\n" ); #endif /* POLARSSL_SHA1_C */ cleanup: rsa_free( &rsa ); #else /* POLARSSL_PKCS1_V15 */ ((void) verbose); #endif /* POLARSSL_PKCS1_V15 */ return( ret ); }
/* * Checkup routine */ int rsa_self_test( void ) { int len; rsa_context rsa; uchar md5sum[16]; uchar decrypted[PTLEN]; uchar ciphertext[CTLEN]; memset( &rsa, 0, sizeof( rsa ) ); rsa.len = 128; #if 0 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 ); #else mpi_read( &rsa.N , "EEF43DF231F4FEFDA3FF0576F864912B" \ "F5D51D627C5911F4794F54C8BE178C66" \ "FD9C447BE512735818E93CF88AB1696C" \ "1C634A898DBFCE384F74CD347B715419" \ "EAE05016842B752F127CC224535C4708" \ "8DE7566D50F0CFC013B2592BAB1E042A" \ "76239E5262D931B84BDAB640028AFE7C" \ "39E2B75A353EABF827854EE249C6EA45", 16 ); mpi_read( &rsa.E , "010001", 16 ); mpi_read( &rsa.D , "B6F6044861BFF94E34379BF3901550A2" \ "9C44658F772EABF4C8BDD9692B43D499" \ "372E63B189A02AF91579E0D95D38A243" \ "C928AD75CD3743AB120B98E3CA70E7B6" \ "C5B3C1EA2065EF5A6347F80B247044D4" \ "775C4379C2286F8724E0DFE859F808E8" \ "BFBE3D257EF84E3A455C5BC452F5600E" \ "5CDD62818D7E937C7D4C9819C1FAF331", 16 ); mpi_read( &rsa.P , "FBD24AF8F6132E9E1D07B73CFD6D0ECE" \ "6E49DD602EF0F4D6FE6DF66493F016EA" \ "C19FF290749194145C3229D0CC57B31F" \ "199AE2819572271CFE40279063B5BEAB", 16 ); mpi_read( &rsa.Q , "F2EB4A3E41438F2690EC2DED0198E4BD" \ "7ABA01D374A27C92BDAEA3803FF8584C" \ "2B923C95868B4C53DCEEA3A750D7B702" \ "748522C8BF781CCED4E76B52A9DD3ACF", 16 ); mpi_read( &rsa.DP, "3947752C39F4D506BBFDB44D582BC551" \ "693EBDEF11DE5722CC0EC11BD196ABEF" \ "CC0910C890EB482E756627A2C9C82D03" \ "26F4D70EB8AA9580FFC821F7B2E6752F", 16 ); mpi_read( &rsa.DQ, "5A71D28DC55CF322A7D8D7ECA3A89A9A" \ "15E4C5A3468CED16F1BAE133721DF43A" \ "400ACDB5DA8768DEDCA69996455A5BD0" \ "7533D0D4AFBD77F4667ED78DCAA30D2F", 16 ); mpi_read( &rsa.QP, "81267EDB140CE8F07CA92F508FEA134B" \ "23C871D428C6EF870F08FFF2AD46D210" \ "8FCD67E28FF95E8E332B5EEE16EB8784" \ "AB3D1E59B078CB93EF5C6E0F12419439", 16 ); #endif 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, RSA_MD5, md5sum, 16, ciphertext, CTLEN ) != 0 ) { printf( "failed\n" ); return( 1 ); } printf( "passed\n PKCS#1 sig. verify: " ); if( rsa_pkcs1_verify( &rsa, RSA_MD5, md5sum, 16, ciphertext, CTLEN ) != 0 ) { printf( "failed\n" ); return( 1 ); } printf( "passed\n\n" ); rsa_free( &rsa ); return( 0 ); }
int message_rsa_encrypt(VCRYPT_CTX *ctx, rsa_context *public_rsa, const char *username, const char *message, VCRYPT_PACKET **packet) { int ret; /* * format: * 1 byte protocol version * 2 bytes encryption key size in bytes * 2 bytes signature key size in bytes * ciphertext * signature * */ if (!public_rsa->len) return -ERR_NO_PUBKEY; // we dont encrypt null terminating char, as this creates a vector of attack int plain_len = strlen(message); if (plain_len == 0) return -ERR_ENCRYPTION_ERROR; size_t plain_chunk_len = public_rsa->len - 11; // get packet size int plain_chunks = ceil(plain_len / (float) plain_chunk_len); int ciphertext_len = plain_chunks * public_rsa->len; // space for signature ciphertext_len += ctx->ssl_req.rsa.len; *packet = packet_new(DEST_CLIENT, username, REQ_MESSAGE_SEND, ciphertext_len + 5); if (!*packet) return -ERR_MALLOC; // TODO: add ciphertext stealing (form signature) to save bandwidth (i.e. use signature as padding) int chunk; int chunk_len; uint8_t *in = (uint8_t*) message, *out = (uint8_t*) (*packet)->payload; *out++ = VCRYPT_PROTOCOL_VERSION; *((uint16_t*) out) = public_rsa->len; out += 2; *((uint16_t*) out) = ctx->ssl_req.rsa.len; out += 2; for (chunk = 0; chunk < plain_chunks; chunk++, in += plain_chunk_len, out += public_rsa->len) { // last usually has different length chunk_len = chunk == plain_chunks - 1 ? plain_len % plain_chunk_len : plain_chunk_len; if ((ret = rsa_pkcs1_encrypt(public_rsa, ctr_drbg_random, &ctx->ssl_req.ctr_drbg, RSA_PUBLIC, chunk_len, in, out) != 0)) { free(packet); return -ERR_ENCRYPTION_ERROR; } } unsigned char hash[64]; sha4_context sha_ctx; sha4_starts(&sha_ctx, 1); sha4_update(&sha_ctx, (uint8_t*) message, plain_len); sha4_finish(&sha_ctx, hash); if ((ret = rsa_pkcs1_sign(&ctx->ssl_req.rsa, NULL, NULL, RSA_PRIVATE, ctx->ssl_req.rsa.hash_id, sizeof hash, hash, out) != 0)) { free(packet); return -ERR_SIGN_ERROR; } return 0; }
int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa, x509_req_name *req_name, int hash_id ) { int ret; char sig_oid[10]; unsigned char *c, *c2; unsigned char hash[64]; unsigned char sig[POLARSSL_MPI_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t sub_len = 0, pub_len = 0, sig_len = 0; size_t len = 0; x509_req_name *cur = req_name; c = tmp_buf + 2048 - 1; ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, 0 ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ); ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &rsa->E ) ); ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &rsa->N ) ); ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) ); ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); if( c - tmp_buf < 1 ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); *--c = 0; pub_len += 1; ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) ); ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_BIT_STRING ) ); ASN1_CHK_ADD( pub_len, asn1_write_algorithm_identifier( &c, tmp_buf, OID_PKCS1_RSA ) ); len += pub_len; ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, pub_len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); while( cur != NULL ) { ASN1_CHK_ADD( sub_len, x509_write_name( &c, tmp_buf, cur->oid, cur->name ) ); cur = cur->next; } len += sub_len; ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); x509_hash( c, len, hash_id, hash ); rsa_pkcs1_sign( rsa, NULL, NULL, RSA_PRIVATE, hash_id, 0, hash, sig ); // Generate correct OID // memcpy( sig_oid, OID_PKCS1, 8 ); sig_oid[8] = hash_id; sig_oid[9] = '\0'; c2 = buf + size - 1; ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, rsa->len ) ); c2 -= len; memcpy( c2, c, len ); len += sig_len; ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); return( len ); }