kokke / tiny-AES-c

Small portable AES128/192/256 in C
The Unlicense
4.3k stars 1.3k forks source link

Different values in x64 and x32 #221

Closed wiresnchains closed 1 year ago

wiresnchains commented 1 year ago

AES256 Encryption returns two different values when compiling in x32 and x64

    /*
    * This function returns a cipher that is already converted to hex
    */
    std::string Aes256_Encrypt(std::string plainText, std::string key) {
        if (key.length() != 32) {
            DebugConsole.Log("AES256_KEY must be 32 bytes long");
            return std::string();
        }

        struct AES_ctx ctx;
        AES_init_ctx(&ctx, reinterpret_cast<const uint8_t*>(key.c_str()));

        std::string paddedText = plainText;
        while (paddedText.size() % AES_BLOCKLEN != 0)
            paddedText += '\0';

        AES_CBC_encrypt_buffer(&ctx, reinterpret_cast<uint8_t*>(&paddedText[0]), paddedText.size());

        return Utils::BinaryToHex(paddedText);
    }

    std::string Aes256_Decrypt(std::string cipherHex, std::string key) {
        if (key.length() != 32) {
            DebugConsole.Log("AES256_KEY must be 32 bytes long");
            return std::string();
        }

        std::string cipherBinary = Utils::HexToBinary(cipherHex);

        struct AES_ctx ctx;
        AES_init_ctx(&ctx, reinterpret_cast<const uint8_t*>(key.c_str()));

        std::string decryptedText = cipherBinary;
        AES_CBC_decrypt_buffer(&ctx, reinterpret_cast<uint8_t*>(&decryptedText[0]), decryptedText.size());

        size_t paddingSize = 0;
        for (size_t i = decryptedText.size() - 1; i >= 0; i--) {
            if (decryptedText[i] == '\0')
                paddingSize++;
            else
                break;
        }
        decryptedText.resize(decryptedText.size() - paddingSize);

        return decryptedText;
    }
kokke commented 1 year ago

Hi @flowxrc and thanks for your interest in this project :)

This looks like a usage error to me.

AES CBC needs both a key and an IV.

The code shown does not set the IV, which means you are encrypting and decrypting with an uninitialized IV - that’s probably why you get different results.

Try setting the IV, e.g. by calling AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv) instead of AES_init_ctx(…)