A test showing a flipped bit in a file encrypted on two different machines

ChaCha ASM Test

I have observed that the ChaCha cipher may have very rarely divergent code paths for AVX vs. SSE.

I have seen this in earlier CryptoPP releases but ran my tests using the latest 8.5.0 release.

I have found on multiple occasions that ChaCha encrypted files decrypt with usually a single flipped bit on other machines. The file will decrypt as expected on the machine that encrypted it.

We run sha256 checks on the decrypted files on both ends. The hashes mismatch as expected when a bit is flipped.

After seeing this behavior in a production environment, I wrote an isolated fuzz test to confirm with garbage files that I could reproduce the behavior.

Included In This Test

Included are:

  • the Visual Studio solution and project used to build the test executable
  • the single source file src/main.cpp
  • a reproducible example in the example/ directory:
    • a minimal built executable cryptopp-chacha-asm-test.exe with hard-coded key, nonce, and filepath
    • the input file which causes the behavior run_459_file_76.bin
    • sample encrypted file with AVX run_459_file_76_avx.bin.enc
    • sample encrypted file without AVX run_459_file_76_no_avx.bin.enc

Included in main.cpp are:

  • a very minimal test case with a specific key and nonce which produce differing results on (presumably) AVX vs SSE paths
  • the source code that was used for the original fuzz test to find a key/nonce/file combo that gives inconsistent behavior, see the RunFuzzTest() function.

When run from Visual Studio the process will use the run/ directory as its working directory.

Build Details

Cryptopp was built as a static library, x64 multi-threaded debug (\MTd) using Visual Studio 2019 v16.10.0, on Windows 10 Pro v10.0.19043, using the .sln file provided with the source code.

Machines Tested

Both machines are running Windows 10 Pro v10.0.19043.

CPUs on each machine:

The 3700X supports AVX, the i7-990X does not.

Testing Method

The fuzz test in the source code was run on both machines described above until an encrypted sha mismatch was found.

Out of about ~50GB worth of 1MB files which were created and then encrypted on two different machines, only one key + nonce + file combination produced a flipped-bit file.

Reproduction

The example/ directory contains a ready-to-run executable. Or, you can build the source yourself using the provided Visual Studio solution. You will need to put a static x64 \MTd cryptlib.lib in the libs/debug/ directory.

The original fuzz test code is commented out. One key/nonce/file combination which produce the flipped bit is hard-coded into main().

The reproducing combo is:

  • file run_459_file_76.bin (from fuzz test run 459, file 76)
  • hex-encoded key D5B9750A22880B92F1A47BE26CB594F166903B5FC1D79EB99F384AAA356B78D9
  • hex-encoded nonce 3A205D07536CD3CC

The test will:

  • calculate the sha256 hash of run_459_file_76.bin
  • encrypt that file to run_459_file_76.bin.enc
  • calculate the sha256 hash of the encrypted file
  • print the original sha256 and the encrypted sha256
  • exit

The encrypted files on each machine differ by a single bit at 0x1EBB4.

The encrypted sha from an AVX-capable CPU is 6fbee484ee64a2ab02235ddf29ca0b61ee3b811d227c2729836d3bd6161c9b18.

The encrypted sha on non-AVX-capable CPU is 8f16077454f8477594cad4304126b0a6f30c8c4d2536e2441fffd320656e1df1.

If avx is disabled in CryptoPP using CRYPTOPP_DISABLE_AVX and CRYPTOPP_DISABLE_AVX2, the resulting encrypted file's sha256 matches on both machines (8f16...). You can replace libs/debug/cryptlib.lib with libs/debug/cryptlib-no-avx.lib to see the encrypted hash change on an AVX-capable machine.

Similar Resources

Upp11 - C++11 lightweight single header unit test framework

upp11 Lightweight C++11 single header unit test framework To use framework: Copy upp11.h in you project dir. Create unit test source files or modify e

Apr 4, 2019

Project basicly find the test that fails some code.

Stress Test project Overview many and many times in competitve programming when you have a solution got WA(wrong answer) and you do not know why and c

Feb 15, 2022

A modern, C++11-native, single-file header-only, tiny framework for unit-tests, TDD and BDD (includes C++98 variant)

lest – lest errors escape testing This tiny C++11 test framework is based on ideas and examples by Kevlin Henney [1,2] and on ideas found in the CATCH

Dec 28, 2022

GCC/gcov code coverage data extraction from the actual embedded system, without requiring a file system, or an operating system, or standard C libraries.

GCC/gcov code coverage data extraction from the actual embedded system, without requiring a file system, or an operating system, or standard C libraries.

Dec 23, 2022

Feature-rich C99 library for memory scanning purposes, designed for Windows running machines, meant to work on both 32-bit and 64-bit portable executables. Has a modern C++ wrapper.

memscan Feature-rich C99 library for memory scanning purposes, designed for Windows running machines, meant to work on both 32-bit and 64-bit portable

Oct 2, 2022

High performance, easy-to-use, and scalable machine learning (ML) package, including linear model (LR), factorization machines (FM), and field-aware factorization machines (FFM) for Python and CLI interface.

High performance, easy-to-use, and scalable machine learning (ML) package, including linear model (LR), factorization machines (FM), and field-aware factorization machines (FFM) for Python and CLI interface.

What is xLearn? xLearn is a high performance, easy-to-use, and scalable machine learning package that contains linear model (LR), factorization machin

Dec 23, 2022

Distributed, Encrypted, Fractured File System - A custom distributed file system written in C with FUSE

A custom FUSE-based filesystem that distributes encrypted shards of data across machines on a local network, allowing those files to be accessible from any machine.

Nov 2, 2022

This PoC uses two diferent technics for stealing the primary token from all running processes, showing that is possible to impersonate and use whatever token present at any process

This PoC uses two diferent technics for stealing  the primary token from all running processes, showing that is possible to impersonate and use whatever token present at any process

StealAllTokens This PoC uses two diferent technics for stealing the primary token from all running processes, showing that is possible to impersonate

Dec 13, 2022

A demonstration of various different techniques for implementing 'threaded code,' a technique used in Forth and in virtual machines like the JVM.

Threaded code is a technique used in the implementation of virtual machines (VMs). It avoids the overhead of calling subroutines repeatedly by 'thread

Nov 4, 2022

nanoc is a tiny subset of C and a tiny compiler that targets 32-bit x86 machines.

nanoc is a tiny subset of C and a tiny compiler that targets 32-bit x86 machines. Tiny? The only types are: int (32-bit signed integer) char (8-

Nov 28, 2022

Two programs to find the LCM of two positive integers.

LCM-finders LCM-finders? LCM-finders is the repo for my LCM finder projects. I made this program in two similar languages. 🛑 Note: Two languages mean

Apr 15, 2022

Two mice, two cursors

Mouse multiplexer This is Arduino code that makes it possible to have two mouse cursors when connecting two USB mice to the same machine. It works on

Dec 13, 2022

A simple two-axis gimbal built using two servo motors, an mpu6050 gyro and accelerometer sensor, and an Arduino (Uno)

A simple two-axis gimbal built using two servo motors, an mpu6050 gyro and accelerometer sensor, and an Arduino (Uno)

Makeshift Gimbal Project A simple two-axis gimbal built using two servo motors, an mpu6050 gyro and accelerometer sensor, and an Arduino (Uno). A shor

Jun 17, 2022

CS 244B project to use a public blockchain as a two-phase commit coordinator to securely commit an atomic transaction across any two systems of a database.

blockchain-2pc CS 244B project to use a public blockchain as a two-phase commit coordinator to securely commit an atomic transaction across any two sy

Jun 13, 2022

Explore building a hash table with two different hash functions that balances chain length

hash-duo Explore building a hash table with two different hash functions that balances chain length. There is a really cool article called Don't Throw

May 7, 2022

This is a beginner-friendly project aiming to build a problem-set on different data structures and algorithms in different programming languages.

DSAready Overview This is a beginner-friendly project that aims to create a problem-set for various Data Structures and Algorithms. Being a programmer

Aug 17, 2022

Different Example Programs from different programming languages

Example Programs Don't repeat the same program again. Code Refactoring and Code Cleanup are accepted Name the File According to the Program written in

Dec 7, 2022

Shows different icons for 64 and 32-bit DLLs. Register with RegSvr32 to install

DllIconHandler This project demonstrates how to create a Shell Icon Handler, that is loaded by Explorer.exe. An icon handler can show different icons

Dec 11, 2022

Implementations of FizzBuzz test, with different optimisations

fizzbuzz Optimisation of classic FizzBuzz test. supernaive The least efficient implementation, with 3 ifs and two printfs per number. It is so ineffic

Oct 25, 2022
proftest is a C application for testing the quality of different operating system APIs for profiling.

proftest is a C application for testing the quality of different operating system APIs for profiling.

Jul 23, 2021
A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD - using C++11, C++14, C++17 and later (or C++03 on the Catch1.x branch)
A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD - using C++11, C++14, C++17 and later (or C++03 on the Catch1.x branch)

Catch2 v3 is being developed! You are on the devel branch, where the next major version, v3, of Catch2 is being developed. As it is a significant rewo

Jan 9, 2023
A dynamic mock tool for C/C++ unit test on Linux&MacOS X86_64

lmock 接口 替换一个函数,修改机器指令,用新函数替换旧函数,支持全局函数(包括第三方和系统函数)、成员函数(包括静态和虚函数)

Dec 21, 2022
PlatformIO + BL602 Bouffalo Arduino Core Test
 PlatformIO + BL602 Bouffalo Arduino Core Test

PlatformIO + BL602 Bouffalo Arduino Core Test Description Uses A custom extension of the PlatformIO SiFive Platform (https://github.com/maxgerhardt/pl

Nov 25, 2022
A tool to test if a shared library is dlopen'ble

A tool to test if a shared library is dlopen'ble

Oct 17, 2021
End to end test framework designed for Juce applications

JUCE End to End test framework What is it? This package provides a mechanism to end-to-end test a JUCE application Prerequisites CMake. Must be 3.18 o

Jan 6, 2023
Various Framework to do Unit Test in C++
Various Framework to do Unit Test in C++

Unit Test in C++ There are many frameworks to performs unit test in C++, we will present the most popular ones and show how to use them. The testing f

Nov 18, 2021
An area to test reading in ATLAS xAOD format and writing out to Parquet

xaod_to_parquet An area to test reading in ATLAS xAOD format and writing out to Parquet Getting the Code Clone the repository with the --recursive fla

Nov 19, 2021
Handy C++ test framework

C++ Voyager Test Framework Voyager is a simple and handy C++ Unit Test framework. It is designed to be beautiful and expressive both. Try it to feel i

Mar 16, 2022
Network utility tool which enables to prototype or test network things.

netsck netsck is a network utility tool which is developed to prototype or test network things. It provides a shell inside which runs javascript engin

May 29, 2022