int cRSAPrivateKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength) { if (a_EncryptedMaxLength < m_Rsa.len) { LOGD("%s: Invalid a_EncryptedMaxLength: got %u, exp at least %u", __FUNCTION__, (unsigned)a_EncryptedMaxLength, (unsigned)(m_Rsa.len) ); ASSERT(!"Invalid a_DecryptedMaxLength!"); return -1; } if (a_EncryptedMaxLength < m_Rsa.len) { LOGD("%s: Invalid a_PlainLength: got %u, exp at least %u", __FUNCTION__, (unsigned)a_PlainLength, (unsigned)(m_Rsa.len) ); ASSERT(!"Invalid a_PlainLength!"); return -1; } int res = rsa_pkcs1_encrypt( &m_Rsa, ctr_drbg_random, &m_Ctr_drbg, RSA_PRIVATE, a_PlainLength, a_PlainData, a_EncryptedData ); if (res != 0) { return -1; } return (int)m_Rsa.len; }
int SparkProtocol::handshake(void) { memcpy(queue + 40, device_id, 12); int err = blocking_receive(queue, 40); if (0 > err) return err; parse_device_pubkey_from_privkey(queue+52, core_private_key); rsa_context rsa; init_rsa_context_with_public_key(&rsa, server_public_key); const int len = 52+MAX_DEVICE_PUBLIC_KEY_LENGTH; err = rsa_pkcs1_encrypt(&rsa, RSA_PUBLIC, len, queue, queue + len); rsa_free(&rsa); if (err) return err; blocking_send(queue + len, 256); err = blocking_receive(queue, 384); if (0 > err) return err; err = set_key(queue); if (err) return err; queue[0] = 0x00; queue[1] = 0x10; hello(queue + 2, descriptor.was_ota_upgrade_successful()); err = blocking_send(queue, 18); if (0 > err) return err; if (!event_loop()) // read the hello message from the server return -1; return 0; }
int chiffrer_rsa(char* data, char* sortie, int taille_data ) { FILE *f; int ret; size_t i; rsa_context rsa; entropy_context entropy; ctr_drbg_context ctr_drbg; char *pers = "rsa_encrypt"; printf( "[i] Seeding the random number generator\n" ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (unsigned char *) pers, strlen( pers ) ) ) != 0 ) { printf( "[-] ctr_drbg_init returned %d\n", ret ); goto exit; } printf( "[i] Reading private key\n" ); rsa_init( &rsa, RSA_PKCS_V15, 0 ); if( ( ret = mpi_read_string( &rsa.N, RSA_N_BASE, RSA_N ) ) != 0 || ( ret = mpi_read_string( &rsa.D, RSA_D_BASE, RSA_D ) ) != 0 ) { printf( "[-] mpi_read_file returned %d\n", ret ); goto exit; } rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3; /* * Calculate the RSA encryption of the hash. */ printf( "[i] Generating the RSA encrypted value (%d/%d)\n", rsa.len, taille_data ); fflush( stdout ); if( ( ret = rsa_pkcs1_encrypt( &rsa, ctr_drbg_random, &ctr_drbg, RSA_PRIVATE, taille_data, data, sortie ) ) != 0 ) { printf( "[-] rsa_pkcs1_encrypt returned %d\n\n", ret ); goto exit; } printf( "[i] Cryptogramme copie\n"); exit: return( ret ); }
static int rsa_encrypt_wrap( void *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { ((void) osize); *olen = ((rsa_context *) ctx)->len; return( rsa_pkcs1_encrypt( (rsa_context *) ctx, f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) ); }
uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) { rsa_context trsa; const char *pers = "rsa_encrypt"; int rc; entropy_context entropy; ctr_drbg_context ctr_drbg; entropy_init(&entropy); if ((rc = ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, (const unsigned char *)pers, strlen(pers))) != 0) debug(1, "ctr_drbg_init returned %d\n", rc); rsa_init(&trsa, RSA_PKCS_V21, POLARSSL_MD_SHA1); // padding and hash id get overwritten // BTW, this seems to reset a lot of parameters in the rsa_context rc = x509parse_key(&trsa, (unsigned char *)super_secret_key, strlen(super_secret_key), NULL, 0); if (rc != 0) debug(1, "Error %d reading the private key."); uint8_t *out = NULL; switch (mode) { case RSA_MODE_AUTH: trsa.padding = RSA_PKCS_V15; trsa.hash_id = POLARSSL_MD_NONE; debug(2, "rsa_apply encrypt"); out = malloc(trsa.len); rc = rsa_pkcs1_encrypt(&trsa, ctr_drbg_random, &ctr_drbg, RSA_PRIVATE, inlen, input, out); if (rc != 0) debug(1, "rsa_pkcs1_encrypt error %d.", rc); *outlen = trsa.len; break; case RSA_MODE_KEY: debug(2, "rsa_apply decrypt"); trsa.padding = RSA_PKCS_V21; trsa.hash_id = POLARSSL_MD_SHA1; out = malloc(trsa.len); #if POLARSSL_VERSION_NUMBER >= 0x01020900 rc = rsa_pkcs1_decrypt(&trsa, ctr_drbg_random, &ctr_drbg, RSA_PRIVATE, (size_t *)outlen, input, out, trsa.len); #else rc = rsa_pkcs1_decrypt(&trsa, RSA_PRIVATE, outlen, input, out, trsa.len); #endif if (rc != 0) debug(1, "decrypt error %d.", rc); break; default: die("bad rsa mode"); } rsa_free(&trsa); debug(2, "rsa_apply exit"); return out; }
static int rsa_encrypt_wrap( void *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { *olen = ((rsa_context *) ctx)->len; if( *olen > osize ) return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); return( rsa_pkcs1_encrypt( (rsa_context *) ctx, f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) ); }
int ciphertext_from_nonce_and_id(const unsigned char *nonce, const unsigned char *id, const unsigned char *pubkey, unsigned char *ciphertext) { unsigned char plaintext[52]; memcpy(plaintext, nonce, 40); memcpy(plaintext + 40, id, 12); rsa_context rsa; init_rsa_context_with_public_key(&rsa, pubkey); int ret = rsa_pkcs1_encrypt(&rsa, RSA_PUBLIC, 52, plaintext, ciphertext); rsa_free(&rsa); return ret; }
int ciphertext_from_nonce_and_id(const unsigned char *nonce, const unsigned char *id, const unsigned char *pubkey, unsigned char *ciphertext) { unsigned char plaintext[52]; memcpy(plaintext, nonce, 40); memcpy(plaintext + 40, id, 12); rsa_context rsa; init_rsa_context_with_public_key(&rsa, pubkey); #ifdef USE_MBEDTLS int ret = mbedtls_rsa_pkcs1_encrypt(&rsa, mbedtls_default_rng, nullptr, MBEDTLS_RSA_PUBLIC, 52, plaintext, ciphertext); #else int ret = rsa_pkcs1_encrypt(&rsa, RSA_PUBLIC, 52, plaintext, ciphertext); #endif rsa_free(&rsa); 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) { 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; }
/** * Adds padding and encrypts a string using either private or public key. * (depending on mode). * @param message: arbitrary binary string to be encrypted. * @param keytable: table containing either the public or the private key, as generated by gen_key. * @return The cyphertext (as a binary string). * @see rsa_genkey */ static int luarsa_pkcs1_encrypt (lua_State *L) { int res = 0; int mode; size_t lmsg, lresult; rsa_context rsa; char *message = (char*)luaL_checklstring(L, 1, &lmsg); /* message */ char result[KEY_SIZE]; char alt_result[KEY_SIZE]; char* strMode=NULL; if(lua_type(L, 3)==LUA_TSTRING) { printf("Got parameter\n"); strMode = (char*)lua_tostring(L, 3); printf("[%s]\n", strMode); mode = strncmp(strMode, "private", 7) ? RSA_PUBLIC : RSA_PRIVATE; } rsa_init( &rsa, RSA_PKCS_V15, 0, NULL, NULL ); processKey(L, 2, &rsa); /* keytable */ rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3; memset(result, 0, KEY_SIZE); // <test> by Jason printf("\nMode==%s\n", mode==RSA_PUBLIC ? "RSA_PUBLIC" : "RSA_PRIVATE" ); printf("Size==%d\n", lmsg ); printf("Crypt.Size==%d\n", rsa.len ); printf("ver: %d\n", rsa.ver); printf("len: %d\n", rsa.len); printf("padding: %d\n", rsa.padding); printf("hash_id: %d\n", rsa.hash_id); mpi_print("N:%s\n", &rsa.N); mpi_print("E:%s\n", &rsa.E); if(mode!=RSA_PUBLIC) { //mpi_print("D:%s\n", &rsa.D); //mpi_print("P:%s\n", &rsa.P); //mpi_print("Q:%s\n", &rsa.Q); //mpi_print("DP:%s\n", &rsa.DP); //mpi_print("DQ:%s\n", &rsa.DQ); //mpi_print("QP:%s\n", &rsa.QP); //mpi_print("RN:%s\n", &rsa.RN); //mpi_print("RP:%s\n", &rsa.RP); //mpi_print("RQ:%s\n", &rsa.RQ); } // </test> by Jason // pass rsa context and message to encryption engine res = rsa_pkcs1_encrypt(&rsa, RSA_PUBLIC, lmsg, message, result); if(res) luaL_error(L, "Error during cipher (%d)", res); /* lmsg = 128; res = rsa_pkcs1_decrypt(&rsa, mode, &lmsg, result, alt_result); if(res) luaL_error(L, "Error during decipher (%d)", res); printf("(%d)", lmsg); */ push_private_key(L, &rsa); // push encrypted result buffer lua_pushlstring(L, result, rsa.len); /* ciphertext */ rsa_free( &rsa ); return 1; }
int sign(unsigned char *output,unsigned char *input, int input_len, char *pri_key_file) { unsigned char * cipher = NULL; unsigned char * k_c = NULL; unsigned char sign[128]; int ret; FILE *fkey; rsa_context rsa_ctx; havege_state prng_ctx; cipher = (unsigned char *)malloc((32)*sizeof(char)); /* ********************** HASH controle integrite *********************** */ k_c = (unsigned char *)malloc(2*KEY_LENGTH*sizeof(unsigned char)); memset(k_c, 0, 2*KEY_LENGTH); //generation de la clef symetrique de KEY_LENGTH bits gen_key(k_c, KEY_LENGTH); sha2_hmac(k_c, KEY_LENGTH, input, input_len, cipher, 0); print_hex(k_c, KEY_LENGTH, "cle secrete utilisée pour le hash : "); /* *** Read the private asymetric key in the file*** */ if( ( fkey = fopen( pri_key_file, "rb" ) ) == NULL ) { ret = 1; printf( " failed\n ! Could not open %s\n" \ " ! Please run rsa_genkey first\n\n",pri_key_file ); goto cleanup; } rsa_init( &rsa_ctx, RSA_PKCS_V15, 0 ); if( ( ret = mpi_read_file( &rsa_ctx.N , 16, fkey ) ) != 0 || ( ret = mpi_read_file( &rsa_ctx.E , 16, fkey ) ) != 0 || ( ret = mpi_read_file( &rsa_ctx.D , 16, fkey ) ) != 0 || ( ret = mpi_read_file( &rsa_ctx.P , 16, fkey ) ) != 0 || ( ret = mpi_read_file( &rsa_ctx.Q , 16, fkey ) ) != 0 || ( ret = mpi_read_file( &rsa_ctx.DP, 16, fkey ) ) != 0 || ( ret = mpi_read_file( &rsa_ctx.DQ, 16, fkey ) ) != 0 || ( ret = mpi_read_file( &rsa_ctx.QP, 16, fkey ) ) != 0 ) { printf( " failed\n ! mpi_read_file returned %d\n\n", ret ); goto cleanup; } rsa_ctx.len = ( mpi_msb( &rsa_ctx.N ) + 7 ) >> 3; fclose( fkey ); /* *** SYM_K(key) : chiffrement RSA de la clé de chiffrement key (16) => rsa-1024 bits = 128 octets en sortie *** */ /* *** cipher = ASYM_Kpriv (Hash) *** */ havege_init(&prng_ctx); memset(sign, 0, 128); if( ( ret = rsa_pkcs1_encrypt( &rsa_ctx, havege_random, &prng_ctx, RSA_PRIVATE, KEY_LENGTH, cipher, sign ) ) != 0 ) { printf( " failed\n ! rsa_pkcs1_encrypt returned %d\n\n", ret ); goto cleanup; } print_hex(sign, sizeof(sign), "Hash chiffrée avec RSA : "); /* *** ASYM_Kpub (K) *** */ output = (unsigned char *) malloc( 128 * sizeof(unsigned char)); memcpy(output, sign, 128); cleanup: if(cipher != NULL) { memset(cipher, 0, 32); free(cipher); } if(k_c != NULL) { memset(k_c, 0, 2*KEY_LENGTH); free(k_c); } memset(&prng_ctx,0x00, sizeof(havege_state)); memset(&rsa_ctx, 0x00, sizeof(rsa_ctx)); memset(sign, 0, 128); 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 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; }