summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/regress/lib/libcrypto/wycheproof/wycheproof.go155
1 files changed, 154 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
index dc6702c7ae..ddb6e57098 100644
--- a/src/regress/lib/libcrypto/wycheproof/wycheproof.go
+++ b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
@@ -1,4 +1,4 @@
1/* $OpenBSD: wycheproof.go,v 1.40 2018/09/02 17:05:51 tb Exp $ */ 1/* $OpenBSD: wycheproof.go,v 1.41 2018/09/02 17:12:01 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
@@ -161,6 +161,23 @@ type wycheproofTestGroupDSA struct {
161 Tests []*wycheproofTestDSA `json:"tests"` 161 Tests []*wycheproofTestDSA `json:"tests"`
162} 162}
163 163
164type wycheproofTestECDH struct {
165 TCID int `json:"tcId"`
166 Comment string `json:"comment"`
167 Public string `json:"public"`
168 Private string `json:"private"`
169 Shared string `json:"shared"`
170 Result string `json:"result"`
171 Flags []string `json:"flags"`
172}
173
174type wycheproofTestGroupECDH struct {
175 Curve string `json:"curve"`
176 Encoding string `json:"encoding"`
177 Type string `json:"type"`
178 Tests []*wycheproofTestECDH `json:"tests"`
179}
180
164type wycheproofECDSAKey struct { 181type wycheproofECDSAKey struct {
165 Curve string `json:"curve"` 182 Curve string `json:"curve"`
166 KeySize int `json:"keySize"` 183 KeySize int `json:"keySize"`
@@ -1058,6 +1075,135 @@ func runDSATestGroup(algorithm string, wtg *wycheproofTestGroupDSA) bool {
1058 return success 1075 return success
1059} 1076}
1060 1077
1078func runECDHTest(nid int, doECpoint bool, wt *wycheproofTestECDH) bool {
1079 privKey := C.EC_KEY_new_by_curve_name(C.int(nid))
1080 if privKey == nil {
1081 log.Fatalf("EC_KEY_new_by_curve_name failed")
1082 }
1083 defer C.EC_KEY_free(privKey)
1084
1085 var bnPriv *C.BIGNUM
1086 wPriv := C.CString(wt.Private)
1087 if C.BN_hex2bn(&bnPriv, wPriv) == 0 {
1088 log.Fatal("Failed to decode wPriv")
1089 }
1090 C.free(unsafe.Pointer(wPriv))
1091 defer C.BN_free(bnPriv)
1092
1093 ret := C.EC_KEY_set_private_key(privKey, bnPriv)
1094 if ret != 1 {
1095 fmt.Printf("FAIL: Test case %d (%q) - EC_KEY_set_private_key failed: got %d want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
1096 return false
1097 }
1098
1099 pub, err := hex.DecodeString(wt.Public)
1100 if err != nil {
1101 log.Fatalf("Failed to decode public key: %v", err)
1102 }
1103
1104 pubLen := len(pub)
1105 if pubLen == 0 {
1106 pub = append(pub, 0)
1107 }
1108
1109 Cpub := (*C.uchar)(C.malloc(C.ulong(pubLen)))
1110 if Cpub == nil {
1111 log.Fatal("malloc failed")
1112 }
1113 C.memcpy(unsafe.Pointer(Cpub), unsafe.Pointer(&pub[0]), C.ulong(pubLen))
1114
1115 p := (*C.uchar)(Cpub)
1116 var pubKey *C.EC_KEY
1117 if (doECpoint) {
1118 pubKey = C.EC_KEY_new_by_curve_name(C.int(nid))
1119 if pubKey == nil {
1120 log.Fatal("EC_KEY_new_by_curve_name failed")
1121 }
1122 pubKey = C.o2i_ECPublicKey(&pubKey, (**C.uchar)(&p), C.long(pubLen))
1123 } else {
1124 pubKey = C.d2i_EC_PUBKEY(nil, (**C.uchar)(&p), C.long(pubLen))
1125 }
1126 defer C.EC_KEY_free(pubKey)
1127 C.free(unsafe.Pointer(Cpub))
1128
1129 if pubKey == nil {
1130 if wt.Result == "invalid" || wt.Result == "acceptable" {
1131 return true
1132 }
1133 fmt.Printf("FAIL: Test case %d (%q) - ASN decoding failed: want %v\n", wt.TCID, wt.Comment, wt.Result)
1134 return false
1135 }
1136
1137 pubGroup := C.EC_KEY_get0_group(pubKey)
1138 privGroup := C.EC_KEY_get0_group(privKey)
1139
1140 ret = C.EC_GROUP_cmp(pubGroup, privGroup, nil)
1141 if ret != 0 {
1142 fmt.Printf("INFO: Test case %d (%q) - EC_GROUP_cmp() = %d, want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
1143 }
1144
1145 pubPoint := C.EC_KEY_get0_public_key(pubKey)
1146 ret = C.EC_POINT_is_on_curve(privGroup, pubPoint, nil)
1147 if ret != 1 {
1148 fmt.Printf("INFO: Test case %d (%q) - EC_POINT_is_on_curve failed: got %d want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
1149 }
1150
1151 secLen := (C.EC_GROUP_get_degree(privGroup) + 7) / 8
1152
1153 secret := make([]byte, secLen)
1154 if secLen == 0 {
1155 secret = append(secret, 0)
1156 }
1157
1158 ret = C.ECDH_compute_key(unsafe.Pointer(&secret[0]), C.ulong(secLen), pubPoint, privKey, nil)
1159 if ret != C.int(secLen) {
1160 if wt.Result == "invalid" {
1161 return true
1162 }
1163 fmt.Printf("FAIL: Test case %d (%q) - ECDH_compute_key() = %d, want %d, result: %v\n", wt.TCID, wt.Comment, ret, int(secLen), wt.Result)
1164 return false
1165 }
1166
1167 shared, err := hex.DecodeString(wt.Shared)
1168 if err != nil{
1169 log.Fatalf("Failed to decode shared secret: %v", err)
1170 }
1171
1172 success := true
1173 if !bytes.Equal(shared, secret) {
1174 fmt.Printf("FAIL: Test case %d (%q) - expected and computed shared secret do not match, want %v\n", wt.TCID, wt.Comment, wt.Result)
1175 success = false
1176 }
1177 return success
1178}
1179
1180func runECDHTestGroup(algorithm string, wtg *wycheproofTestGroupECDH) bool {
1181 // No secp256r1 support.
1182 if wtg.Curve == "secp256r1" {
1183 return true
1184 }
1185
1186 doECpoint := false
1187 if wtg.Encoding == "ecpoint" {
1188 doECpoint = true
1189 }
1190
1191 fmt.Printf("Running %v test group %v with curve %v and %v encoding...\n", algorithm, wtg.Type, wtg.Curve, wtg.Encoding)
1192
1193 nid, err := nidFromString(wtg.Curve)
1194 if err != nil {
1195 log.Fatalf("Failed to get nid for curve: %v", err)
1196 }
1197
1198 success := true
1199 for _, wt := range wtg.Tests {
1200 if !runECDHTest(nid, doECpoint, wt) {
1201 success = false
1202 }
1203 }
1204 return success
1205}
1206
1061func runECDSATest(ecKey *C.EC_KEY, nid int, h hash.Hash, wt *wycheproofTestECDSA) bool { 1207func runECDSATest(ecKey *C.EC_KEY, nid int, h hash.Hash, wt *wycheproofTestECDSA) bool {
1062 msg, err := hex.DecodeString(wt.Msg) 1208 msg, err := hex.DecodeString(wt.Msg)
1063 if err != nil { 1209 if err != nil {
@@ -1386,6 +1532,8 @@ func runTestVectors(path string) bool {
1386 wtg = &wycheproofTestGroupChaCha20Poly1305{} 1532 wtg = &wycheproofTestGroupChaCha20Poly1305{}
1387 case "DSA": 1533 case "DSA":
1388 wtg = &wycheproofTestGroupDSA{} 1534 wtg = &wycheproofTestGroupDSA{}
1535 case "ECDH":
1536 wtg = &wycheproofTestGroupECDH{}
1389 case "ECDSA": 1537 case "ECDSA":
1390 wtg = &wycheproofTestGroupECDSA{} 1538 wtg = &wycheproofTestGroupECDSA{}
1391 case "RSASSA-PSS": 1539 case "RSASSA-PSS":
@@ -1428,6 +1576,10 @@ func runTestVectors(path string) bool {
1428 if !runDSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupDSA)) { 1576 if !runDSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupDSA)) {
1429 success = false 1577 success = false
1430 } 1578 }
1579 case "ECDH":
1580 if !runECDHTestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupECDH)) {
1581 success = false
1582 }
1431 case "ECDSA": 1583 case "ECDSA":
1432 if !runECDSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupECDSA)) { 1584 if !runECDSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupECDSA)) {
1433 success = false 1585 success = false
@@ -1466,6 +1618,7 @@ func main() {
1466 {"AES", "aes_[cg]*[^xv]_test.json"}, // Skip AES-EAX, AES-GCM-SIV and AES-SIV-CMAC. 1618 {"AES", "aes_[cg]*[^xv]_test.json"}, // Skip AES-EAX, AES-GCM-SIV and AES-SIV-CMAC.
1467 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"}, 1619 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"},
1468 {"DSA", "dsa_test.json"}, 1620 {"DSA", "dsa_test.json"},
1621 {"ECDH", "ecdh_[^w]*test.json"}, // Skip ecdh_webcrypto_test.json for now.
1469 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now. 1622 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now.
1470 {"RSA", "rsa_*test.json"}, 1623 {"RSA", "rsa_*test.json"},
1471 {"X25519", "x25519_*test.json"}, 1624 {"X25519", "x25519_*test.json"},