I am trying to encrypt and Decrypt file using EVP apis. I am getting correct result when size is greater or equal to 16 bytes only. Here is my codes for the above stated problem.

 #include <stdio.h>

    #include <stdlib.h>

    #include <openssl/evp.h>
    #include <openssl/pem.h>
    #include <openssl/rsa.h>
    #include <openssl/err.h>

    #include <arpa/inet.h> 

    #if 1
    int do_evp_seal(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;
        ctx = EVP_CIPHER_CTX_new();
        unsigned char buffer[4096];
        unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH];
        //size_t len;
        int len_out;
        unsigned char *ek = NULL;
        int eklen=0;
        uint32_t eklen_n=0;
        unsigned char iv[EVP_MAX_IV_LENGTH];

        if (!PEM_read_RSA_PUBKEY(rsa_pkey_file, &rsa_pkey, NULL, NULL))
        {
            fprintf(stderr, "Error loading RSA Public Key File.\n");
            ERR_print_errors_fp(stderr);
            retval = 2;
            goto out;
        }

        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_SealInit(ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &pkey, 1))
        {
            fprintf(stderr, "EVP_SealInit: failed.\n");
            retval = 3;
            goto out_free;
        }

        /* First we write out the encrypted key length, then the encrypted key,
         * then the iv (the IV length is fixed by the cipher we have chosen).
         */

        eklen_n = htonl(eklen);
        if (fwrite(&eklen_n, sizeof eklen_n, 1, out_file) != 1)
        {
            perror("output file");
            retval = 5;
            goto out_free;
        }
        if (fwrite(ek, eklen, 1, out_file) != 1)
        {
            perror("output file");
            retval = 5;
            goto out_free;
        }
        if (fwrite(iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc()), 1, out_file) != 1)
        {
            perror("output file");
            retval = 5;
            goto out_free;
        }

        /* Now we process the input file and write the encrypted data to the
         * output file. */

        while (1)
        {
            int numlen = fread(buffer, 1, sizeof buffer, in_file);
            if (!EVP_SealUpdate(ctx, buffer_out, &len_out, buffer, numlen))
            {
                fprintf(stderr, "EVP_SealUpdate: 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 (numlen < sizeof(buffer)) { // EOF
                break;
            }
        }

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

        if (!EVP_SealFinal(ctx, buffer_out, &len_out))
        {
            fprintf(stderr, "EVP_SealFinal: 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);
        EVP_CIPHER_CTX_cleanup(ctx);
        free(ek);

        out:
        return retval;
    }
    #endif
    int main(int argc, char *argv[])
    {
        FILE *rsa_pkey_file,*ifp,*ofp;
        int rv;

        if (argc < 2)
        {
            fprintf(stderr, "Usage: %s <PEM RSA Public Key File>\n", argv[0]);
            exit(1);
        }

        rsa_pkey_file = fopen(argv[1], "rb");
        ifp = fopen(argv[2], "rb");
        ofp = fopen(argv[3], "wb");
        if (!rsa_pkey_file)
        {
            perror(argv[1]);
            fprintf(stderr, "Error loading PEM RSA Public Key File.\n");
            exit(2);
        }
        if (!ifp)
        {
            perror(argv[1]);
            fprintf(stderr, "Error loading input file.\n");
            exit(2);
        }
        if (!ofp)
        {
            perror(argv[1]);
            fprintf(stderr, "Error loading output file.\n");
            exit(2);
        }

        rv = do_evp_seal(rsa_pkey_file, ifp, ofp);

        fclose(rsa_pkey_file);
        fclose(ifp);
        fclose(ofp);
        return rv;
    }

Here is my code for decryption for the above stated problem. For size less than 16 bytes the decrypted file is empty. Although the code seems to be logically correct.

#include <stdio.h>
#include <stdlib.h>

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/err.h>

#include <arpa/inet.h> /* For htonl() */


#if 1
int do_evp_unseal(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;
    ctx = EVP_CIPHER_CTX_new();
    unsigned char buffer[4096];
    unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH];
    //size_t len;
    int len_out;
    unsigned char *ek;
    unsigned int eklen=0;
    uint32_t eklen_n=0;
    unsigned char iv[EVP_MAX_IV_LENGTH];

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

    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));

    /* First need to fetch the encrypted key length, encrypted key and IV */

    if (fread(&eklen_n, sizeof eklen_n, 1, in_file) != 1)
    {
        perror("input file");
        retval = 4;
        goto out_free;
    }
    eklen = ntohl(eklen_n);
    if (eklen > EVP_PKEY_size(pkey))
    {
        fprintf(stderr, "Bad encrypted key length (%u > %d)\n", eklen,
            EVP_PKEY_size(pkey));
        retval = 4;
        goto out_free;
    }
    if (fread(ek, eklen, 1, in_file) != 1)
    {
        perror("input file");
        retval = 4;
        goto out_free;
    }
    if (fread(iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc()), 1, in_file) != 1)
    {
        perror("input file");
        retval = 4;
        goto out_free;
    }

    if (!EVP_OpenInit(ctx, EVP_aes_128_cbc(), ek, eklen, iv, pkey))
    {
        fprintf(stderr, "EVP_OpenInit: failed.\n");
        retval = 3;
        goto out_free;
    }

    while (1)
    {
        int numlen = fread(buffer, 1, sizeof buffer, in_file);
        if (!EVP_OpenUpdate(ctx, buffer_out, &len_out, buffer, numlen))
        {
            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 (numlen < sizeof(buffer)) { // EOF
            break;
        }
    }

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

    if (!EVP_OpenFinal(ctx, buffer_out, &len_out))
    {
        fprintf(stderr, "EVP_SealFinal: 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);
    EVP_CIPHER_CTX_cleanup(ctx);
    free(ek);

    out:
    return retval;
}
#endif
int main(int argc, char *argv[])
{
    FILE *rsa_pkey_file,*ifp,*ofp;
    int rv;

    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s <PEM RSA Private Key File>\n", argv[0]);
        exit(1);
    }

    rsa_pkey_file = fopen(argv[1], "rb");
    ifp = fopen(argv[2], "rb");
    ofp = fopen(argv[3], "wb");
    if (!rsa_pkey_file)
    {
        perror(argv[1]);
        fprintf(stderr, "Error loading PEM RSA Private Key File.\n");
        exit(2);
    }

    rv = do_evp_unseal(rsa_pkey_file, ifp, ofp);

    fclose(rsa_pkey_file);
    fclose(ifp);
    fclose(ofp);
    return rv;
}
0

There are 0 answers