From 08aab544858ed4958389833fcca0d620f9e0a36a Mon Sep 17 00:00:00 2001 From: Sean McGrail Date: Mon, 9 Sep 2024 23:42:41 +0000 Subject: [PATCH] ACVP ML-KEM testing --- .../acvp/acvptool/subprocess/ml_kem.go | 194 ++++++++++++++++++ .../acvp/acvptool/subprocess/subprocess.go | 1 + .../acvp/acvptool/test/expected/ML-KEM.bz2 | Bin 0 -> 13960 bytes util/fipstools/acvp/acvptool/test/tests.json | 3 +- .../acvp/acvptool/test/vectors/ML-KEM.bz2 | Bin 0 -> 15398 bytes .../acvp/modulewrapper/modulewrapper.cc | 139 ++++++++++++- 6 files changed, 333 insertions(+), 4 deletions(-) create mode 100644 util/fipstools/acvp/acvptool/subprocess/ml_kem.go create mode 100644 util/fipstools/acvp/acvptool/test/expected/ML-KEM.bz2 create mode 100644 util/fipstools/acvp/acvptool/test/vectors/ML-KEM.bz2 diff --git a/util/fipstools/acvp/acvptool/subprocess/ml_kem.go b/util/fipstools/acvp/acvptool/subprocess/ml_kem.go new file mode 100644 index 00000000000..59d5c4d75f9 --- /dev/null +++ b/util/fipstools/acvp/acvptool/subprocess/ml_kem.go @@ -0,0 +1,194 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +package subprocess + +import ( + "encoding/json" + "fmt" + "strings" +) + +type mlKem struct{} + +func (*mlKem) Process(vectorSet []byte, m Transactable) (interface{}, error) { + var vs struct { + Mode string `json:"mode"` + TestGroups json.RawMessage `json:"testGroups"` + } + + if err := json.Unmarshal(vectorSet, &vs); err != nil { + return nil, err + } + + switch { + case strings.EqualFold(vs.Mode, "keyGen"): + return processMlKemKeyGen(vs.TestGroups, m) + case strings.EqualFold(vs.Mode, "encapDecap"): + return processMlKemEncapDecap(vs.TestGroups, m) + } + + return nil, fmt.Errorf("unknown ML-KEM mode: %v", vs.Mode) +} + +type mlKemKeyGenTestGroup struct { + ID uint64 `json:"tgId"` + Type string `json:"testType"` + ParameterSet string `json:"parameterSet"` + Tests []struct { + ID uint64 `json:"tcId"` + D hexEncodedByteString `json:"d"` + Z hexEncodedByteString `json:"z"` + } +} + +type mlKemKeyGenTestGroupResponse struct { + ID uint64 `json:"tgId"` + Tests []mlKemKeyGenTestCaseResponse `json:"tests"` +} + +type mlKemKeyGenTestCaseResponse struct { + ID uint64 `json:"tcId"` + EK hexEncodedByteString `json:"ek"` + DK hexEncodedByteString `json:"dk"` +} + +func processMlKemKeyGen(vectors json.RawMessage, m Transactable) (interface{}, error) { + var groups []mlKemKeyGenTestGroup + + if err := json.Unmarshal(vectors, &groups); err != nil { + return nil, err + } + + var responses []mlKemKeyGenTestGroupResponse + + for _, group := range groups { + if !strings.EqualFold(group.Type, "AFT") { + return nil, fmt.Errorf("unsupported keyGen test type: %v", group.Type) + } + + response := mlKemKeyGenTestGroupResponse{ + ID: group.ID, + } + + for _, test := range group.Tests { + results, err := m.Transact("ML-KEM/"+group.ParameterSet+"/keyGen", 2, test.D, test.Z) + if err != nil { + return nil, err + } + + ek := results[0] + dk := results[1] + + response.Tests = append(response.Tests, mlKemKeyGenTestCaseResponse{ + ID: test.ID, + EK: ek, + DK: dk, + }) + } + + responses = append(responses, response) + } + + return responses, nil +} + +type mlKemEncapDecapTestGroup struct { + ID uint64 `json:"tgId"` + Type string `json:"testType"` + ParameterSet string `json:"parameterSet"` + Function string `json:"function"` + DK hexEncodedByteString `json:"dk"` + Tests []struct { + ID uint64 `json:"tcId"` + EK hexEncodedByteString `json:"ek"` + M hexEncodedByteString `json:"m"` + C hexEncodedByteString `json:"c"` + } +} + +type mlKemEncDecapTestGroupResponse struct { + ID uint64 `json:"tgId"` + Tests []mlKemEncDecapTestCaseResponse `json:"tests"` +} + +type mlKemEncDecapTestCaseResponse struct { + ID uint64 `json:"tcId"` + C hexEncodedByteString `json:"c,omitempty"` + K hexEncodedByteString `json:"k,omitempty"` +} + +func processMlKemEncapDecap(vectors json.RawMessage, m Transactable) (interface{}, error) { + var groups []mlKemEncapDecapTestGroup + + if err := json.Unmarshal(vectors, &groups); err != nil { + return nil, err + } + + var responses []mlKemEncDecapTestGroupResponse + + for _, group := range groups { + if (strings.EqualFold(group.Function, "encapsulation") && !strings.EqualFold(group.Type, "AFT")) || + (strings.EqualFold(group.Function, "decapsulation") && !strings.EqualFold(group.Type, "VAL")) { + return nil, fmt.Errorf("unsupported encapDecap function and test group type pair: (%v, %v)", group.Function, group.Type) + } + + response := mlKemEncDecapTestGroupResponse{ + ID: group.ID, + } + + for _, test := range group.Tests { + var ( + err error + testResponse mlKemEncDecapTestCaseResponse + ) + + switch { + case strings.EqualFold(group.Function, "encapsulation"): + testResponse, err = processMlKemEncapTestCase(test.ID, group.ParameterSet, test.EK, test.M, m) + case strings.EqualFold(group.Function, "decapsulation"): + testResponse, err = processMlKemDecapTestCase(test.ID, group.ParameterSet, group.DK, test.C, m) + default: + return nil, fmt.Errorf("unknown encDecap function: %v", group.Function) + } + if err != nil { + return nil, err + } + + response.Tests = append(response.Tests, testResponse) + } + + responses = append(responses, response) + } + return responses, nil +} + +func processMlKemEncapTestCase(id uint64, algorithm string, ek []byte, m []byte, t Transactable) (mlKemEncDecapTestCaseResponse, error) { + results, err := t.Transact("ML-KEM/"+algorithm+"/encap", 2, ek, m) + if err != nil { + return mlKemEncDecapTestCaseResponse{}, err + } + + c := results[0] + k := results[1] + + return mlKemEncDecapTestCaseResponse{ + ID: id, + C: c, + K: k, + }, nil +} + +func processMlKemDecapTestCase(id uint64, algorithm string, dk []byte, c []byte, t Transactable) (mlKemEncDecapTestCaseResponse, error) { + results, err := t.Transact("ML-KEM/"+algorithm+"/decap", 1, dk, c) + if err != nil { + return mlKemEncDecapTestCaseResponse{}, err + } + + k := results[0] + + return mlKemEncDecapTestCaseResponse{ + ID: id, + K: k, + }, nil +} diff --git a/util/fipstools/acvp/acvptool/subprocess/subprocess.go b/util/fipstools/acvp/acvptool/subprocess/subprocess.go index b655b4a4ec3..2f21c707230 100644 --- a/util/fipstools/acvp/acvptool/subprocess/subprocess.go +++ b/util/fipstools/acvp/acvptool/subprocess/subprocess.go @@ -153,6 +153,7 @@ func NewWithIO(cmd *exec.Cmd, in io.WriteCloser, out io.ReadCloser) *Subprocess "KAS-ECC-SSC": &kas{}, "KAS-FFC-SSC": &kasDH{}, "PBKDF": &pbkdf{}, + "ML-KEM": &mlKem{}, } m.primitives["ECDSA"] = &ecdsa{"ECDSA", map[string]bool{"P-224": true, "P-256": true, "P-384": true, "P-521": true}, m.primitives} diff --git a/util/fipstools/acvp/acvptool/test/expected/ML-KEM.bz2 b/util/fipstools/acvp/acvptool/test/expected/ML-KEM.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..a1c8378cab24752f217f73a75b49d90eb76ac2bc GIT binary patch literal 13960 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 literal 0 HcmV?d00001 diff --git a/util/fipstools/acvp/acvptool/test/tests.json b/util/fipstools/acvp/acvptool/test/tests.json index 6aa28a1d703..c8f48bf2f90 100644 --- a/util/fipstools/acvp/acvptool/test/tests.json +++ b/util/fipstools/acvp/acvptool/test/tests.json @@ -31,5 +31,6 @@ {"Wrapper": "modulewrapper", "In": "vectors/TLS-1.2-KDF.bz2", "Out": "expected/TLS-1.2-KDF.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/PBKDF.bz2", "Out": "expected/PBKDF.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/KDA-HKDF.bz2", "Out": "expected/KDA-HKDF.bz2"}, -{"Wrapper": "modulewrapper", "In": "vectors/KDA-OneStep.bz2", "Out": "expected/KDA-OneStep.bz2"} +{"Wrapper": "modulewrapper", "In": "vectors/KDA-OneStep.bz2", "Out": "expected/KDA-OneStep.bz2"}, +{"Wrapper": "modulewrapper", "In": "vectors/ML-KEM.bz2", "Out": "expected/ML-KEM.bz2"} ] diff --git a/util/fipstools/acvp/acvptool/test/vectors/ML-KEM.bz2 b/util/fipstools/acvp/acvptool/test/vectors/ML-KEM.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..09da3260915f774545c28690c93e017c7dae7951 GIT binary patch literal 15398 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 literal 0 HcmV?d00001 diff --git a/util/fipstools/acvp/modulewrapper/modulewrapper.cc b/util/fipstools/acvp/modulewrapper/modulewrapper.cc index 59d72e5bdb3..12dbf1f1976 100644 --- a/util/fipstools/acvp/modulewrapper/modulewrapper.cc +++ b/util/fipstools/acvp/modulewrapper/modulewrapper.cc @@ -12,11 +12,11 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include #include -#include #include @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -732,7 +733,7 @@ static bool GetConfig(const Span args[], }] }] },)" - R"({ + R"({ "sigType": "pss", "properties": [{ "modulo": 2048, @@ -988,7 +989,7 @@ static bool GetConfig(const Span args[], }] }] },)" - R"({ + R"({ "sigType": "pss", "properties": [{ "modulo": 2048, @@ -1307,6 +1308,19 @@ static bool GetConfig(const Span args[], "encoding": ["concatenation"], "z": [{"min": 224, "max": 8192, "increment": 8}], "l": 2048 + },)" + R"({ + "algorithm": "ML-KEM", + "mode": "keyGen", + "revision": "FIPS203", + "parameterSets": ["ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"] + }, + { + "algorithm": "ML-KEM", + "mode": "encapDecap", + "revision": "FIPS203", + "parameterSets": ["ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"], + "functions": ["encapsulation", "decapsulation"] } ])"; return write_reply({Span( @@ -2830,6 +2844,116 @@ static bool KBKDF_CTR_HMAC(const Span args[], return write_reply({Span(out)}); } +template +static bool ML_KEM_KEYGEN(const Span args[], + ReplyCallback write_reply) { + const Span d = args[0]; + const Span z = args[1]; + + std::vector(seed); + seed.reserve(d.size()+z.size()); + for (size_t i = 0; i < d.size(); i++) { + seed.insert(seed.end(), d[i]); + } + for (size_t i = 0; i < z.size(); i++) { + seed.insert(seed.end(), z[i]); + } + + EVP_PKEY *raw = NULL; + size_t seed_len = 0; + + bssl::UniquePtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_KEM, nullptr)); + if (!EVP_PKEY_CTX_kem_set_params(ctx.get(), nid) || + !EVP_PKEY_keygen_init(ctx.get()) || + !EVP_PKEY_keygen_deterministic(ctx.get(), &raw, NULL, &seed_len) || + seed_len != seed.size() || + !EVP_PKEY_keygen_deterministic(ctx.get(), &raw, seed.data(), &seed_len)) { + return false; + } + bssl::UniquePtr pkey(raw); + + size_t decaps_key_size = 0; + size_t encaps_key_size = 0; + + if (!EVP_PKEY_get_raw_private_key(pkey.get(), nullptr, &decaps_key_size) || + !EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &encaps_key_size)) { + return false; + } + + std::vector decaps_key(decaps_key_size); + std::vector encaps_key(encaps_key_size); + + if (!EVP_PKEY_get_raw_private_key(pkey.get(), decaps_key.data(), + &decaps_key_size) || + !EVP_PKEY_get_raw_public_key(pkey.get(), encaps_key.data(), + &encaps_key_size)) { + return false; + } + + return write_reply({Span(encaps_key.data(), encaps_key_size), + Span(decaps_key.data(), decaps_key_size)}); +} + +template +static bool ML_KEM_ENCAP(const Span args[], + ReplyCallback write_reply) { + const Span ek = args[0]; + const Span m = args[1]; + + bssl::UniquePtr pkey(EVP_PKEY_kem_new_raw_public_key(nid, ek.data(), ek.size())); + bssl::UniquePtr ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); + + size_t ciphertext_len = 0; + size_t shared_secret_len = 0; + size_t seed_len = 0; + if (!EVP_PKEY_encapsulate_deterministic(ctx.get(), nullptr, &ciphertext_len, + nullptr, &shared_secret_len, nullptr, + &seed_len) || + seed_len != m.size()) { + return false; + } + + std::vector ciphertext(ciphertext_len); + std::vector shared_secret(shared_secret_len); + + if (!EVP_PKEY_encapsulate_deterministic( + ctx.get(), ciphertext.data(), &ciphertext_len, shared_secret.data(), + &shared_secret_len, m.data(), &seed_len)) { + return false; + } + + return write_reply( + {Span(ciphertext.data(), ciphertext_len), + Span(shared_secret.data(), shared_secret_len)}); +} + +template +static bool ML_KEM_DECAP(const Span args[], + ReplyCallback write_reply) { + const Span dk = args[0]; + const Span c = args[1]; + + bssl::UniquePtr pkey( + EVP_PKEY_kem_new_raw_secret_key(nid, dk.data(), dk.size())); + bssl::UniquePtr ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); + + size_t shared_secret_len = 0; + if (!EVP_PKEY_decapsulate(ctx.get(), nullptr, &shared_secret_len, c.data(), + c.size())) { + return false; + } + + std::vector shared_secret(shared_secret_len); + + if (!EVP_PKEY_decapsulate(ctx.get(), shared_secret.data(), &shared_secret_len, + c.data(), c.size())) { + return false; + } + + return write_reply( + {Span(shared_secret.data(), shared_secret_len)}); +} + static struct { char name[kMaxNameLength + 1]; uint8_t num_expected_args; @@ -3064,6 +3188,15 @@ static struct { {"KDF/Counter/HMAC-SHA2-512", 3, KBKDF_CTR_HMAC}, {"KDF/Counter/HMAC-SHA2-512/224", 3, KBKDF_CTR_HMAC}, {"KDF/Counter/HMAC-SHA2-512/256", 3, KBKDF_CTR_HMAC}, + {"ML-KEM/ML-KEM-512/keyGen", 2, ML_KEM_KEYGEN}, + {"ML-KEM/ML-KEM-768/keyGen", 2, ML_KEM_KEYGEN}, + {"ML-KEM/ML-KEM-1024/keyGen", 2, ML_KEM_KEYGEN}, + {"ML-KEM/ML-KEM-512/encap", 2, ML_KEM_ENCAP}, + {"ML-KEM/ML-KEM-768/encap", 2, ML_KEM_ENCAP}, + {"ML-KEM/ML-KEM-1024/encap", 2, ML_KEM_ENCAP}, + {"ML-KEM/ML-KEM-512/decap", 2, ML_KEM_DECAP}, + {"ML-KEM/ML-KEM-768/decap", 2, ML_KEM_DECAP}, + {"ML-KEM/ML-KEM-1024/decap", 2, ML_KEM_DECAP}, }; Handler FindHandler(Span> args) {