diff -Nru aeskeyfind-1.0/debian/changelog aeskeyfind-1.0/debian/changelog --- aeskeyfind-1.0/debian/changelog 2021-01-30 21:13:18.000000000 +0000 +++ aeskeyfind-1.0/debian/changelog 2021-06-15 20:43:59.000000000 +0100 @@ -1,3 +1,32 @@ +aeskeyfind (1:1.0-11) unstable; urgency=medium + + * Restrict the architectures we build for to amd64 and i386 (#989179) + Our approaches at fixing #989179 all failed to fix the integration tests + for the other archs, which means there are more problems afecting those + archs and thus we can't ensure that the package meets the Debian standards + for our users. + + -- Samuel Henrique Tue, 15 Jun 2021 20:43:59 +0100 + +aeskeyfind (1:1.0-10) unstable; urgency=medium + + * d/p/40_fix-undefined-left-shift.patch: New patch to fix #989179 at the + root cause (thanks to Adrian Bunk for the patch and Jan Gru for reporting + the issue) + + -- Samuel Henrique Mon, 14 Jun 2021 20:47:05 +0100 + +aeskeyfind (1:1.0-9) unstable; urgency=medium + + [ Samuel Henrique ] + * Removes -O4 optimization to fix bug caused by code with undefined behavior + (closes: #989179, LP: #1838334) + + [ Jan Gru ] + * Add autopkgtests + + -- Samuel Henrique Wed, 09 Jun 2021 23:53:43 +0100 + aeskeyfind (1:1.0-8) unstable; urgency=medium * Re-import upstream tarball, this time with its signature diff -Nru aeskeyfind-1.0/debian/control aeskeyfind-1.0/debian/control --- aeskeyfind-1.0/debian/control 2021-01-30 21:13:18.000000000 +0000 +++ aeskeyfind-1.0/debian/control 2021-06-15 20:43:59.000000000 +0100 @@ -11,7 +11,7 @@ Vcs-Git: https://salsa.debian.org/pkg-security-team/aeskeyfind.git Package: aeskeyfind -Architecture: any +Architecture: amd64 i386 Depends: ${misc:Depends}, ${shlibs:Depends} Description: tool for locating AES keys in a captured memory image This program illustrates automatic techniques for locating 128-bit and diff -Nru aeskeyfind-1.0/debian/patches/40_fix-undefined-left-shift.patch aeskeyfind-1.0/debian/patches/40_fix-undefined-left-shift.patch --- aeskeyfind-1.0/debian/patches/40_fix-undefined-left-shift.patch 1970-01-01 01:00:00.000000000 +0100 +++ aeskeyfind-1.0/debian/patches/40_fix-undefined-left-shift.patch 2021-06-15 20:43:59.000000000 +0100 @@ -0,0 +1,17 @@ +Description: Fix bug caused by code with undefined behavior (left shift with negative exponent) +Bug-Debian: https://bugs.debian.org/989179 +Bug-Ubuntu: https://bugs.launchpad.net/debian/+source/aeskeyfind/+bug/1838334 +Author: Adrian Bunk +Index: aeskeyfind/aes.h +=================================================================== +--- aeskeyfind.orig/aes.h ++++ aeskeyfind/aes.h +@@ -12,7 +12,7 @@ extern uint8_t rcon[255]; + static inline uint32_t key_core(uint32_t k, int i) { + uint32_t t = 0; + for (int j=0; j<4; j++) +- t = set_byte(t, (j-1)%4, sbox[get_byte(k,j)]); ++ t = set_byte(t, (j-1+4)%4, sbox[get_byte(k,j)]); + return set_byte(t, 0, get_byte(t,0) ^ rcon[i]); + } + diff -Nru aeskeyfind-1.0/debian/patches/series aeskeyfind-1.0/debian/patches/series --- aeskeyfind-1.0/debian/patches/series 2021-01-30 21:13:18.000000000 +0000 +++ aeskeyfind-1.0/debian/patches/series 2021-06-15 20:43:59.000000000 +0100 @@ -1,3 +1,4 @@ 10_add-GCC-hardening.patch 20_sbox-size.patch 30_big-files-support.patch +40_fix-undefined-left-shift.patch diff -Nru aeskeyfind-1.0/debian/tests/control aeskeyfind-1.0/debian/tests/control --- aeskeyfind-1.0/debian/tests/control 1970-01-01 01:00:00.000000000 +0100 +++ aeskeyfind-1.0/debian/tests/control 2021-06-15 20:43:59.000000000 +0100 @@ -0,0 +1,3 @@ +Tests: smoke, recover-aes-128, recover-aes-256 +Depends: aeskeyfind, gdb, procps, python3-pycryptodome +Restrictions: allow-stderr diff -Nru aeskeyfind-1.0/debian/tests/helpers/gen_aes_dump.sh aeskeyfind-1.0/debian/tests/helpers/gen_aes_dump.sh --- aeskeyfind-1.0/debian/tests/helpers/gen_aes_dump.sh 1970-01-01 01:00:00.000000000 +0100 +++ aeskeyfind-1.0/debian/tests/helpers/gen_aes_dump.sh 2021-06-15 20:43:59.000000000 +0100 @@ -0,0 +1,24 @@ +#!/bin/sh + +# $1 = key specification as multiline string +# $2 = dump file to store process memory + +GEN_SCRIPT="debian/tests/helpers/gen_aes_key.py" + +# Spawns subshell running the key generation script +(echo "$1" | python3 "${GEN_SCRIPT}") & + +# Sleep to retrieve the PID of the child process reliably +sleep .3 + +PID=$(pgrep -f "python3 ${GEN_SCRIPT}") + +#gcore -o"$3" ${PID} > /dev/null 2>&1 +# Dumps memory +grep rw-p /proc/${PID}/maps | sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1\t\2/p' \ +| while read start stop; + do gdb --batch --pid ${PID} -ex "append memory $2 0x$start 0x$stop" > /dev/null 2>&1; +done + +# Terminates key generation script +kill -9 ${PID} diff -Nru aeskeyfind-1.0/debian/tests/helpers/gen_aes_key.py aeskeyfind-1.0/debian/tests/helpers/gen_aes_key.py --- aeskeyfind-1.0/debian/tests/helpers/gen_aes_key.py 1970-01-01 01:00:00.000000000 +0100 +++ aeskeyfind-1.0/debian/tests/helpers/gen_aes_key.py 2021-06-15 20:43:59.000000000 +0100 @@ -0,0 +1,83 @@ +import argparse +import time +import sys + +# Use pycryptodome's AES library +# See https://pycryptodome.readthedocs.io/en/latest/src/cipher/aes.html +from Cryptodome.Cipher import AES + + +KEY_ELEMENTS = ["KEY", "IV"] + + +def main(infile=None): + lines = [] + + # Checks, if interactive session or reading from a file + if sys.stdin.isatty(): + if infile.name != "": + # Reads specification file + with open(infile.name, "r") as f: + lines = f.readlines() + else: + exit("Supply data via STDIN or file!") + else: + lines = sys.stdin.readlines() + + construct_key(lines) + + +def construct_key(lines): + keymaterial = {} + + # Populates keymaterial + for line in lines: + # Strips of \n + line = line.strip() + + # Tokenizes line + parts = line.split("=", 1) + name = parts[0] + val = parts[-1] + + # Stores line in dict + if name in KEY_ELEMENTS: + keymaterial[name] = bytes(val, "utf-8") + + # Performs checks regarding well-formed key material + if "KEY" not in keymaterial: + exit("Key specification is incomplete.") + elif ( + len(keymaterial["KEY"]) != 16 + and len(keymaterial["KEY"]) != 24 + and len(keymaterial["KEY"]) != 32 + ): + exit("Unsupported key length: " + str(len(keymaterial["KEY"]))) + + # Constructs AES key by given parameters + # Assign it to a variable to keep it in memory + if "IV" in keymaterial.keys(): + aes_key = AES.new( + keymaterial["KEY"], AES.MODE_CBC, iv=keymaterial["IV"] + ) # noqa: F841 + else: + aes_key = AES.new(keymaterial["KEY"], AES.MODE_CBC) # noqa: F841 + + while True: + time.sleep(1) + + +def parse_args(): + parser = argparse.ArgumentParser( + description="Construct an AES key according to specified key material and sleep forever." # noqa: E501 + ) + parser.add_argument( + "keyspec", nargs="?", type=argparse.FileType("r"), default=sys.stdin + ) + args = parser.parse_args() + return args + + +if __name__ == "__main__": + args = parse_args() + construct_key(args.keyspec) diff -Nru aeskeyfind-1.0/debian/tests/helpers/test_aes_extraction.sh aeskeyfind-1.0/debian/tests/helpers/test_aes_extraction.sh --- aeskeyfind-1.0/debian/tests/helpers/test_aes_extraction.sh 1970-01-01 01:00:00.000000000 +0100 +++ aeskeyfind-1.0/debian/tests/helpers/test_aes_extraction.sh 2021-06-15 20:43:59.000000000 +0100 @@ -0,0 +1,62 @@ +#!/bin/sh + +################################################################ +# Usage: # +# test_aes_extraction # +# # +# Example: # +# test_aes_extraction "DebianDebianDebi" "aaaabbbbccccdddd"# +# # +# # +# Note: Use either 16, 24 or 32 byte long keys and IVs. # +################################################################ + +# Exit on first failure +set -e + +# Converts a ASCII string to its hex representation +str2hex() { + echo "$1" | sed 's/\(.\)/\1\n/g' | \ + xargs -I {} printf "%x" "'{}" +} + +# Path of the script, which is used to create AES keys +# and dump the memory of the process performing AES construction +GEN_DUMP="debian/tests/helpers/gen_aes_dump.sh" + + +# Defines the AES key-material, used to generate the dump +# and to serve as target value for the extraction +if [ -z "$1" ] +then + echo "No key provided!" + exit 1 +fi + +KEY="$1" + +# Combination of the parameters to feed into the script +if [ -z "$2" ] +then + KEYSPEC="KEY=$1" +else + KEYSPEC="KEY=$1\nIV=$2" +fi + +# Memory dump to process +DMP="${AUTOPKGTEST_TMP}/aes.dmp" + +# Dump memory of process, which generates key material +sh ${GEN_DUMP} "$KEYSPEC" "$DMP" + +# Previous bug fixed in the past which might trigger again: +# https://bugs.debian.org/989179 +ACTUAL=$(aeskeyfind "${DMP}") + +# Checks, compare actual result with target values +echo "${ACTUAL}" | grep -q $(str2hex "${KEY}") + +# Clean up +rm ${DMP} + +exit 0 diff -Nru aeskeyfind-1.0/debian/tests/recover-aes-128 aeskeyfind-1.0/debian/tests/recover-aes-128 --- aeskeyfind-1.0/debian/tests/recover-aes-128 1970-01-01 01:00:00.000000000 +0100 +++ aeskeyfind-1.0/debian/tests/recover-aes-128 2021-06-15 20:43:59.000000000 +0100 @@ -0,0 +1,13 @@ +#!/bin/sh + +set -e + +# Helper script to use for dumping and key extraction +TEST_SCRIPT="debian/tests/helpers/test_aes_extraction.sh" + +# Defines the AES key-material +KEY="DebianDebianDebi" + +# Dump memory of process, which generates key material +sh ${TEST_SCRIPT} "$KEY" + diff -Nru aeskeyfind-1.0/debian/tests/recover-aes-256 aeskeyfind-1.0/debian/tests/recover-aes-256 --- aeskeyfind-1.0/debian/tests/recover-aes-256 1970-01-01 01:00:00.000000000 +0100 +++ aeskeyfind-1.0/debian/tests/recover-aes-256 2021-06-15 20:43:59.000000000 +0100 @@ -0,0 +1,13 @@ +#!/bin/sh + +set -e + +# Helper script to use for dumping and key extraction +TEST_SCRIPT="debian/tests/helpers/test_aes_extraction.sh" + +# Defines the AES key-material +KEY="DebianDebianDebianDebianDebianDe" + +# Dump memory of process, which generates key material +sh ${TEST_SCRIPT} "$KEY" + diff -Nru aeskeyfind-1.0/debian/tests/smoke aeskeyfind-1.0/debian/tests/smoke --- aeskeyfind-1.0/debian/tests/smoke 1970-01-01 01:00:00.000000000 +0100 +++ aeskeyfind-1.0/debian/tests/smoke 2021-06-15 20:43:59.000000000 +0100 @@ -0,0 +1,17 @@ +#!/bin/sh + +# Exit on failure immediately +set -e + +# Specifies testfile containing 1K of zeros +DMP="${AUTOPKGTEST_TMP}/zeros.dmp" +truncate -s 1K ${DMP} + +# Run aeskeyfind with zero-filled dump +# This is needed, since aeskeyfind returns 1 upon calling without parameters +aeskeyfind ${DMP} + +# Clean up +rm ${DMP} + +exit 0