Skip to content

Commit

Permalink
Clean up TODOs
Browse files Browse the repository at this point in the history
  • Loading branch information
WillChilds-Klein committed Sep 26, 2023
1 parent efc8d2a commit 9c09d51
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 36 deletions.
18 changes: 10 additions & 8 deletions util/fipstools/acvp/acvptool/subprocess/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"strings"
)

// The following structures reflect the JSON of ACVP hash tests. See
Expand Down Expand Up @@ -55,15 +56,13 @@ type hashTestGroupResponse struct {
}

type hashTestResponse struct {
ID uint64 `json:"tcId"`
DigestHex string `json:"md,omitempty"`
OutputLength *uint64 `json:"outLen,omitempty"`
MCTResults []hashMCTResult `json:"resultsArray,omitempty"`
ID uint64 `json:"tcId"`
DigestHex string `json:"md,omitempty"`
MCTResults []hashMCTResult `json:"resultsArray,omitempty"`
}

type hashMCTResult struct {
DigestHex string `json:"md"`
OutputLength *uint64 `json:"outLen,omitempty"`
DigestHex string `json:"md"`
}

// hashPrimitive implements an ACVP algorithm by making requests to the
Expand Down Expand Up @@ -122,7 +121,10 @@ func (h *hashPrimitive) Process(vectorSet []byte, m Transactable) (any, error) {
})

case "MCT":
if len(msg) != h.size {
// MCT tests for conventional digest functions expect message
// and digest output lengths to be equivalent, however SHAKE
// does not have a predefined output length.
if len(msg) != h.size && !strings.HasPrefix(h.algo, "SHAKE") {
return nil, fmt.Errorf("MCT test case %d/%d contains message of length %d but the digest length is %d", group.ID, test.ID, len(msg), h.size)
}

Expand All @@ -136,7 +138,7 @@ func (h *hashPrimitive) Process(vectorSet []byte, m Transactable) (any, error) {
}

digest = result[0]
testResponse.MCTResults = append(testResponse.MCTResults, hashMCTResult{hex.EncodeToString(digest), nil})
testResponse.MCTResults = append(testResponse.MCTResults, hashMCTResult{hex.EncodeToString(digest)})
}

response.Tests = append(response.Tests, testResponse)
Expand Down
27 changes: 14 additions & 13 deletions util/fipstools/acvp/acvptool/subprocess/subprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,20 @@ func NewWithIO(cmd *exec.Cmd, in io.WriteCloser, out io.ReadCloser) *Subprocess
}

m.primitives = map[string]primitive{
"SHA-1": &hashPrimitive{"SHA-1", 20},
"SHA2-224": &hashPrimitive{"SHA2-224", 28},
"SHA2-256": &hashPrimitive{"SHA2-256", 32},
"SHA2-384": &hashPrimitive{"SHA2-384", 48},
"SHA2-512": &hashPrimitive{"SHA2-512", 64},
"SHA2-512/224": &hashPrimitive{"SHA2-512/224", 28},
"SHA2-512/256": &hashPrimitive{"SHA2-512/256", 32},
"SHA3-224": &hashPrimitive{"SHA3-224", 28},
"SHA3-256": &hashPrimitive{"SHA3-256", 32},
"SHA3-384": &hashPrimitive{"SHA3-384", 48},
"SHA3-512": &hashPrimitive{"SHA3-512", 64},
"SHAKE-128": &hashPrimitive{"SHAKE-128", 16}, // TODO [childw] explain why 16 -- msg len for MCT
"SHAKE-256": &hashPrimitive{"SHAKE-256", 16},
"SHA-1": &hashPrimitive{"SHA-1", 20},
"SHA2-224": &hashPrimitive{"SHA2-224", 28},
"SHA2-256": &hashPrimitive{"SHA2-256", 32},
"SHA2-384": &hashPrimitive{"SHA2-384", 48},
"SHA2-512": &hashPrimitive{"SHA2-512", 64},
"SHA2-512/224": &hashPrimitive{"SHA2-512/224", 28},
"SHA2-512/256": &hashPrimitive{"SHA2-512/256", 32},
"SHA3-224": &hashPrimitive{"SHA3-224", 28},
"SHA3-256": &hashPrimitive{"SHA3-256", 32},
"SHA3-384": &hashPrimitive{"SHA3-384", 48},
"SHA3-512": &hashPrimitive{"SHA3-512", 64},
// NOTE: SHAKE does not have a predifined digest output size
"SHAKE-128": &hashPrimitive{"SHAKE-128", -1},
"SHAKE-256": &hashPrimitive{"SHAKE-256", -1},
"ACVP-AES-ECB": &blockCipher{"AES", 16, 2, true, false, iterateAES},
"ACVP-AES-CBC": &blockCipher{"AES-CBC", 16, 2, true, true, iterateAESCBC},
"ACVP-AES-CBC-CS3": &blockCipher{"AES-CBC-CS3", 16, 1, false, true, iterateAESCBC},
Expand Down
28 changes: 13 additions & 15 deletions util/fipstools/acvp/modulewrapper/modulewrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1205,34 +1205,32 @@ static bool HashMCTSha3(const Span<const uint8_t> args[],

template <const EVP_MD *(MDFunc)()>
static bool HashMCTXof(const Span<const uint8_t> args[], ReplyCallback write_reply) {
// The following logic conforms to the Monte Carlo tests described in
// The spec for SHAKE monte carlo tests is written to be generic between a
// minimum and maximum output length, but the vectors obtained from ACVP
// allow only 1024 bits. Supporting dynamically sized MCTs would require
// passing the min/max output lengths to the modulewrapper, parsing ibid.,
// and dynamically allocating and freeing appropriately sized bufffers. To
// keep things simple, we defer that complexity until/if needed.
//
// https://pages.nist.gov/ACVP/draft-celi-acvp-sha3.html#name-shake-monte-carlo-test

// TODO [childw] parse min/max uint32's, this will require allocating |md|
// and |msg| dynamically.
const unsigned minOutBytes = 1024/8;
const unsigned maxOutBytes = 1024/8;
const unsigned range = maxOutBytes - minOutBytes + 1;
const unsigned md_out_size = 1024/8;
const unsigned output_len = 1024/8;
const unsigned msg_size = 128/8;

const size_t array_len = 1001;
unsigned char md[array_len][md_out_size];
unsigned char md[array_len][output_len];
unsigned char msg[array_len][msg_size];

// Zero out |md| and |msg| to clear any residual stack garbage before XOF computation
for (size_t i = 0; i < array_len; i++) {
OPENSSL_cleanse(md[i], sizeof(md[0]) * sizeof(unsigned char));
OPENSSL_cleanse(msg[i], sizeof(msg[0]) * sizeof(unsigned char));
}

memcpy(md[0], args[0].data(), msg_size);

unsigned outputLen = maxOutBytes;
unsigned output_len_mut = output_len;
for (size_t i = 1; i < array_len; i++) {
memcpy(msg[i], md[i-1], msg_size);
EVP_Digest(msg[i], sizeof(msg[i]), md[i], &outputLen, MDFunc(), NULL);
const unsigned rightmostOutputBits = (unsigned) md[i][md_out_size-1] & 0xffff;
outputLen = minOutBytes + (rightmostOutputBits % range);
EVP_Digest(msg[i], sizeof(msg[i]), md[i], &output_len_mut, MDFunc(), NULL);
}

return write_reply({Span<const uint8_t>(md[1000])});
Expand Down Expand Up @@ -2541,7 +2539,7 @@ static struct {
{"SHA3-256/MCT", 1, HashMCTSha3<EVP_sha3_256, SHA256_DIGEST_LENGTH>},
{"SHA3-384/MCT", 1, HashMCTSha3<EVP_sha3_384, SHA384_DIGEST_LENGTH>},
{"SHA3-512/MCT", 1, HashMCTSha3<EVP_sha3_512, SHA512_DIGEST_LENGTH>},
{"SHAKE-128/MCT", 1, HashMCTXof<EVP_shake128>}, // TODO [childw] bump args to 3 and pass over min/max
{"SHAKE-128/MCT", 1, HashMCTXof<EVP_shake128>},
{"SHAKE-256/MCT", 1, HashMCTXof<EVP_shake256>},
{"SHA-1/LDT", 2, HashLDT<SHA1, SHA_DIGEST_LENGTH>},
{"SHA2-224/LDT", 2, HashLDT<SHA224, SHA224_DIGEST_LENGTH>},
Expand Down

0 comments on commit 9c09d51

Please sign in to comment.