Getting error in EVP_OpenInit() of OpenSSL EVP api

2020-03-06 08:45发布

问题:

I am facing a problem in RSA decryption using OpenSSL Library (EVP api). Here is my code for key generation

#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>

#define SECFILE "sec.pem"
#define PUBFILE "pub.pem"

int main()
{

    EVP_PKEY_CTX *ctx;
    EVP_PKEY *pkey = NULL;
    ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
    FILE *fp;

    if (!ctx)
    {
        /* Error occurred */
        perror("Error in CTX \n");

    }
    if (EVP_PKEY_keygen_init(ctx) <= 0)
    {
        /* Error */
        perror("Error in EVP_PKEY_keygen_init \n");
    }
    if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
    {
        /* Error */
        perror("Error in EVP_PKEY_CTX_set_rsa_keygen_bits \n");
    }
    /* Generate key */
    if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
    {   
        /* Error */
        perror("Error in EVP_PKEY_keygen \n");

    }


    fp = fopen(SECFILE, "w");
    PEM_write_PrivateKey(fp, pkey, NULL,NULL, 0,0, NULL);
    fclose(fp);

    fp = fopen(PUBFILE, "w");
    PEM_write_PUBKEY(fp,pkey);
    fclose(fp);


    return 0;
}

For encryption :

I used this link

For decryption :

   int do_evp_open(FILE *rsa_pkey_file, FILE *in_file, FILE *out_file) 
{ 
    int retval = 0; 
    RSA *rsa_pkey = NULL; 
    EVP_PKEY *pkey = EVP_PKEY_new(); 
    EVP_CIPHER_CTX ctx; 
    unsigned char buffer[4096]; 
    unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH]; 
    size_t len; 
    int len_out; 
    unsigned char *ek; 
    int eklen ; 
    uint32_t eklen_n; 
    unsigned char iv[EVP_MAX_IV_LENGTH] = {122,205,106,192,4,183,69,176,84,28,214,226,220,140,86,174}; 


    /// Read RSA Private Key 
    if (PEM_read_RSAPrivateKey(rsa_pkey_file, &rsa_pkey, NULL, NULL) == NULL) 
    { 
        fprintf(stderr, "Error loading RSA Private Key File.\n"); 
        ERR_print_errors_fp(stderr); 
        retval = -2; 
        goto out; 
    } 


    /// Assign RSA key to EVP key
    if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey)) 
    { 
        fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n"); 
        retval = -3; 
        goto out; 
    }

    EVP_CIPHER_CTX_init(&ctx); 

    ek = malloc( EVP_PKEY_size(pkey)); 



    if (!EVP_OpenInit(&ctx, EVP_aes_128_cbc(), ek, eklen, iv,pkey)) 
    { 
        fprintf(stderr, "EVP_OpenInit: failed.\n"); 
       ERR_print_errors_fp(stderr); /// Prints error of occured in Openssl  
        retval = -3; 
        goto out_free; 
    } 




    while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0) 
    { 
        if (!EVP_OpenUpdate(&ctx, buffer_out, &len_out, buffer, len)) 
        { 
            fprintf(stderr, "EVP_OpenUpdate: failed.\n"); 
            retval = 3; 
            goto out_free; 
        } 

        if (fwrite(buffer_out, len_out, 1, out_file) != 1) 
        { 
            perror("output file"); 
            retval = -5; 
            goto out_free; 
        } 
    } 

    if (ferror(in_file)) 
    { 
        perror("input file"); 
        retval = -4; 
        goto out_free; 
    } 

    if (!EVP_OpenFinal(&ctx, buffer_out, &len_out)) 
    { 
        fprintf(stderr, "EVP_OpenFinal: failed.\n"); 
        retval = - 3; 
        goto out_free; 
    } 

    if (fwrite(buffer_out, len_out, 1, out_file) != 1) 
    { 
        perror("output file"); 
        retval = -5; 
        goto out_free; 
    } 

    out_free: 
    EVP_PKEY_free(pkey); 
    free(ek); 

    out: 
    return retval; 
} 

My Private and public keys are :

-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDj+g6m7KY5zK8z
FZ/MKFySr1ZB+n0b3GjhMUcUDn5S9N7oyoCzkOVVa7gl0jTI8dwCFVAy8693Rq+i
AT7dUTLViT9V8GkX9r0yFcppt5uc2YgI5aOOTvmQKQe08FSZ7QbviEL25MNnBfB1
wpd+mJN3nb0hkeo7x2IZD/ZVfs+TmOG9mHbQR8b1XcxEDoLx3aX1J8Eix1pN7YK6
nDAFm984Ho+PCz1aGl/TnDl3b90X5HXGHiD6uNDHokZ+th8B6AeFFRlkWlQd0w2R
e/EEZ36p4TQOHSc3sSUw6pen0N8YmBNZksBEr1vsZvYkKtRKCfy0fXtL4iqKzcgJ
ocos+Z6nAgMBAAECggEBALlWDdlYpF5y76/JEaso2PGLR8XFvTYMPttsc0tz6PDK
D/oSvwS8dCS4uPFObgk6ztCGwTda8rg2KAy9lHzaSUheFrZoBxgrSG5SVscRNJoU
IsqQ3iGQRMUVBiXsB+tHTg8nqMENA2pa4rzpoL2Tjrd87kg/VryYgEC9wFaLDHgB
FaXJJlaeuTBQXV7Ga9pg+KF1Kv91/q3T62Um0ggSajFpX15x6sLIo5EWm0DGksn0
chQeiEs33e8fHil95g0nXK+hXOMnMvbAln/eOCGktO4JnPTjicAA7iKliCsLiaeZ
t5Czscv/8AVlBAISGJcE8ASM+AbalXtnoOK6W+dv0gkCgYEA/cPi7U8bJ0tlvxF3
3vc8V7uzuAgKtOKQet1spQtAoi343ZoSyFHQEwO5PMmtB56/mk3+/mDpoKTQo0oK
f5COIlzW+PIMQCroalpJe+ZcY/PS8SPoOY39yiX4WQchgac01R0Qf6XDAOfyfZ9d
MZTtDgpkx/oyfRTzxI7D9SZUqZ0CgYEA5fwH5uwmc0fsIw3tl3pHHOK9g78Rs6XE
0feXplBCzx+qaEtAK1Jp1nMX/PmN575i3UN3dii9YV8v9geTf+hytpQd/TbrvsSY
Py9j95XYN75Z5TAsWnZbZr/gTdZSz0yObb/9GzxBipp+EHCEOSS0RF8u9XHlM9bC
0agB4VZKqBMCgYByIjxaR44K6lpkyVKEseYt/3ohd1x5Zr1cxWIsCReU2eBoqvdv
qXxQUQhrUrnEB55dpF7fwm7Rlc9Q4eg+36FNyzvU0+i2o5XM37bVRxKe0fc6BdBY
sohG9zTvtclYKwAUKfJVtxQxwCDMZ3Te7ACCpCIX32v93gKVkTCJfift8QKBgHZ9
PAEAZ+r7AjEpSuDBMgQy2ZsYBOG+pUHcQzh/n3wg/2XOZ1gqlLbVA2XlmPPtxffj
e5fX84JITWh/jMHYm8lvVGgSNLFLjnj3TJTRkd1eZ+hJwoA0/HBaqRDRPEbrVXI7
+QZgLBBh+lMz9RuPyoRzWblBHepwWl00JwvWro4bAoGBAKFAXVzbx74JM6wzr9H5
TusTwOM5mf/I1TkCq1Dd5n1vDVfrkNokZ2LfJWqiQHLZj2rGxSQSVjIsVaBmEDTZ
ob8duUsbkYQe4dToHFHcBO+akBtULC4HWv/D4pPVoyAE7WJBJBw0vl1sA15kiXBu
HBXffOzN/Erqvp90HLtefpMp
-----END PRIVATE KEY-----


-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4/oOpuymOcyvMxWfzChc
kq9WQfp9G9xo4TFHFA5+UvTe6MqAs5DlVWu4JdI0yPHcAhVQMvOvd0avogE+3VEy
1Yk/VfBpF/a9MhXKabebnNmICOWjjk75kCkHtPBUme0G74hC9uTDZwXwdcKXfpiT
d529IZHqO8diGQ/2VX7Pk5jhvZh20EfG9V3MRA6C8d2l9SfBIsdaTe2CupwwBZvf
OB6Pjws9Whpf05w5d2/dF+R1xh4g+rjQx6JGfrYfAegHhRUZZFpUHdMNkXvxBGd+
qeE0Dh0nN7ElMOqXp9DfGJgTWZLARK9b7Gb2JCrUSgn8tH17S+Iqis3ICaHKLPme
pwIDAQAB
-----END PUBLIC KEY-----

The error I am getting While EVP_OpenInit is :

140004942804648:error:0407106B:lib(4):func(113):reason(107):rsa_pk1.c:190: 140004942804648:error:04065072:lib(4):func(101):reason(114):rsa_eay.c:594

Any help would be appreciated. Thanks, Pawan

回答1:

Are you absolutely sure, that you have initialized variable eklen?



回答2:

I see you have used EVP_OpenInit(), EVP_OpenUpdate() and EVP_OpenFinal() for decryption. So I'm going to assume that you've used EVP_SealInit(), EVP_SealUpdate() and EVP_SealFinal() functions for encryption.

So if you have used EVP_SealInit(), you must have passed the address (pointer) to eklen (please check man EVP_SealInit) where the variable gets a value assigned. In analogous to that the eklen variable that you are passing to EVP_OpenInit() must contain a valid key length.

The following is the description from man EVP_OpenInit.

EVP_OpenInit() initializes a cipher context ctx for decryption with cipher type. It decrypts the encrypted symmetric key of length ekl bytes passed in the ek parameter using the private key priv. The IV is supplied in the iv parameter.

I'm not sure here, but I guess you need to use EVP_PKEY_size() function in this case to get the length of the key.

For example (in your decryption code):

....
..
. 
EVP_CIPHER_CTX_init(&ctx); 
ek = malloc( EVP_PKEY_size(pkey)); 

/* Add the following line */
eklen = EVP_PKEY_size(pkey);

if (!EVP_OpenInit(&ctx, EVP_aes_128_cbc(), ek, eklen, iv,pkey)) 
{ 
    fprintf(stderr, "EVP_OpenInit: failed.\n"); 
...
..
.