// Copyright (c) 2019, 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.

package subprocess

import (
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"fmt"
)

// The following structures reflect the JSON of ACVP DRBG tests. See
// https://pages.nist.gov/ACVP/draft-vassilev-acvp-drbg.html#name-test-vectors

type drbgTestVectorSet struct {
	Groups []drbgTestGroup `json:"testGroups"`
}

type drbgTestGroup struct {
	ID                    uint64 `json:"tgId"`
	Mode                  string `json:"mode"`
	UseDerivationFunction bool   `json:"derFunc,omitempty"`
	PredictionResistance  bool   `json:"predResistance"`
	Reseed                bool   `json:"reSeed"`
	EntropyBits           uint64 `json:"entropyInputLen"`
	NonceBits             uint64 `json:"nonceLen"`
	PersonalizationBits   uint64 `json:"persoStringLen"`
	AdditionalDataBits    uint64 `json:"additionalInputLen"`
	RetBits               uint64 `json:"returnedBitsLen"`
	Tests                 []struct {
		ID                 uint64           `json:"tcId"`
		EntropyHex         string           `json:"entropyInput"`
		NonceHex           string           `json:"nonce"`
		PersonalizationHex string           `json:"persoString"`
		Other              []drbgOtherInput `json:"otherInput"`
	} `json:"tests"`
}

type drbgOtherInput struct {
	Use               string `json:"intendedUse"`
	AdditionalDataHex string `json:"additionalInput"`
	EntropyHex        string `json:"entropyInput"`
}

type drbgTestGroupResponse struct {
	ID    uint64             `json:"tgId"`
	Tests []drbgTestResponse `json:"tests"`
}

type drbgTestResponse struct {
	ID     uint64 `json:"tcId"`
	OutHex string `json:"returnedBits,omitempty"`
}

// drbg implements an ACVP algorithm by making requests to the
// subprocess to generate random bits with the given entropy and other paramaters.
type drbg struct {
	// algo is the ACVP name for this algorithm and also the command name
	// given to the subprocess to generate random bytes.
	algo  string
	modes map[string]bool // the supported underlying primitives for the DRBG
}

func (d *drbg) Process(vectorSet []byte, m Transactable) (any, error) {
	var parsed drbgTestVectorSet
	if err := json.Unmarshal(vectorSet, &parsed); err != nil {
		return nil, err
	}

	var ret []drbgTestGroupResponse
	// See
	// https://pages.nist.gov/ACVP/draft-vassilev-acvp-drbg.html#name-test-vectors
	// for details about the tests.
	for _, group := range parsed.Groups {
		response := drbgTestGroupResponse{
			ID: group.ID,
		}

		if _, ok := d.modes[group.Mode]; !ok {
			return nil, fmt.Errorf("test group %d specifies mode %q, which is not supported for the %s algorithm", group.ID, group.Mode, d.algo)
		}

		if group.RetBits%8 != 0 {
			return nil, fmt.Errorf("Test group %d requests %d-bit outputs, but fractional-bytes are not supported", group.ID, group.RetBits)
		}

		for _, test := range group.Tests {
			ent, err := extractField(test.EntropyHex, group.EntropyBits)
			if err != nil {
				return nil, fmt.Errorf("failed to extract entropy hex from test case %d/%d: %s", group.ID, test.ID, err)
			}

			nonce, err := extractField(test.NonceHex, group.NonceBits)
			if err != nil {
				return nil, fmt.Errorf("failed to extract nonce hex from test case %d/%d: %s", group.ID, test.ID, err)
			}

			perso, err := extractField(test.PersonalizationHex, group.PersonalizationBits)
			if err != nil {
				return nil, fmt.Errorf("failed to extract personalization hex from test case %d/%d: %s", group.ID, test.ID, err)
			}

			outLen := group.RetBits / 8
			var outLenBytes [4]byte
			binary.LittleEndian.PutUint32(outLenBytes[:], uint32(outLen))

			var result [][]byte
			if group.PredictionResistance {
				var a1, a2, a3, a4 []byte
				if err := extractOtherInputs(test.Other, []drbgOtherInputExpectations{
					{"generate", group.AdditionalDataBits, &a1, group.EntropyBits, &a2},
					{"generate", group.AdditionalDataBits, &a3, group.EntropyBits, &a4}}); err != nil {
					return nil, fmt.Errorf("failed to parse other inputs from test case %d/%d: %s", group.ID, test.ID, err)
				}
				result, err = m.Transact(d.algo+"-pr/"+group.Mode, 1, outLenBytes[:], ent, perso, a1, a2, a3, a4, nonce)
			} else if group.Reseed {
				var a1, a2, a3, a4 []byte
				if err := extractOtherInputs(test.Other, []drbgOtherInputExpectations{
					{"reSeed", group.AdditionalDataBits, &a1, group.EntropyBits, &a2},
					{"generate", group.AdditionalDataBits, &a3, 0, nil},
					{"generate", group.AdditionalDataBits, &a4, 0, nil}}); err != nil {
					return nil, fmt.Errorf("failed to parse other inputs from test case %d/%d: %s", group.ID, test.ID, err)
				}
				result, err = m.Transact(d.algo+"-reseed/"+group.Mode, 1, outLenBytes[:], ent, perso, a1, a2, a3, a4, nonce)
			} else {
				var a1, a2 []byte
				if err := extractOtherInputs(test.Other, []drbgOtherInputExpectations{
					{"generate", group.AdditionalDataBits, &a1, 0, nil},
					{"generate", group.AdditionalDataBits, &a2, 0, nil}}); err != nil {
					return nil, fmt.Errorf("failed to parse other inputs from test case %d/%d: %s", group.ID, test.ID, err)
				}
				result, err = m.Transact(d.algo+"/"+group.Mode, 1, outLenBytes[:], ent, perso, a1, a2, nonce)
			}

			if err != nil {
				return nil, fmt.Errorf("DRBG operation failed: %s", err)
			}

			if l := uint64(len(result[0])); l != outLen {
				return nil, fmt.Errorf("wrong length DRBG result: %d bytes but wanted %d", l, outLen)
			}

			// https://pages.nist.gov/ACVP/draft-vassilev-acvp-drbg.html#name-responses
			response.Tests = append(response.Tests, drbgTestResponse{
				ID:     test.ID,
				OutHex: hex.EncodeToString(result[0]),
			})
		}

		ret = append(ret, response)
	}

	return ret, nil
}

type drbgOtherInputExpectations struct {
	use                   string
	additionalInputBitLen uint64
	additionalInputOut    *[]byte
	entropyBitLen         uint64
	entropyOut            *[]byte
}

func extractOtherInputs(inputs []drbgOtherInput, expected []drbgOtherInputExpectations) (err error) {
	if len(inputs) != len(expected) {
		return fmt.Errorf("found %d other inputs but %d were expected", len(inputs), len(expected))
	}

	for i := range inputs {
		input, expect := &inputs[i], &expected[i]

		if input.Use != expect.use {
			return fmt.Errorf("other input #%d has type %q but expected %q", i, input.Use, expect.use)
		}

		if expect.additionalInputBitLen == 0 {
			if len(input.AdditionalDataHex) != 0 {
				return fmt.Errorf("other input #%d has unexpected additional input", i)
			}
		} else {
			*expect.additionalInputOut, err = extractField(input.AdditionalDataHex, expect.additionalInputBitLen)
			if err != nil {
				return err
			}
		}

		if expect.entropyBitLen == 0 {
			if len(input.EntropyHex) != 0 {
				return fmt.Errorf("other input #%d has unexpected entropy value", i)
			}
		} else {
			*expect.entropyOut, err = extractField(input.EntropyHex, expect.entropyBitLen)
			if err != nil {
				return err
			}
		}
	}

	return nil
}

// validate the length and hex of a JSON field in test vectors
func extractField(fieldHex string, bits uint64) ([]byte, error) {
	if uint64(len(fieldHex))*4 != bits {
		return nil, fmt.Errorf("expected %d bits but have %d-byte hex string", bits, len(fieldHex))
	}
	return hex.DecodeString(fieldHex)
}
