// Copyright 2022 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// break-kat corrupts a known-answer-test input in a binary and writes the
// corrupted binary to stdout. This is used to demonstrate that the KATs in the
// binary notice the error.
package main

import (
	"bytes"
	"encoding/hex"
	"flag"
	"fmt"
	"io"
	"os"
	"os/exec"
	"sort"
)

var (
	kats = map[string]string{
		"HMAC-SHA-256":    "dad91293dfcf2a7c8ecd13fe353fa75b",
		"AES-CBC-encrypt": "078609a6c5ac2544699adf682fa377f9be8ab6aef563e8c56a36b84f557fadd3",
		"AES-CBC-decrypt": "347aa5a024b28257b36510be583d4f47adb7bbeedc6005bbbd0d0a9f06bb7b10",
		"AES-GCM-encrypt": "8fcc4099808e75caaff582898848a88d808b55ab4e9370797d940be8cc1d7884",
		"AES-GCM-decrypt": "35f3058f875760ff09d3120f70c4bc9ed7a86872e13452202176f7371ae04faae1dd391920f5d13953d896785994823c",
		"DRBG":            "c4da0740d505f1ee280b95e58c4931ac6de846a0152fbb4a3f174cf4787a4f1a40c2b50babe14aae530be5886d910a27",
		"DRBG-reseed":     "c7161ca36c2309b716e9859bb96c6d49bdc8352103a18cd24ef42ec97ef46bf446eb1a4576c186e9351803763a7912fe",
		"HKDF":            "68678504b9b3add17d5967a1a7bd37993fd8a33ce7303071f39c096d1635b3c9",
		"MLDSA-keygen":    "0c6f387d2ab43387f021b0da816c71f0bc815ef0b16af1124f354c273eedb42fe54a019a",
		"MLDSA-sign":      "f8c725848b39d9d980f02ff7a02419087065e2c80ac4d3d5974931ea7bd664b66e6bf3c7",
		"MLDSA-verify":    "4923cea1293b2400ccc3b19f1e803ed85a0d6e0ba64f35f845f420d848e1858205883fdd",
		"MLKEM-keygen":    "d8c9397c3130d8ecb411a68efcc89a553cb7e6817e0288bd0691609bf5",
		"MLKEM-encap":     "7d9f1cb4ae04d75fa6575ae0e429b573a974b7",
		"MLKEM-decap":     "a3192a8c88fc996d2df9858d2c55363993f0494d7ec0be5a567b8a4243a5745d",
		"SHA-1":           "132fd9bad5c1826263bafbb699f707a5",
		"SHA-256":         "ff3b857da7236a2baa0f396b51522217",
		"SHA-512":         "212512f8d2ad8322781c6c4d69a9daa1",
		"SLHDSA-keygen":   "be6bd7e8e198eaf62d572f13fc79f26f",
		"SLHDSA-sign":     "82d409744d97ae305318469f7b857b91d4e33310b709b550a7c48a46094ec9d4",
		"SLHDSA-verify":   "3fd69193ee9708bdea110ba29f235ff2ec9888d12761f84dc6e3f0d7eb48d05cacf6e87f",
		"TLS10-KDF":       "abc3657b094c7628a0b282996fe75a75f4984fd94d4ecc2fcf53a2c469a3f731",
		"TLS12-KDF":       "c5438ee26fd4acbd259fc91855dc69bf884ee29322fcbfd2966a4623d42ec781",
		"TLS13-KDF":       "024a0d80f357f2499a1244dac26dab66fc13ed85fca71dace146211119525874",
		"RSA-sign":        "d2b56e53306f720d7929d8708bf46f1c22300305582b115bedcac722d8aa5ab2",
		"RSA-verify":      "abe2cbc13d6bd39d48db5334ddbf8d070a93bdcb104e2cc5d0ee486ee295f6b31bda126c41890b98b73e70e6b65d82f95c663121755a90744c8d1c21148a1960be0eca446e9ff497f1345c537ef8119b9a4398e95c5c6de2b1c955905c5299d8ce7a3b6ab76380d9babdd15f610237e1f3f2aa1c1f1e770b62fbb596381b2ebdd77ecef9c90d4c92f7b6b05fed2936285fa94826e62055322a33b6f04c74ce69e5d8d737fb838b79d2d48e3daf71387531882531a95ac964d02ea413bf85952982bbc089527daff5b845c9a0f4d14ef1956d9c3acae882d12da66da0f35794f5ee32232333517db9315232a183b991654dbea41615345c885325926744a53915",
		"ECDSA-sign":      "1e35930be860d0942ca7bbd6f6ded87f157e4de24f81ed4b875c0e018e89a81f",
		"ECDSA-verify":    "6780c5fc70275e2c7061a0e7877bb174deadeb9887027f3fa83654158ba7f50c2d36e5799790bfbe2183d33e96f3c51f6a232f2a24488c8e5f64c37ea2cf0529",
		"Z-computation":   "e7604491269afb5b102d6ea52cb59feb70aede6ce3bfb3e0105485abd861d77b",
		"FFDH":            "a14f8ad36be37b18b8f35864392f150ab7ee22c47e1870052a3f17918274af18aaeaf4cf6aacfde96c9d586eb7ebaff6b03fe3b79a8e2ff9dd6df34caaf2ac70fd3771d026b41a561ee90e4337d0575f8a0bd160c868e7e3cef88aa1d88448b1e4742ba11480a9f8a8b737347c408d74a7d57598c48875629df0c85327a124ddec1ad50cd597a985588434ce19c6f044a1696b5f244b899b7e77d4f6f20213ae8eb15d37eb8e67e6c8bdbc4fd6e17426283da96f23a897b210058c7c70fb126a5bf606dbeb1a6d5cca04184c4e95c2e8a70f50f5c1eabd066bd79c180456316ac02d366eb3b0e7ba82fb70dcbd737ca55734579dd250fffa8e0584be99d32b35",
	}

	listTests = flag.Bool("list-tests", false, "List known test values and exit")
)

func main() {
	flag.Parse()

	if *listTests {
		for _, kat := range sortedKATs() {
			fmt.Println(kat)
		}
		os.Exit(0)
	}

	if flag.NArg() == 0 || flag.NArg() > 2 || (flag.NArg() == 2 && kats[flag.Arg(1)] == "") {
		fmt.Fprintln(os.Stderr, "Usage: break-kat <binary path> <test to break> > output")
		fmt.Fprintln(os.Stderr, "       break-kat <binary path>  (to run all tests)")
		fmt.Fprintln(os.Stderr, "Possible values for <test to break>:")
		for _, kat := range sortedKATs() {
			fmt.Fprintln(os.Stderr, " ", kat)
		}
		os.Exit(1)
	}

	inPath := flag.Arg(0)
	binaryContents, err := os.ReadFile(inPath)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(2)
	}

	if flag.NArg() == 2 {
		breakBinary(binaryContents, flag.Arg(1), os.Stdout)
		return
	}

	for _, test := range sortedKATs() {
		fmt.Printf("\n### Running test for %q\n\n", test)

		const outFile = "test_fips_broken"
		output, err := os.OpenFile(outFile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0755)
		if err != nil {
			panic(err)
		}
		breakBinary(binaryContents, test, output)
		output.Close()

		cmd := exec.Command("./" + outFile)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stdout
		if err := cmd.Run(); err != nil {
			fmt.Printf("(task failed with: %s)\n", err)
		} else {
			fmt.Println("(task exec successful)")
		}
		os.Remove(outFile)
	}

	for _, test := range []string{"ECDSA_PWCT", "RSA_PWCT", "MLDSA_PWCT", "MLKEM_PWCT", "SLHDSA_PWCT"} {
		fmt.Printf("\n### Running test for %q\n\n", test)

		cmd := exec.Command("./" + inPath)
		cmd.Env = append(cmd.Environ(), "BORINGSSL_FIPS_BREAK_TEST="+test)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stdout
		if err := cmd.Run(); err != nil {
			fmt.Printf("(task failed with: %s)\n", err)
		} else {
			fmt.Println("(task exec successful)")
		}
	}
}

func breakBinary(binaryContents []byte, test string, output io.Writer) {
	testInputValue, err := hex.DecodeString(kats[test])
	if err != nil {
		panic("invalid KAT data: " + err.Error())
	}

	brokenContents := make([]byte, len(binaryContents))
	copy(brokenContents, binaryContents)

	found := false
	for {
		i := bytes.Index(brokenContents, testInputValue)
		if i < 0 {
			break
		}
		found = true

		// Zero out the entire value because the compiler may produce code
		// where parts of the value are embedded in the instructions.
		// See crbug.com/399818730
		for j := range testInputValue {
			brokenContents[i+j] = 0
		}
	}

	if !found {
		fmt.Fprintln(os.Stderr, "Expected test input value for", test, "was not found in binary.")
		os.Exit(3)
	}

	if n, err := output.Write(brokenContents); err != nil || n != len(brokenContents) {
		fmt.Fprintf(os.Stderr, "Bad write: %s (%d vs expected %d)\n", err, n, len(brokenContents))
		os.Exit(1)
	}
}

func sortedKATs() []string {
	var ret []string
	for kat := range kats {
		ret = append(ret, kat)
	}
	sort.Strings(ret)
	return ret
}
