acvp: support KAS-ECC-SSC staticUnified mode.

Change-Id: I3dfd75c93b3ae83e0a4db643ac7d00d2867fa656
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46704
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/util/fipstools/acvp/acvptool/subprocess/kas.go b/util/fipstools/acvp/acvptool/subprocess/kas.go
index b95e48a..e63e660 100644
--- a/util/fipstools/acvp/acvptool/subprocess/kas.go
+++ b/util/fipstools/acvp/acvptool/subprocess/kas.go
@@ -35,11 +35,17 @@
 }
 
 type kasTest struct {
-	ID            uint64 `json:"tcId"`
-	XHex          string `json:"ephemeralPublicServerX"`
-	YHex          string `json:"ephemeralPublicServerY"`
-	PrivateKeyHex string `json:"ephemeralPrivateIut"`
-	ResultHex     string `json:"z"`
+	ID uint64 `json:"tcId"`
+
+	EphemeralXHex          string `json:"ephemeralPublicServerX"`
+	EphemeralYHex          string `json:"ephemeralPublicServerY"`
+	EphemeralPrivateKeyHex string `json:"ephemeralPrivateIut"`
+
+	StaticXHex          string `json:"staticPublicServerX"`
+	StaticYHex          string `json:"staticPublicServerY"`
+	StaticPrivateKeyHex string `json:"staticPrivateIut"`
+
+	ResultHex string `json:"z"`
 }
 
 type kasTestGroupResponse struct {
@@ -48,9 +54,14 @@
 }
 
 type kasTestResponse struct {
-	ID        uint64 `json:"tcId"`
-	XHex      string `json:"ephemeralPublicIutX,omitempty"`
-	YHex      string `json:"ephemeralPublicIutY,omitempty"`
+	ID uint64 `json:"tcId"`
+
+	EphemeralXHex string `json:"ephemeralPublicIutX,omitempty"`
+	EphemeralYHex string `json:"ephemeralPublicIutY,omitempty"`
+
+	StaticXHex string `json:"staticPublicIutX,omitempty"`
+	StaticYHex string `json:"staticPublicIutY,omitempty"`
+
 	ResultHex string `json:"z,omitempty"`
 	Passed    *bool  `json:"testPassed,omitempty"`
 }
@@ -94,33 +105,47 @@
 			return nil, fmt.Errorf("unknown role %q", group.Role)
 		}
 
-		if group.Scheme != "ephemeralUnified" {
+		var useStaticNamedFields bool
+		switch group.Scheme {
+		case "ephemeralUnified":
+			break
+		case "staticUnified":
+			useStaticNamedFields = true
+			break
+		default:
 			return nil, fmt.Errorf("unknown scheme %q", group.Scheme)
 		}
 
 		method := "ECDH/" + group.Curve
 
 		for _, test := range group.Tests {
-			if len(test.XHex) == 0 || len(test.YHex) == 0 {
+			var xHex, yHex, privateKeyHex string
+			if useStaticNamedFields {
+				xHex, yHex, privateKeyHex = test.StaticXHex, test.StaticYHex, test.StaticPrivateKeyHex
+			} else {
+				xHex, yHex, privateKeyHex = test.EphemeralXHex, test.EphemeralYHex, test.EphemeralPrivateKeyHex
+			}
+
+			if len(xHex) == 0 || len(yHex) == 0 {
 				return nil, fmt.Errorf("%d/%d is missing peer's point", group.ID, test.ID)
 			}
 
-			peerX, err := hex.DecodeString(test.XHex)
+			peerX, err := hex.DecodeString(xHex)
 			if err != nil {
 				return nil, err
 			}
 
-			peerY, err := hex.DecodeString(test.YHex)
+			peerY, err := hex.DecodeString(yHex)
 			if err != nil {
 				return nil, err
 			}
 
-			if (len(test.PrivateKeyHex) != 0) != privateKeyGiven {
+			if (len(privateKeyHex) != 0) != privateKeyGiven {
 				return nil, fmt.Errorf("%d/%d incorrect private key presence", group.ID, test.ID)
 			}
 
 			if privateKeyGiven {
-				privateKey, err := hex.DecodeString(test.PrivateKeyHex)
+				privateKey, err := hex.DecodeString(privateKeyHex)
 				if err != nil {
 					return nil, err
 				}
@@ -146,12 +171,20 @@
 					return nil, err
 				}
 
-				response.Tests = append(response.Tests, kasTestResponse{
+				testResponse := kasTestResponse{
 					ID:        test.ID,
-					XHex:      hex.EncodeToString(result[0]),
-					YHex:      hex.EncodeToString(result[1]),
 					ResultHex: hex.EncodeToString(result[2]),
-				})
+				}
+
+				if useStaticNamedFields {
+					testResponse.StaticXHex = hex.EncodeToString(result[0])
+					testResponse.StaticYHex = hex.EncodeToString(result[1])
+				} else {
+					testResponse.EphemeralXHex = hex.EncodeToString(result[0])
+					testResponse.EphemeralYHex = hex.EncodeToString(result[1])
+				}
+
+				response.Tests = append(response.Tests, testResponse)
 			}
 		}
 
diff --git a/util/fipstools/acvp/acvptool/test/vectors/KAS-ECC-SSC.bz2 b/util/fipstools/acvp/acvptool/test/vectors/KAS-ECC-SSC.bz2
index a595d49..116f253 100644
--- a/util/fipstools/acvp/acvptool/test/vectors/KAS-ECC-SSC.bz2
+++ b/util/fipstools/acvp/acvptool/test/vectors/KAS-ECC-SSC.bz2
Binary files differ
diff --git a/util/fipstools/acvp/modulewrapper/modulewrapper.cc b/util/fipstools/acvp/modulewrapper/modulewrapper.cc
index ddf91c6..01e4113 100644
--- a/util/fipstools/acvp/modulewrapper/modulewrapper.cc
+++ b/util/fipstools/acvp/modulewrapper/modulewrapper.cc
@@ -801,6 +801,12 @@
               "initiator",
               "responder"
             ]
+          },
+          "staticUnified": {
+            "kasRole": [
+              "initiator",
+              "responder"
+            ]
           }
         },
         "domainParameterGenerationMethods": [