diff options
author | tb <> | 2018-09-02 17:12:01 +0000 |
---|---|---|
committer | tb <> | 2018-09-02 17:12:01 +0000 |
commit | 9200435a5b6465d7acbe3e3c950e8d6438edab09 (patch) | |
tree | e786b395f768e963dc594e04853acacf84f540af | |
parent | acfaa0edfd1a46405f11f084ce62e978607b876f (diff) | |
download | openbsd-9200435a5b6465d7acbe3e3c950e8d6438edab09.tar.gz openbsd-9200435a5b6465d7acbe3e3c950e8d6438edab09.tar.bz2 openbsd-9200435a5b6465d7acbe3e3c950e8d6438edab09.zip |
Run Wycheproof ECDH tests against libcrypto. Some tests currently fail,
will be fixed with the next commit to libcrypto.
-rw-r--r-- | src/regress/lib/libcrypto/wycheproof/wycheproof.go | 155 |
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 | ||
164 | type 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 | |||
174 | type wycheproofTestGroupECDH struct { | ||
175 | Curve string `json:"curve"` | ||
176 | Encoding string `json:"encoding"` | ||
177 | Type string `json:"type"` | ||
178 | Tests []*wycheproofTestECDH `json:"tests"` | ||
179 | } | ||
180 | |||
164 | type wycheproofECDSAKey struct { | 181 | type 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 | ||
1078 | func 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 | |||
1180 | func 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 | |||
1061 | func runECDSATest(ecKey *C.EC_KEY, nid int, h hash.Hash, wt *wycheproofTestECDSA) bool { | 1207 | func 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"}, |