From 51d9a8d3b3270fc506fb039a1af0c6f3033f37b6 Mon Sep 17 00:00:00 2001 From: Sean McGrail <549813+skmcgrail@users.noreply.github.com> Date: Tue, 10 Sep 2024 21:03:42 +0000 Subject: [PATCH] ACVP ECDSA SHA3 Digest Testing (#1819) By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- .../acvp/acvptool/subprocess/ecdsa.go | 108 ++++++------------ .../acvp/acvptool/test/expected/ECDSA.bz2 | Bin 439 -> 524 bytes util/fipstools/acvp/acvptool/test/tests.json | 1 + .../acvptool/test/vectors/ECDSA-KeyGen.bz2 | Bin 0 -> 372 bytes .../acvptool/test/vectors/ECDSA-SigGen.bz2 | Bin 3416 -> 6112 bytes .../acvp/acvptool/test/vectors/ECDSA.bz2 | Bin 8485 -> 14928 bytes .../acvp/modulewrapper/modulewrapper.cc | 20 +++- 7 files changed, 52 insertions(+), 77 deletions(-) create mode 100644 util/fipstools/acvp/acvptool/test/vectors/ECDSA-KeyGen.bz2 diff --git a/util/fipstools/acvp/acvptool/subprocess/ecdsa.go b/util/fipstools/acvp/acvptool/subprocess/ecdsa.go index db240bb21f..798716aa49 100644 --- a/util/fipstools/acvp/acvptool/subprocess/ecdsa.go +++ b/util/fipstools/acvp/acvptool/subprocess/ecdsa.go @@ -16,7 +16,6 @@ package subprocess import ( "bytes" - "encoding/hex" "encoding/json" "fmt" ) @@ -36,30 +35,30 @@ type ecdsaTestGroup struct { HashAlgo string `json:"hashAlg,omitEmpty"` ComponentTest bool `json:"componentTest"` Tests []struct { - ID uint64 `json:"tcId"` - QxHex string `json:"qx,omitempty"` - QyHex string `json:"qy,omitempty"` - RHex string `json:"r,omitempty"` - SHex string `json:"s,omitempty"` - MsgHex string `json:"message,omitempty"` + ID uint64 `json:"tcId"` + Qx hexEncodedByteString `json:"qx,omitempty"` + Qy hexEncodedByteString `json:"qy,omitempty"` + R hexEncodedByteString `json:"r,omitempty"` + S hexEncodedByteString `json:"s,omitempty"` + Msg hexEncodedByteString `json:"message,omitempty"` } `json:"tests"` } type ecdsaTestGroupResponse struct { - ID uint64 `json:"tgId"` - Tests []ecdsaTestResponse `json:"tests"` - QxHex string `json:"qx,omitempty"` - QyHex string `json:"qy,omitempty"` + ID uint64 `json:"tgId"` + Tests []ecdsaTestResponse `json:"tests"` + Qx hexEncodedByteString `json:"qx,omitempty"` + Qy hexEncodedByteString `json:"qy,omitempty"` } type ecdsaTestResponse struct { - ID uint64 `json:"tcId"` - DHex string `json:"d,omitempty"` - QxHex string `json:"qx,omitempty"` - QyHex string `json:"qy,omitempty"` - RHex string `json:"r,omitempty"` - SHex string `json:"s,omitempty"` - Passed *bool `json:"testPassed,omitempty"` // using pointer so value is not omitted when it is false + ID uint64 `json:"tcId"` + D hexEncodedByteString `json:"d,omitempty"` + Qx hexEncodedByteString `json:"qx,omitempty"` + Qy hexEncodedByteString `json:"qy,omitempty"` + R hexEncodedByteString `json:"r,omitempty"` + S hexEncodedByteString `json:"s,omitempty"` + Passed *bool `json:"testPassed,omitempty"` // using pointer so value is not omitted when it is false } // ecdsa implements an ACVP algorithm by making requests to the @@ -83,8 +82,6 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { // https://pages.nist.gov/ACVP/draft-fussell-acvp-ecdsa.html#name-test-vectors // for details about the tests. for _, group := range parsed.Groups { - group := group - if _, ok := e.curves[group.Curve]; !ok { return nil, fmt.Errorf("curve %q in test group %d not supported", group.Curve, group.ID) } @@ -92,13 +89,10 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { response := ecdsaTestGroupResponse{ ID: group.ID, } + var sigGenPrivateKey []byte - var qxHex []byte - var qyHex []byte for _, test := range group.Tests { - test := test - var testResp ecdsaTestResponse switch parsed.Mode { @@ -110,20 +104,12 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { if err != nil { return nil, fmt.Errorf("key generation failed for test case %d/%d: %s", group.ID, test.ID, err) } - testResp.DHex = hex.EncodeToString(result[0]) - testResp.QxHex = hex.EncodeToString(result[1]) - testResp.QyHex = hex.EncodeToString(result[2]) + testResp.D = result[0] + testResp.Qx = result[1] + testResp.Qy = result[2] case "keyVer": - qx, err := hex.DecodeString(test.QxHex) - if err != nil { - return nil, fmt.Errorf("failed to decode qx in test case %d/%d: %s", group.ID, test.ID, err) - } - qy, err := hex.DecodeString(test.QyHex) - if err != nil { - return nil, fmt.Errorf("failed to decode qy in test case %d/%d: %s", group.ID, test.ID, err) - } - result, err := m.Transact(e.algo+"/"+"keyVer", 1, []byte(group.Curve), qx, qy) + result, err := m.Transact(e.algo+"/"+"keyVer", 1, []byte(group.Curve), test.Qx, test.Qy) if err != nil { return nil, fmt.Errorf("key verification failed for test case %d/%d: %s", group.ID, test.ID, err) } @@ -154,39 +140,31 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { } sigGenPrivateKey = result[0] - qxHex = result[1] - qyHex = result[2] - response.QxHex = hex.EncodeToString(qxHex) - response.QyHex = hex.EncodeToString(qyHex) + response.Qx = result[1] + response.Qy = result[2] } - msg, err := hex.DecodeString(test.MsgHex) - if err != nil { - return nil, fmt.Errorf("failed to decode message hex in test case %d/%d: %s", group.ID, test.ID, err) - } op := e.algo + "/" + "sigGen" if group.ComponentTest { - if len(msg) != h.size { - return nil, fmt.Errorf("test case %d/%d contains message %q of length %d, but expected length %d", group.ID, test.ID, test.MsgHex, len(msg), h.size) + if len(test.Msg) != h.size { + return nil, fmt.Errorf("test case %d/%d contains message %q of length %d, but expected length %d", group.ID, test.ID, test.Msg, len(test.Msg), h.size) } op += "/componentTest" } - result, err := m.Transact(op, 2, []byte(group.Curve), sigGenPrivateKey, []byte(group.HashAlgo), msg) + result, err := m.Transact(op, 2, []byte(group.Curve), sigGenPrivateKey, []byte(group.HashAlgo), test.Msg) if err != nil { return nil, fmt.Errorf("signature generation failed for test case %d/%d: %s", group.ID, test.ID, err) } - rHex := result[0] - sHex := result[1] - testResp.RHex = hex.EncodeToString(rHex) - testResp.SHex = hex.EncodeToString(sHex) + testResp.R = result[0] + testResp.S = result[1] // Ask the subprocess to verify the generated signature for this test case. - ver_result, ver_err := m.Transact(e.algo+"/"+"sigVer", 1, []byte(group.Curve), []byte(group.HashAlgo), msg, qxHex, qyHex, rHex, sHex) + ver_result, ver_err := m.Transact(e.algo+"/"+"sigVer", 1, []byte(group.Curve), []byte(group.HashAlgo), test.Msg, response.Qx, response.Qy, testResp.R, testResp.S) if ver_err != nil { - return nil, fmt.Errorf("After signature generation, signature verification failed for test case %d/%d: %s", group.ID, test.ID, ver_err) + return nil, fmt.Errorf("after signature generation, signature verification failed for test case %d/%d: %s", group.ID, test.ID, ver_err) } // ver_result[0] should be a single byte. The value should be one in this case. if !bytes.Equal(ver_result[0], []byte{01}) { - return nil, fmt.Errorf("After signature generation, signature verification returned unexpected result: %q for test case %d/%d.", ver_result[0], group.ID, test.ID) + return nil, fmt.Errorf("after signature generation, signature verification returned unexpected result: %q for test case %d/%d", ver_result[0], group.ID, test.ID) } case "sigVer": @@ -196,27 +174,7 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { return nil, fmt.Errorf("unsupported hash algorithm %q in test group %d", group.HashAlgo, group.ID) } - msg, err := hex.DecodeString(test.MsgHex) - if err != nil { - return nil, fmt.Errorf("failed to decode message hex in test case %d/%d: %s", group.ID, test.ID, err) - } - qx, err := hex.DecodeString(test.QxHex) - if err != nil { - return nil, fmt.Errorf("failed to decode qx in test case %d/%d: %s", group.ID, test.ID, err) - } - qy, err := hex.DecodeString(test.QyHex) - if err != nil { - return nil, fmt.Errorf("failed to decode qy in test case %d/%d: %s", group.ID, test.ID, err) - } - r, err := hex.DecodeString(test.RHex) - if err != nil { - return nil, fmt.Errorf("failed to decode R in test case %d/%d: %s", group.ID, test.ID, err) - } - s, err := hex.DecodeString(test.SHex) - if err != nil { - return nil, fmt.Errorf("failed to decode S in test case %d/%d: %s", group.ID, test.ID, err) - } - result, err := m.Transact(e.algo+"/"+"sigVer", 1, []byte(group.Curve), []byte(group.HashAlgo), msg, qx, qy, r, s) + result, err := m.Transact(e.algo+"/"+"sigVer", 1, []byte(group.Curve), []byte(group.HashAlgo), test.Msg, test.Qx, test.Qy, test.R, test.S) if err != nil { return nil, fmt.Errorf("signature verification failed for test case %d/%d: %s", group.ID, test.ID, err) } diff --git a/util/fipstools/acvp/acvptool/test/expected/ECDSA.bz2 b/util/fipstools/acvp/acvptool/test/expected/ECDSA.bz2 index 0d508a8736a5783a3169b93c07eb1de50371946d..063cf2417dcec7b7626e390f03e896fd23924190 100644 GIT binary patch literal 524 zcmV+n0`vVsT4*^jL0KkKS@2Q!M*s*Me}F_(Kmbq%|L`uLP8u)g-wHqid`1IM8YIO0 zsWmb^BhVw$Ns|*JLnZ{8kW&*>^d^8B0BH398Vm-2&;SOS4FJ#vfTcL`NacpA-&QFefFsbqj0ci_BS_1n8oGk%qZr`ygskK!u$csN~=h>^Jub;i& z_(I`DfVAFsP&0=B2DAVJL4}}L9?;Cg+V2~*-+lg&%QTWxNl=nWNhIniB}ysiK|&FX z)RLvl=Q+jZX^ABli6q3M2}qJ?DisPy?Wc1s_QYm@ynzAI9(?O z5|HNE>IV94Y)$Q(^e{O@(|VreW~>iRrftU6j#Z|)wCQwC2y1FhN!gTASLot$60w3|k{rb4&5t1{s`Lt6PS)zY)%AqkC-MU9FqKtCR>6 zT=P3miG#TO&%%l-#ZgpND-}h2g%qmAMMet&MO0X;ECD%;?w$JU=#VFGr~>wPTYA`d zNd5)n3+Z@Y)GWbo<%S3>L|CL0g0IitC<1wAkbxQ12+SAVi$&k`Y6>Sr8T4Z=MJd;0pk>g3t>*hgUJ9@mk*w?mgazvXXhB#Mg{&Y;BX&3Hva2ME)m%w1FDl{-?Lp6D2}uN!s!1y> z3oOB&DM2`yJteV3?L8S8qR6s3qI1r_qQ@&v2QE7BcZ9qgu#x<<)JIl}0;yu(+ zRuy=LVipucMNwg7aRS;#_e~lVcWedMv8uus3Vs6eg6?jAL|OrG>5&N*5hc4^K(;wi zSn3p@7ScG{+{A*M4mdHT?kO`l%2Ho>aBp-b6}70KQv$94Ul0J90FN;jGXO3kHNHb2 hSs2F|Dwu-fF=5`oTR~v~V2_jjF64@Ep&?Jv$) ziKz7kk5Kf=4FCs}FwoEd02%-Q001h95DDrHq75zKUH#K7wf~9VIAK zNTJbjLhF%%7#n8;dX`d-$JuL`Ux#&2pE4ZT4NPG+qHWKVZ-C7a$Vm#L2PtJ$?&RL6yky5*GOXdmPDS`aVkV-}b0jWJ!n1*zqV>F2u9y{-Qsru?tiJm< S5}?eB{x0N-aG@bzC~|<*522g@ literal 0 HcmV?d00001 diff --git a/util/fipstools/acvp/acvptool/test/vectors/ECDSA-SigGen.bz2 b/util/fipstools/acvp/acvptool/test/vectors/ECDSA-SigGen.bz2 index 474e3c0849e5ed207a618cc952d953863ccf1de8..ed73c4533cda937df8e44ff2305f5740909934a9 100644 GIT binary patch literal 6112 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 literal 3416 zcmV-e4X5%#T4*^jL0KkKS+d!XkN^>l-+)z6PzV3;KjKabFYn(fU=Tk5cX~YyREnrT zq*6*kg%qu_w!okTD5@R+0x7a+8klKN44N?-007e_2龺yP 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

rY%aQ$I44jne=NMV56eEw^! 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 args[], "SHA2-384", "SHA2-512", "SHA2-512/224", - "SHA2-512/256" + "SHA2-512/256", + "SHA3-224", + "SHA3-256", + "SHA3-384", + "SHA3-512" ] }] }, @@ -613,7 +617,11 @@ static bool GetConfig(const Span args[], "SHA2-384", "SHA2-512", "SHA2-512/224", - "SHA2-512/256" + "SHA2-512/256", + "SHA3-224", + "SHA3-256", + "SHA3-384", + "SHA3-512" ] }] },)" @@ -2287,6 +2295,14 @@ static const EVP_MD *HashFromName(Span name) { return EVP_sha512_224(); } else if (StringEq(name, "SHA2-512/256")) { return EVP_sha512_256(); + } else if (StringEq(name, "SHA3-224")) { + return EVP_sha3_224(); + } else if (StringEq(name, "SHA3-256")) { + return EVP_sha3_256(); + } else if (StringEq(name, "SHA3-384")) { + return EVP_sha3_384(); + } else if (StringEq(name, "SHA3-512")) { + return EVP_sha3_512(); } else if (StringEq(name, "SHAKE-128")) { return EVP_shake128(); } else if (StringEq(name, "SHAKE-256")) {