RSA

You cannot do a "private encrypt" operation using EVP_PKEY_encrypt. That function only does a public encrypt operation. Similarly you cannot do "public decrypt" with EVP_PKEY_decrypt.

In reality a "private encrypt" operation is more commonly known as a signature. You need to use EVP_PKEY_sign for that. A "public decrypt" operaiton is more commonly known as a verify. You need to use EVP_PKEY_verify for that.

Load public key

OSSL_DECODER_CTX *dctx; EVP_PKEY *pkey = NULL; const char *format = "PEM"; const char *structure = NULL; // any structure const char *keytype = "RSA"; dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, format, structure, keytype, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, NULL, NULL); if(!dctx) { unsigned long e = ERR_get_error(); print_error("Key decoder hiccup: '%X'.\n", e); return NULL; } size_t size = key_size; // data pointer will be changed const unsigned char *data = const_cast<const unsigned char*>(key); if (!OSSL_DECODER_from_data(dctx, &data, &size)) { unsigned long e = ERR_get_error(); print_error("Key decoding error: '%X'.\n", e); print_error("load_rsa RSA error: %s %s %s\n", ERR_lib_error_string(e), ERR_reason_error_string(e), ERR_error_string(e, NULL) ); } OSSL_DECODER_CTX_free(dctx); free(key);

Encypt buffer

const size_t pwd_buffer_size = 512; unsigned char pwd_buffer[pwd_buffer_size]; memset(pwd_buffer, 0x00, pwd_buffer_size); // signs the `res_k0` using the private key rsa and stores the signature in `pwd_buffer` size_t pwd_size = pwd_buffer_size; EVP_PKEY *pkey = rsa; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); EVP_PKEY_encrypt_init(ctx); EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING); EVP_PKEY_encrypt(ctx, pwd_buffer, &pwd_size, res_k0, key_size); EVP_PKEY_CTX_free(ctx);

Load private key with password

OSSL_DECODER_CTX *dctx; EVP_PKEY *pkey = NULL; const char *format = "PEM"; const char *structure = NULL; // any structure const char *keytype = "RSA"; dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, format, structure, keytype, OSSL_KEYMGMT_SELECT_KEYPAIR, NULL, NULL); if(!dctx) { int e = ERR_get_error(); print_error("decoder hiccup: '%X'.\n", e); return; } OSSL_DECODER_CTX_set_passphrase_cb(dctx, &pass_cb, NULL); size_t size = key_size; // data pointer will be changed const unsigned char *data = const_cast<const unsigned char*>(key); if (!OSSL_DECODER_from_data(dctx, &data, &size)) { int e = ERR_get_error(); print_error("decoding error: '%X'.\n", e); } OSSL_DECODER_CTX_free(dctx);

Decrypt buffer

const size_t buffer_size = 512; unsigned char crypted_pwd[buffer_size]; memcpy(crypted_pwd, crypted, buffer_size); unsigned char pwd[buffer_size]; memset(pwd, 0x00, buffer_size); size_t pwd_size = buffer_size; EVP_PKEY *pkey = _rsa; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); EVP_PKEY_decrypt_init(ctx); EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING); bool decrypt_ok = EVP_PKEY_decrypt(ctx, pwd, &pwd_size, crypted_pwd, buffer_size) == 1; EVP_PKEY_CTX_free(ctx); if(!decrypt_ok) { unsigned long e = ERR_get_error(); print_error("Can't decrypt '%X'\n", e); print_error("decrypt: %s %s %s\n", ERR_lib_error_string(e), ERR_reason_error_string(e), ERR_error_string(e, NULL) ); return false; }