this post was submitted on 16 Jul 2023
1 points (100.0% liked)

openssl

1 readers
0 users here now

openssl.

founded 1 year ago
MODERATORS
 
This is an automated archive.

The original was posted on /r/openssl by /u/inigmati1 on 2023-07-15 07:49:33+00:00.


I am trying to decrypt 64byte data encrypted using aes_256_gcm() algorithm using Openssl library in C. General process is initialise context, initialising EVP decrypt API, setting up IV, calling EVP Decrypt updates, then setting up TAG using EVP_CIPHER_CTX_ctrl() and finally, finalising the decryption. Yet, after checking up everything, segmentation fault occurs when execution reaches at EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof(tag), tag);

. Even using "strlen" or manual size in place of "sizeof(tag)" has no change in be the behaviour. Please correct me what's going wrong.

N.B. 1: I am not setting up AAD whilst encrypting the plaintext. Even if I used AAD with passing NULL values, no effect at all.

N.B. 2: Signature verification is okay. If tried to decrypt same string in logic written in Typescript, it works fine.

I am not sure where I am getting wrong.

Here's the C code.

int aes_decrypt(const unsigned char *ciphertext, size_t ciphertext_len, char *key,
            char *iv, unsigned char *plaintext, unsigned char *tag)
{
    if (tag == NULL)
    {
        fprintf(stderr, "Error: tag is NULL.\n");
        return 0;
    }

    if (strlen(tag) < TAG_SIZE)
    {
        fprintf(stderr, "Error: tag is smaller than TAG_SIZE.\n");
        return 0;
    }

    //key derivation fuction works fine.
    unsigned char kdfResult[32];
    pbkdf2((char *)key, (const unsigned char *)iv, strlen((const char *)iv), 100000, 32, kdfResult);

    int ivbytelen;
    unsigned char *ivByteArray = hex_string_to_bytes(iv, &ivbytelen);

    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;
    int result;

    if (!(ctx = EVP_CIPHER_CTX_new()))
    {
        fprintf(stderr, "Error creating EVP_CIPHER_CTX.\n");
        return 0;
    }

    if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
    {
        fprintf(stderr, "Error setting cipher type and mode.\n");
        EVP_CIPHER_CTX_free(ctx);
        return 0;
    }

    int ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, IV_SIZE, NULL);
    if (ret != 1) {
        EVP_CIPHER_CTX_free(ctx);
        fprintf(stderr, "Error setting ivg.\n");
        return 0;
    }

    if (1 != EVP_DecryptInit_ex(ctx, NULL, NULL, kdfResult, ivByteArray))
    {
        fprintf(stderr, "Error setting key and IV.\n");
        EVP_CIPHER_CTX_free(ctx);
        return 0;
    }

    EVP_DecryptUpdate(ctx, NULL, &len, NULL, 16);

    if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
    {
        fprintf(stderr, "Error decrypting ciphertext.\n");
        EVP_CIPHER_CTX_free(ctx);
        return 0;
    }

    //Once control reaches at this point, segmentation fault occurs

    if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, strlen(tag), tag))
    {
        fprintf(stderr, "Error setting authentication tag.\n");
        EVP_CIPHER_CTX_free(ctx);
        return 0;
    }

    plaintext_len = len;

    result = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
    EVP_CIPHER_CTX_free(ctx);

    if (result > 0)
    {
        plaintext_len += len;
        return plaintext_len;
    }
    else
    {
        fprintf(stderr, "Error finalizing decryption.\n");
        return -1;
    }
}

for setting tag length, i tried strlen and passing size manually. Nothing worked.

EDIT:

Encryption data used in hex format (ofcourse I formatted it into byte array before passing it for AES decryption).

ciphertext: "71cba06a6c1918a2d1712d4317211efed7f1c8120109c0931a081194ba18c696b6daeaea71fa3d354dcfca4794c7bde8ff269c42178754796b9b2b4c0ba2682d"

tag: "3decb85890fff4aa1feae4c7abbe570f"

iv: "5b7733889cea3f33af2d3819"

key: "b1ea1f8a27990fdf7053935db78e923d751db61217fda864c14faf1e34d01159"

As was requested, here's the pbkdf2() implementation:

void pbkdf2(const char *password, const unsigned char *salt, int salt_len, int iterations, int key_len, unsigned char *derived_key)
{
    if (PKCS5_PBKDF2_HMAC(password, strlen(password), salt, salt_len, iterations, EVP_sha256(), key_len, derived_key) != 1)
    {
        fprintf(stderr, "Failed to derive key\n");
    }
}

no comments (yet)
sorted by: hot top controversial new old
there doesn't seem to be anything here