// Copyright (c) 2017, Google Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

// The make_cavp utility generates cipher_test input files from NIST CAVP Known
// Answer Test response (.rsp) files.
package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strings"
)

var (
	cipher             = flag.String("cipher", "", "The name of the cipher/mode (supported: aes, tdes, gcm). Required.")
	cmdLineLabelStr    = flag.String("extra-labels", "", "Comma-separated list of additional label pairs to add (e.g. 'Cipher=AES-128-CBC,Operation=ENCRYPT')")
	swapIVAndPlaintext = flag.Bool("swap-iv-plaintext", false, "When processing CBC vector files for CTR mode, swap IV and plaintext.")
)

type kvPair struct {
	key, value string
}

// Test generates a FileTest file from a CAVP response file.
type Test struct {
	translations map[kvPair]kvPair
	transform    func(k, v string) []kvPair
	defaults     map[string]string
	// kvDelim is the rune that delimits key-value pairs throughout the file ('=' or ':').
	kvDelim rune
}

func (t *Test) parseKeyValue(s string) (key, value string) {
	if t.kvDelim == 0 {
		i := strings.IndexAny(s, "=:")
		if i != -1 {
			t.kvDelim = rune(s[i])
		}
	}
	if i := strings.IndexRune(s, t.kvDelim); t.kvDelim != 0 && i != -1 {
		key, value = s[:i], s[i+1:]
		if trimmed := strings.TrimSpace(value); len(trimmed) != 0 {
			value = trimmed
		} else {
			value = " "
		}
	} else {
		key = s
	}
	return strings.TrimSpace(key), value
}

func (t *Test) translateKeyValue(key, value string) (string, string) {
	if kv, ok := t.translations[kvPair{key, ""}]; ok {
		if len(kv.value) == 0 && len(value) != 0 {
			return kv.key, value
		}
		return kv.key, kv.value
	}
	if kv, ok := t.translations[kvPair{key, value}]; ok {
		return kv.key, kv.value
	}
	return key, value
}

func printKeyValue(key, value string) {
	if len(value) == 0 {
		fmt.Println(key)
	} else {
		// Omit the value if it is " ", i.e. print "key: ", not "key:  ".
		value = strings.TrimSpace(value)
		fmt.Printf("%s: %s\n", key, value)
	}
}

func (t *Test) generate(r io.Reader, cmdLineLabelStr string) {
	s := bufio.NewScanner(r)

	// Label blocks consist of lines of the form "[key]" or "[key =
	// value]". |labels| holds keys and values of the most recent block
	// of labels.
	var labels map[string]string

	// Auxiliary labels passed as a flag.
	cmdLineLabels := make(map[string]string)
	if len(cmdLineLabelStr) != 0 {
		pairs := strings.Split(cmdLineLabelStr, ",")
		for _, p := range pairs {
			key, value := t.parseKeyValue(p)
			cmdLineLabels[key] = value
		}
	}

	t.kvDelim = 0 // Reset kvDelim for scanning the file.

	// Whether we are in a test or a label section.
	inLabels := false
	inTest := false

	n := 0
	var currentKv map[string]string
	for s.Scan() {
		n++
		line := s.Text()
		l := strings.TrimSpace(line)
		l = strings.SplitN(l, "#", 2)[0] // Trim trailing comments.

		// Blank line.
		if len(l) == 0 {
			if inTest {
				// Fill in missing defaults at the end of a test case.
				for k, v := range t.defaults {
					if _, ok := currentKv[k]; !ok {
						printKeyValue(k, v)
					}
				}
				fmt.Println()
			}
			inTest = false
			currentKv = make(map[string]string)
			inLabels = false
			continue
		}

		// Label section.
		if l[0] == '[' {
			if l[len(l)-1] != ']' {
				log.Fatalf("line #%d invalid: %q", n, line)
			}
			if !inLabels {
				labels = make(map[string]string)
				inLabels = true
			}

			k, v := t.parseKeyValue(l[1 : len(l)-1])
			k, v = t.translateKeyValue(k, v)
			if len(k) != 0 {
				labels[k] = v
			}

			continue
		}

		// Repeat the label map at the beginning of each test section.
		if !inTest {
			inTest = true
			for k, v := range cmdLineLabels {
				printKeyValue(k, v)
				currentKv[k] = v
			}
			for k, v := range labels {
				printKeyValue(k, v)
				currentKv[k] = v
			}
		}

		// Look up translation and apply transformation (if any).
		k, v := t.parseKeyValue(l)
		k, v = t.translateKeyValue(k, v)
		kvPairs := []kvPair{{k, v}}
		if t.transform != nil {
			kvPairs = t.transform(k, v)
		}

		for _, kv := range kvPairs {
			k, v := kv.key, kv.value
			if *cipher == "tdes" && k == "Key" {
				v += v + v // Key1=Key2=Key3
			}
			if len(k) != 0 {
				printKeyValue(k, v)
				currentKv[k] = v
			}
		}
	}
}

func usage() {
	fmt.Fprintln(os.Stderr, "usage: make_cavp <file 1> [<file 2> ...]")
	flag.PrintDefaults()
}

func maybeSwapIVAndPlaintext(k, v string) []kvPair {
	if *swapIVAndPlaintext {
		if k == "Plaintext" {
			return []kvPair{{"IV", v}}
		} else if k == "IV" {
			return []kvPair{{"Plaintext", v}}
		}
	}
	return []kvPair{{k, v}}
}

// Test generator for different values of the -cipher flag.
var testMap = map[string]Test{
	// Generate cipher_test input file from AESVS .rsp file.
	"aes": Test{
		translations: map[kvPair]kvPair{
			{"ENCRYPT", ""}:    {"Operation", "ENCRYPT"},
			{"DECRYPT", ""}:    {"Operation", "DECRYPT"},
			{"COUNT", ""}:      {"Count", ""},
			{"KEY", ""}:        {"Key", ""},
			{"PLAINTEXT", ""}:  {"Plaintext", ""},
			{"CIPHERTEXT", ""}: {"Ciphertext", ""},
			{"COUNT", ""}:      {"", ""}, // delete
		},
		transform: maybeSwapIVAndPlaintext,
	},
	// Generate cipher_test input file from TMOVS .rsp file.
	"tdes": Test{
		translations: map[kvPair]kvPair{
			{"ENCRYPT", ""}:    {"Operation", "ENCRYPT"},
			{"DECRYPT", ""}:    {"Operation", "DECRYPT"},
			{"COUNT", ""}:      {"Count", ""},
			{"KEYs", ""}:       {"Key", ""},
			{"PLAINTEXT", ""}:  {"Plaintext", ""},
			{"CIPHERTEXT", ""}: {"Ciphertext", ""},
			{"COUNT", ""}:      {"", ""}, // delete
		},
		transform: maybeSwapIVAndPlaintext,
	},
	// Generate aead_test input file from GCMVS .rsp file.
	"gcm": Test{
		translations: map[kvPair]kvPair{
			{"Keylen", ""}: {"", ""}, // delete
			{"IVlen", ""}:  {"", ""}, // delete
			{"PTlen", ""}:  {"", ""}, // delete
			{"AADlen", ""}: {"", ""}, // delete
			{"Taglen", ""}: {"", ""}, // delete
			{"Count", ""}:  {"", ""}, // delete
			{"Key", ""}:    {"KEY", ""},
			{"IV", ""}:     {"NONCE", ""},
			{"PT", ""}:     {"IN", ""},
			{"AAD", ""}:    {"AD", ""},
			{"Tag", ""}:    {"TAG", ""},
			{"FAIL", ""}:   {"FAILS", " "},
		},
		transform: func(k, v string) []kvPair {
			if k == "FAILS" {
				// FAIL cases only appear in the decrypt rsp files. Skip encryption for
				// these.
				return []kvPair{{"FAILS", " "}, {"NO_SEAL", " "}}
			}
			return []kvPair{{k, v}}
		},
		defaults: map[string]string{
			"IN": " ", // FAIL tests don't have IN
		},
	},
}

func main() {
	flag.Usage = usage
	flag.Parse()

	if len(flag.Args()) == 0 {
		fmt.Fprintf(os.Stderr, "no input files\n\n")
		flag.Usage()
		os.Exit(1)
	}

	test, ok := testMap[*cipher]
	if !ok {
		fmt.Fprintf(os.Stderr, "invalid cipher: %q\n\n", *cipher)
		flag.Usage()
		os.Exit(1)
	}

	args := append([]string{"make_cavp"}, os.Args[1:]...)
	fmt.Printf("# Generated by %q\n\n", strings.Join(args, " "))

	for i, p := range flag.Args() {
		f, err := os.Open(p)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()

		fmt.Printf("# File %d: %s\n\n", i+1, p)
		test.generate(f, *cmdLineLabelStr)
	}
}
