int rsa_verify (const uint8_t *pubkey, const uint8_t *hash, const uint8_t *sig) { int r; 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.N, pubkey, KEY_CONTENT_LEN); DEBUG_INFO ("RSA verify..."); r = rsa_pkcs1_verify (&rsa_ctx, RSA_PUBLIC, SIG_RSA_SHA256, 32, hash, sig); rsa_free (&rsa_ctx); if (r < 0) { DEBUG_INFO ("fail:"); DEBUG_SHORT (r); return r; } else { DEBUG_INFO ("verified.\r\n"); return 0; } }
static int rsa_verify_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { if( sig_len != ((rsa_context *) ctx)->len ) return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL, RSA_PUBLIC, md_alg, (unsigned int) hash_len, hash, sig ) ); }
int verify_signature(const unsigned char *signature, const unsigned char *pubkey, const unsigned char *expected_hmac) { rsa_context rsa; init_rsa_context_with_public_key(&rsa, pubkey); int ret = rsa_pkcs1_verify(&rsa, RSA_PUBLIC, RSA_RAW, 20, expected_hmac, signature); rsa_free(&rsa); return ret; }
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 verify_signature(const unsigned char *signature, const unsigned char *pubkey, const unsigned char *expected_hmac) { rsa_context rsa; init_rsa_context_with_public_key(&rsa, pubkey); #ifdef USE_MBEDTLS int ret = mbedtls_rsa_pkcs1_verify(&rsa, mbedtls_default_rng, nullptr, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_NONE, 20, expected_hmac, signature); #else int ret = rsa_pkcs1_verify(&rsa, (rsa_mode_t)RSA_PUBLIC, (rsa_hash_id_t)RSA_RAW, 20, expected_hmac, signature); #endif rsa_free(&rsa); return ret; }
static int rsa_verify_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { int ret; if( sig_len < ((rsa_context *) ctx)->len ) return( POLARSSL_ERR_RSA_VERIFY_FAILED ); if( ( ret = rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL, RSA_PUBLIC, md_alg, (unsigned int) hash_len, hash, sig ) ) != 0 ) return( ret ); if( sig_len > ((rsa_context *) ctx)->len ) return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); return( 0 ); }
static int do_rsa_verify_spki(struct verifier *v, UINT32 length, const UINT8 *msg, struct sexp *e) { CAST(rsa_verifier, self, v); mpz_t s; int res; mpz_init(s); res = (decode_rsa_sig_val(e, s, self->size) && rsa_pkcs1_verify(self, length, msg, s)); mpz_clear(s); return res; }
int RsaSignVerify(void *data, u64 len, u8 *sign, u8 *mod, u8 *priv_exp, u32 sig_type, u8 rsa_mode) { int rsa_result = 0; rsa_context ctx; u8 hash[HASH_MAX_LEN]; if(!RsaKeyInit(&ctx, mod, priv_exp, (u8*)RSA_PUB_EXP, GetRsaType(sig_type))) return -1; if(!CalcHashForSign(data, len, hash, sig_type)) return -1; if(rsa_mode == CTR_RSA_VERIFY) rsa_result = rsa_pkcs1_verify(&ctx, RSA_PUBLIC, GetRsaHashType(sig_type), 0, hash, sign); else // CTR_RSA_SIGN rsa_result = rsa_rsassa_pkcs1_v15_sign(&ctx, RSA_PRIVATE, GetRsaHashType(sig_type), 0, hash, sign); rsa_free(&ctx); return rsa_result; }
int ctr_rsa_verify_hash(const u8 signature[0x100], const u8 hash[0x20], rsakey2048* key) { ctr_rsa_context ctx; u32 result; u8 output[0x100]; if (key->keytype == RSAKEY_INVALID) return Fail; ctr_rsa_init(&ctx, key); // memset(output, 0, 0x100); // result = ctr_rsa_public(signature, output, key); // printf("Result = %d\n", result); // memdump(stdout, "output: ", output, 0x100); result = rsa_pkcs1_verify(&ctx.rsa, RSA_PUBLIC, SIG_RSA_SHA256, 0x20, hash, (u8*)signature); ctr_rsa_free(&ctx); if (result == 0) return Good; else return Fail; }
static int _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo, const gnutls_datum_t * vdata, const gnutls_datum_t * signature, const gnutls_pk_params_st * pk_params) { int ret; unsigned int hash_len; bigint_t tmp[2] = { NULL, NULL }; switch (algo) { case GNUTLS_PK_EC: /* ECDSA */ { ecc_key pub; struct dsa_signature sig; int stat; int curve_id = pk_params->flags; if (is_supported_curve(curve_id) == 0) return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]); if (ret < 0) { gnutls_assert (); goto cleanup; } _ecc_params_to_pubkey(pk_params, &pub); memcpy (&sig.r, tmp[0], sizeof (sig.r)); memcpy (&sig.s, tmp[1], sizeof (sig.s)); _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) hash_len = vdata->size; ret = ecc_verify_hash(&sig, vdata->data, hash_len, &stat, &pub, curve_id); if (ret != 0 || stat != 1) { gnutls_assert(); ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; } else ret = 0; _gnutls_mpi_release (&tmp[0]); _gnutls_mpi_release (&tmp[1]); _ecc_params_clear( &pub); break; } case GNUTLS_PK_DSA: { struct dsa_public_key pub; struct dsa_signature sig; ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]); if (ret < 0) { gnutls_assert (); goto cleanup; } memset(&pub, 0, sizeof(pub)); _dsa_params_to_pubkey (pk_params, &pub); memcpy (&sig.r, tmp[0], sizeof (sig.r)); memcpy (&sig.s, tmp[1], sizeof (sig.s)); _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) hash_len = vdata->size; ret = _dsa_verify (&pub, hash_len, vdata->data, &sig); if (ret == 0) { gnutls_assert(); ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; } else ret = 0; _gnutls_mpi_release (&tmp[0]); _gnutls_mpi_release (&tmp[1]); break; } case GNUTLS_PK_RSA: { struct rsa_public_key pub; _rsa_params_to_pubkey (pk_params, &pub); ret = _gnutls_mpi_scan_nz (&tmp[0], signature->data, signature->size); if (ret < 0) { gnutls_assert (); goto cleanup; } ret = rsa_pkcs1_verify (&pub, vdata->size, vdata->data, TOMPZ(tmp[0])); if (ret == 0) ret = gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED); else ret = 0; _gnutls_mpi_release (&tmp[0]); break; } default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } cleanup: return ret; }
int main( int argc, char *argv[] ) { FILE *f; int ret; size_t i; rsa_context rsa; unsigned char hash[20]; unsigned char buf[512]; char filename[512]; ret = 1; if( argc != 3 ) { printf( "usage: rsa_verify_pss <key_file> <filename>\n" ); #ifdef WIN32 printf( "\n" ); #endif goto exit; } printf( "\n . Reading public key from '%s'", argv[1] ); fflush( stdout ); rsa_init( &rsa, RSA_PKCS_V21, POLARSSL_MD_SHA1 ); if( ( ret = x509parse_public_keyfile( &rsa, argv[1] ) ) != 0 ) { printf( " failed\n ! x509parse_public_key returned %d\n\n", ret ); goto exit; } /* * Extract the RSA signature from the text file */ ret = 1; snprintf( filename, 512, "%s.sig", argv[2] ); if( ( f = fopen( filename, "rb" ) ) == NULL ) { printf( "\n ! Could not open %s\n\n", filename ); goto exit; } i = fread( buf, 1, rsa.len, f ); fclose( f ); if( i != rsa.len ) { printf( "\n ! Invalid RSA signature format\n\n" ); goto exit; } /* * Compute the SHA-1 hash of the input file and compare * it with the hash decrypted from the RSA signature. */ printf( "\n . Verifying 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_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20, hash, buf ) ) != 0 ) { printf( " failed\n ! rsa_pkcs1_verify returned %d\n\n", ret ); goto exit; } printf( "\n . OK (the decrypted SHA-1 hash matches)\n\n" ); ret = 0; exit: #ifdef WIN32 printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif 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 main( int argc, char *argv[] ) { FILE *f; int ret; size_t n, buflen; int server_fd = -1; unsigned char *p, *end; unsigned char buf[2048]; unsigned char hash[20]; const char *pers = "dh_client"; entropy_context entropy; ctr_drbg_context ctr_drbg; rsa_context rsa; dhm_context dhm; aes_context aes; ((void) argc); ((void) argv); memset( &rsa, 0, sizeof( rsa ) ); memset( &dhm, 0, sizeof( dhm ) ); /* * 1. Setup the RNG */ printf( "\n . Seeding the random number generator" ); fflush( stdout ); entropy_init( &entropy ); 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; } /* * 2. Read the server's public RSA key */ printf( "\n . Reading public key from rsa_pub.txt" ); fflush( stdout ); if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL ) { ret = 1; printf( " failed\n ! Could not open rsa_pub.txt\n" \ " ! Please run rsa_genkey first\n\n" ); goto exit; } rsa_init( &rsa, RSA_PKCS_V15, 0 ); if( ( ret = mpi_read_file( &rsa.N, 16, f ) ) != 0 || ( ret = mpi_read_file( &rsa.E, 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 ); /* * 3. Initiate the connection */ printf( "\n . Connecting to tcp/%s/%d", SERVER_NAME, SERVER_PORT ); fflush( stdout ); if( ( ret = net_connect( &server_fd, SERVER_NAME, SERVER_PORT ) ) != 0 ) { printf( " failed\n ! net_connect returned %d\n\n", ret ); goto exit; } /* * 4a. First get the buffer length */ printf( "\n . Receiving the server's DH parameters" ); fflush( stdout ); memset( buf, 0, sizeof( buf ) ); if( ( ret = net_recv( &server_fd, buf, 2 ) ) != 2 ) { printf( " failed\n ! net_recv returned %d\n\n", ret ); goto exit; } n = buflen = ( buf[0] << 8 ) | buf[1]; if( buflen < 1 || buflen > sizeof( buf ) ) { printf( " failed\n ! Got an invalid buffer length\n\n" ); goto exit; } /* * 4b. Get the DHM parameters: P, G and Ys = G^Xs mod P */ memset( buf, 0, sizeof( buf ) ); if( ( ret = net_recv( &server_fd, buf, n ) ) != (int) n ) { printf( " failed\n ! net_recv returned %d\n\n", ret ); goto exit; } p = buf, end = buf + buflen; if( ( ret = dhm_read_params( &dhm, &p, end ) ) != 0 ) { printf( " failed\n ! dhm_read_params returned %d\n\n", ret ); goto exit; } if( dhm.len < 64 || dhm.len > 512 ) { ret = 1; printf( " failed\n ! Invalid DHM modulus size\n\n" ); goto exit; } /* * 5. Check that the server's RSA signature matches * the SHA-1 hash of (P,G,Ys) */ printf( "\n . Verifying the server's RSA signature" ); fflush( stdout ); p += 2; if( ( n = (size_t) ( end - p ) ) != rsa.len ) { ret = 1; printf( " failed\n ! Invalid RSA signature size\n\n" ); goto exit; } sha1( buf, (int)( p - 2 - buf ), hash ); if( ( ret = rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 0, hash, p ) ) != 0 ) { printf( " failed\n ! rsa_pkcs1_verify returned %d\n\n", ret ); goto exit; } /* * 6. Send our public value: Yc = G ^ Xc mod P */ printf( "\n . Sending own public value to server" ); fflush( stdout ); n = dhm.len; if( ( ret = dhm_make_public( &dhm, dhm.len, buf, n, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { printf( " failed\n ! dhm_make_public returned %d\n\n", ret ); goto exit; } if( ( ret = net_send( &server_fd, buf, n ) ) != (int) n ) { printf( " failed\n ! net_send returned %d\n\n", ret ); goto exit; } /* * 7. Derive the shared secret: K = Ys ^ Xc mod P */ printf( "\n . Shared secret: " ); fflush( stdout ); n = dhm.len; if( ( ret = dhm_calc_secret( &dhm, buf, &n ) ) != 0 ) { printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret ); goto exit; } for( n = 0; n < 16; n++ ) printf( "%02x", buf[n] ); /* * 8. Setup the AES-256 decryption key * * This is an overly simplified example; best practice is * to hash the shared secret with a random value to derive * the keying material for the encryption/decryption keys, * IVs and MACs. */ printf( "...\n . Receiving and decrypting the ciphertext" ); fflush( stdout ); aes_setkey_dec( &aes, buf, 256 ); memset( buf, 0, sizeof( buf ) ); if( ( ret = net_recv( &server_fd, buf, 16 ) ) != 16 ) { printf( " failed\n ! net_recv returned %d\n\n", ret ); goto exit; } aes_crypt_ecb( &aes, AES_DECRYPT, buf, buf ); buf[16] = '\0'; printf( "\n . Plaintext is \"%s\"\n\n", (char *) buf ); exit: net_close( server_fd ); rsa_free( &rsa ); dhm_free( &dhm ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
static int do_rsa_verify(struct verifier *v, int algorithm, UINT32 length, const UINT8 *msg, UINT32 signature_length, const UINT8 *signature_data) { CAST(rsa_verifier, self, v); mpz_t s; int res = 0; trace("do_rsa_verify: Verifying %a signature\n", algorithm); mpz_init(s); switch(algorithm) { #if 0 case ATOM_RSA_PKCS1_SHA1: case ATOM_RSA_PKCS1_SHA1_LOCAL: if (signature_length > self->size) goto fail; bignum_parse_u(s, signature_length, signature_data); break; case ATOM_SPKI: #endif case ATOM_SSH_RSA: { struct simple_buffer buffer; UINT32 length; const UINT8 *digits; int atom; simple_buffer_init(&buffer, signature_length, signature_data); if (!(parse_atom(&buffer, &atom) && (atom == ATOM_SSH_RSA) && parse_string(&buffer, &length, &digits) && (length <= self->size) && parse_eod(&buffer) )) goto fail; bignum_parse_u(s, length, digits); break; } /* It doesn't matter here which flavour of SPKI is used. */ case ATOM_SPKI_SIGN_RSA: case ATOM_SPKI_SIGN_DSS: { struct simple_buffer buffer; struct sexp *e; simple_buffer_init(&buffer, signature_length, signature_data); if (! ( (e = sexp_parse_canonical(&buffer)) && parse_eod(&buffer) && decode_rsa_sig_val(e, s, self->size)) ) goto fail; break; } default: fatal("do_rsa_verify: Internal error!\n"); } res = rsa_pkcs1_verify(self, length, msg, s); fail: mpz_clear(s); return res; }
/* * 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 ); }
int main( int argc, char *argv[] ) { FILE *f; int ret, i, c; rsa_context rsa; unsigned char hash[20]; unsigned char buf[512]; ret = 1; if( argc != 2 ) { printf( "usage: rsa_verify <filename>\n" ); #ifdef WIN32 printf( "\n" ); #endif goto exit; } printf( "\n . Reading public key from rsa_pub.txt" ); fflush( stdout ); if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL ) { printf( " failed\n ! Could not open rsa_pub.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 ) { printf( " failed\n ! mpi_read_file returned %d\n\n", ret ); goto exit; } rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3; fclose( f ); /* * Extract the RSA signature from the text file */ ret = 1; i = strlen( argv[1] ); memcpy( argv[1] + i, ".sig", 5 ); if( ( f = fopen( argv[1], "rb" ) ) == NULL ) { printf( "\n ! Could not open %s\n\n", argv[1] ); goto exit; } argv[1][i] = '\0', i = 0; while( fscanf( f, "%02X", &c ) > 0 && i < (int) sizeof( buf ) ) buf[i++] = (unsigned char) c; fclose( f ); if( i != rsa.len ) { printf( "\n ! Invalid RSA signature format\n\n" ); goto exit; } /* * Compute the SHA-1 hash of the input file and compare * it with the hash decrypted from the RSA signature. */ printf( "\n . Verifying 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_verify( &rsa, RSA_PUBLIC, RSA_SHA1, 20, hash, buf ) ) != 0 ) { printf( " failed\n ! rsa_pkcs1_verify returned %d\n\n", ret ); goto exit; } printf( "\n . OK (the decrypted SHA-1 hash matches)\n\n" ); ret = 0; exit: #ifdef WIN32 printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
/* * 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 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 message_rsa_decrypt(VCRYPT_CTX *ctx, rsa_context *public_rsa, uint8_t *ciphertext, size_t len, char **decrypted) { int ret = 0; int ret_len = 0; if (len < 5) return -ERR_DECRYPTION_ERROR; if (*ciphertext++ != VCRYPT_PROTOCOL_VERSION) return -ERR_DECRYPTION_ERROR; uint16_t encr_key_len = *((uint16_t*) ciphertext); ciphertext += 2; uint16_t sig_key_len = *((uint16_t*) ciphertext); ciphertext += 2; if (encr_key_len != ctx->ssl_req.rsa.len) return -ERR_DECRYPTION_ERROR; if ((len - 5 - sig_key_len) % encr_key_len) return -ERR_DECRYPTION_ERROR; int ciphertext_chunks = (len - 5 - sig_key_len) / encr_key_len; // maximum possible plaintext length int plain_len = ciphertext_chunks * ctx->ssl_req.rsa.len; if (ciphertext_chunks < 1) return -ERR_DECRYPTION_ERROR; // we need the signature too *decrypted = malloc(plain_len + 1); // 1 char for the null terminator if (!*decrypted) return -ERR_MALLOC; int chunk; size_t decrypted_len = 0; uint8_t *in = ciphertext, *out = (uint8_t*) *decrypted; for (chunk = 0; chunk < ciphertext_chunks; chunk++, out += decrypted_len, in += ctx->ssl_req.rsa.len) { if ((ret = rsa_pkcs1_decrypt(&ctx->ssl_req.rsa, RSA_PRIVATE, &decrypted_len, in, out, ctx->ssl_req.rsa.len)) != 0) { char err[256]; error_strerror(ret, err, sizeof err); dolog(0, " failed\n ! rsa_pkcs1_decrypt returned %d: %s (chunk: %d)\n", ret, err, chunk); free(*decrypted); return -ERR_DECRYPTION_ERROR; } ret_len += decrypted_len; } *out = 0; if (!public_rsa || !public_rsa->len) { return -ERR_SIGN_VERIFY_ERROR; } unsigned char hash[64]; sha4_context sha_ctx; sha4_starts(&sha_ctx, 1); sha4_update(&sha_ctx, (uint8_t*) *decrypted, ret_len); sha4_finish(&sha_ctx, hash); if ((ret = rsa_pkcs1_verify(public_rsa, RSA_PUBLIC, public_rsa->hash_id, sizeof hash, hash, in)) != 0) { char err[256]; error_strerror(ret, err, sizeof err); dolog(0, " failed\n ! rsa_pkcs1_verify returned %d: %s\nmessage was: %s\n", ret, err, *decrypted); return -ERR_SIGN_VERIFY_ERROR; } return ret_len; }