Skip to content

The method returns inconsistent expected results after running it about 10,000 times #108811

@czd890

Description

@czd890

Description

I use fixed parameters to loop the test. After running about 10,000 times, the returned decryptedByteCount will change from 9 to 1. This happens widely on multiple net8 versions of Linux and Windows.

the code should use release to build. If it is debug mode, this bug cannot be reproduced.

Does this seem to be related to the JIT not optimizing correctly?

        public int Decrypt(byte[] buffer, string key, string iv, out byte[] decryptedData)
        {
            int decryptedByteCount = 0;
            decryptedData = new byte[buffer.Length];

            using var aes = Aes.Create();
            aes.Mode = CipherMode.CBC;
            aes.KeySize = 16;
            aes.Padding = PaddingMode.Zeros;
            
            var instPwdArray = Encoding.ASCII.GetBytes(key);
            var instSaltArray = Encoding.ASCII.GetBytes(iv);

            using (var decryptor = aes.CreateDecryptor(instPwdArray, instSaltArray))
            {
                using (var memoryStream = new MemoryStream(buffer))
                {
                    using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        int read;
                        do
                        {
                            read = cryptoStream.Read(
                                decryptedData,
                                decryptedByteCount,
                                decryptedData.Length - decryptedByteCount);
                            decryptedByteCount += read;
                        } while (read != 0);
                    }
                }
            }

            // Found the accurate length of decrypted data
            while (decryptedData[decryptedByteCount - 1] == 0 && decryptedByteCount > 0)
            {
                decryptedByteCount--;
            }

            return decryptedByteCount;
        }

test parameters

var hex = "3AE46205A50ED00E7612A91692552B7A";
var key = "abcdef1234567890";
var iv = "abcdef1234567890";
Decrypt(convert_hex_to_bytes(hex),key,iv, out decrptorBytes)

If I modify the code to the following two methods, this problem can be fixed.

method1: using(){} struct for aes

            ......
            using (var aes = Aes.Create())
            {
                aes.Mode = CipherMode.CBC;
                ......
            }
            while (decryptedData[decryptedByteCount - 1] == 0 && decryptedByteCount > 0)
            ......

method2: add MemoryBarrier.

            ......
            Thread.MemoryBarrier();
            while (decryptedData[decryptedByteCount - 1] == 0 && decryptedByteCount > 0)
            ......

Reproduction Steps

Repeat the run more than 10,000 times.

Expected behavior

The results should always be consistent.

Actual behavior

After running it about 10,000 times, it will always return wrong results.

Regression?

has never happened on net6.

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions