in projects/linux/crypto/rsa_openssl.c [382:506]
static int rsa_openssl_load_pubkey (EVP_PKEY **rsa, const struct rsa_public_key *key)
{
uint8_t exp[4];
BIGNUM *n = NULL;
BIGNUM *e = NULL;
int status;
ERR_clear_error ();
n = BN_bin2bn (key->modulus, key->mod_length, NULL);
if (n == NULL) {
return -ERR_get_error ();
}
exp[0] = key->exponent >> 24;
exp[1] = key->exponent >> 16;
exp[2] = key->exponent >> 8;
exp[3] = key->exponent;
e = BN_bin2bn (exp, sizeof (exp), NULL);
if (e == NULL) {
status = -ERR_get_error ();
goto err_e;
}
#if OPENSSL_IS_VERSION_3
{
OSSL_PARAM_BLD *param_list = NULL;
OSSL_PARAM *rsa_params = NULL;
EVP_PKEY_CTX *ctx = NULL;
param_list = OSSL_PARAM_BLD_new ();
if (param_list == NULL) {
status = -ERR_get_error ();
goto err_list;
}
status = OSSL_PARAM_BLD_push_BN (param_list, "n", n);
if (status != 1) {
status = -ERR_get_error ();
goto err_push;
}
status = OSSL_PARAM_BLD_push_BN (param_list, "e", e);
if (status != 1) {
status = -ERR_get_error ();
goto err_push;
}
rsa_params = OSSL_PARAM_BLD_to_param (param_list);
if (rsa_params == NULL) {
status = -ERR_get_error ();
goto err_push;
}
ctx = EVP_PKEY_CTX_new_from_name (NULL, "RSA", NULL);
if (ctx == NULL) {
status = -ERR_get_error ();
goto err_ctx;
}
status = EVP_PKEY_fromdata_init (ctx);
if (status != 1) {
status = -ERR_get_error ();
goto err_key;
}
status = EVP_PKEY_fromdata (ctx, rsa, EVP_PKEY_PUBLIC_KEY, rsa_params);
if (status != 1) {
status = -ERR_get_error ();
goto err_key;
}
status = 0;
err_key:
EVP_PKEY_CTX_free (ctx);
err_ctx:
OSSL_PARAM_free (rsa_params);
err_push:
OSSL_PARAM_BLD_free (param_list);
}
#else
{
RSA *rsa_key;
rsa_key = RSA_new ();
if (rsa_key == NULL) {
status = -ERR_get_error ();
goto err_list;
}
status = RSA_set0_key (rsa_key, n, e, NULL);
if (status == 0) {
status = -ERR_get_error ();
goto err_rsa;
}
*rsa = EVP_PKEY_new ();
if (*rsa == NULL) {
status = -ERR_get_error ();
goto err_rsa;
}
status = EVP_PKEY_assign_RSA (*rsa, rsa_key);
if (status != 1) {
status = -ERR_get_error ();
goto err_rsa;
}
/* Don't free anything that was created. */
return 0;
err_rsa:
RSA_free (rsa_key);
}
#endif
err_list:
BN_free (e);
err_e:
BN_free (n);
return status;
}