diff options
| author | tb <> | 2018-09-02 17:12:01 +0000 |
|---|---|---|
| committer | tb <> | 2018-09-02 17:12:01 +0000 |
| commit | 3fb96290089d394bea5927f746d82d949294e08d (patch) | |
| tree | e786b395f768e963dc594e04853acacf84f540af /src | |
| parent | 642995eb540079c48359b9b455fed554e2277c10 (diff) | |
| download | openbsd-3fb96290089d394bea5927f746d82d949294e08d.tar.gz openbsd-3fb96290089d394bea5927f746d82d949294e08d.tar.bz2 openbsd-3fb96290089d394bea5927f746d82d949294e08d.zip | |
Run Wycheproof ECDH tests against libcrypto. Some tests currently fail,
will be fixed with the next commit to libcrypto.
Diffstat (limited to 'src')
| -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"}, |
