diff options
| author | tb <> | 2018-09-01 05:56:24 +0000 |
|---|---|---|
| committer | tb <> | 2018-09-01 05:56:24 +0000 |
| commit | 26f747fc220b10eb50df18cf29515fbe91993a4b (patch) | |
| tree | c10341ccb824d2e6f5c86760c7f7e7acb50a4f3e /src | |
| parent | ab82fc96211b03411f245a194d52f6ef86aa12d5 (diff) | |
| download | openbsd-26f747fc220b10eb50df18cf29515fbe91993a4b.tar.gz openbsd-26f747fc220b10eb50df18cf29515fbe91993a4b.tar.bz2 openbsd-26f747fc220b10eb50df18cf29515fbe91993a4b.zip | |
Run Wycheproof RSASSA-PSS testvectors against libcrypto.
Diffstat (limited to '')
| -rw-r--r-- | src/regress/lib/libcrypto/wycheproof/wycheproof.go | 146 |
1 files changed, 144 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go index 70dd99b6cd..21c9d1aae1 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.37 2018/08/29 19:22:32 tb Exp $ */ | 1 | /* $OpenBSD: wycheproof.go,v 1.38 2018/09/01 05:56:24 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> |
| @@ -210,6 +210,30 @@ type wycheproofTestGroupRSA struct { | |||
| 210 | Tests []*wycheproofTestRSA `json:"tests"` | 210 | Tests []*wycheproofTestRSA `json:"tests"` |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | type wycheproofTestRSASSA struct { | ||
| 214 | TCID int `json:"tcId"` | ||
| 215 | Comment string `json:"comment"` | ||
| 216 | Msg string `json:"msg"` | ||
| 217 | Sig string `json:"sig"` | ||
| 218 | Result string `json:"result"` | ||
| 219 | Flags []string `json:"flags"` | ||
| 220 | } | ||
| 221 | |||
| 222 | type wycheproofTestGroupRSASSA struct { | ||
| 223 | E string `json:"e"` | ||
| 224 | KeyASN string `json:"keyAsn"` | ||
| 225 | KeyDER string `json:"keyDer"` | ||
| 226 | KeyPEM string `json:"keyPem"` | ||
| 227 | KeySize int `json:"keysize"` | ||
| 228 | MGF string `json:"mgf"` | ||
| 229 | MGFSHA string `json:"mgfSha"` | ||
| 230 | N string `json:"n"` | ||
| 231 | SLen int `json:"sLen"` | ||
| 232 | SHA string `json:"sha"` | ||
| 233 | Type string `json:"type"` | ||
| 234 | Tests []*wycheproofTestRSASSA `json:"tests"` | ||
| 235 | } | ||
| 236 | |||
| 213 | type wycheproofTestX25519 struct { | 237 | type wycheproofTestX25519 struct { |
| 214 | TCID int `json:"tcId"` | 238 | TCID int `json:"tcId"` |
| 215 | Comment string `json:"comment"` | 239 | Comment string `json:"comment"` |
| @@ -282,6 +306,23 @@ func hashFromString(hs string) (hash.Hash, error) { | |||
| 282 | } | 306 | } |
| 283 | } | 307 | } |
| 284 | 308 | ||
| 309 | func hashEvpMdFromString(hs string) (*C.EVP_MD, error) { | ||
| 310 | switch hs { | ||
| 311 | case "SHA-1": | ||
| 312 | return C.EVP_sha1(), nil | ||
| 313 | case "SHA-224": | ||
| 314 | return C.EVP_sha224(), nil | ||
| 315 | case "SHA-256": | ||
| 316 | return C.EVP_sha256(), nil | ||
| 317 | case "SHA-384": | ||
| 318 | return C.EVP_sha384(), nil | ||
| 319 | case "SHA-512": | ||
| 320 | return C.EVP_sha512(), nil | ||
| 321 | default: | ||
| 322 | return nil, fmt.Errorf("unknown hash %q", hs) | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 285 | func checkAesCbcPkcs5(ctx *C.EVP_CIPHER_CTX, doEncrypt int, key []byte, keyLen int, iv []byte, ivLen int, in []byte, inLen int, out []byte, outLen int, wt *wycheproofTestAesCbcPkcs5) bool { | 326 | func checkAesCbcPkcs5(ctx *C.EVP_CIPHER_CTX, doEncrypt int, key []byte, keyLen int, iv []byte, ivLen int, in []byte, inLen int, out []byte, outLen int, wt *wycheproofTestAesCbcPkcs5) bool { |
| 286 | var action string | 327 | var action string |
| 287 | if doEncrypt == 1 { | 328 | if doEncrypt == 1 { |
| @@ -1105,6 +1146,101 @@ func runECDSATestGroup(algorithm string, wtg *wycheproofTestGroupECDSA) bool { | |||
| 1105 | return success | 1146 | return success |
| 1106 | } | 1147 | } |
| 1107 | 1148 | ||
| 1149 | func runRSASSATest(rsa *C.RSA, h hash.Hash, sha *C.EVP_MD, mgfSha *C.EVP_MD, sLen int, wt *wycheproofTestRSASSA) bool { | ||
| 1150 | msg, err := hex.DecodeString(wt.Msg) | ||
| 1151 | if err != nil { | ||
| 1152 | log.Fatalf("Failed to decode message %q: %v", wt.Msg, err) | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | h.Reset() | ||
| 1156 | h.Write(msg) | ||
| 1157 | msg = h.Sum(nil) | ||
| 1158 | |||
| 1159 | sig, err := hex.DecodeString(wt.Sig) | ||
| 1160 | if err != nil { | ||
| 1161 | log.Fatalf("Failed to decode signature %q: %v", wt.Sig, err) | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | msgLen, sigLen := len(msg), len(sig) | ||
| 1165 | if msgLen == 0 { | ||
| 1166 | msg = append(msg, 0) | ||
| 1167 | } | ||
| 1168 | if sigLen == 0 { | ||
| 1169 | sig = append(sig, 0) | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | sigOut := make([]byte, sigLen) | ||
| 1173 | if sigLen == 0 { | ||
| 1174 | sigOut = append(sigOut, 0) | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | ret := C.RSA_public_decrypt(C.int(sigLen), (*C.uchar)(unsafe.Pointer(&sig[0])), (*C.uchar)(unsafe.Pointer(&sigOut[0])), rsa, C.RSA_NO_PADDING) | ||
| 1178 | if ret == -1 { | ||
| 1179 | if wt.Result == "invalid" { | ||
| 1180 | return true | ||
| 1181 | } | ||
| 1182 | fmt.Printf("FAIL: Test case %d (%q) - RSA_public_decrypt() = %d, want %v\n", wt.TCID, wt.Comment, int(ret), wt.Result) | ||
| 1183 | return false | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | ret = C.RSA_verify_PKCS1_PSS_mgf1(rsa, (*C.uchar)(unsafe.Pointer(&msg[0])), sha, mgfSha, (*C.uchar)(unsafe.Pointer(&sigOut[0])), C.int(sLen)) | ||
| 1187 | |||
| 1188 | // XXX: audit acceptable cases... | ||
| 1189 | success := false | ||
| 1190 | if ret == 1 && (wt.Result == "valid" || wt.Result == "acceptable") { | ||
| 1191 | success = true | ||
| 1192 | } else if ret == 0 && (wt.Result == "invalid" || wt.Result == "acceptable") { | ||
| 1193 | success = true | ||
| 1194 | } else { | ||
| 1195 | fmt.Printf("FAIL: Test case %d (%q) - RSA_verify_PKCS1_PSS_mgf1() = %d, want %v\n", wt.TCID, wt.Comment, int(ret), wt.Result) | ||
| 1196 | } | ||
| 1197 | return success | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | func runRSASSATestGroup(algorithm string, wtg *wycheproofTestGroupRSASSA) bool { | ||
| 1201 | fmt.Printf("Running %v test group %v with key size %d and %v...\n", algorithm, wtg.Type, wtg.KeySize, wtg.SHA) | ||
| 1202 | rsa := C.RSA_new() | ||
| 1203 | if rsa == nil { | ||
| 1204 | log.Fatal("RSA_new failed") | ||
| 1205 | } | ||
| 1206 | defer C.RSA_free(rsa) | ||
| 1207 | |||
| 1208 | e := C.CString(wtg.E) | ||
| 1209 | if C.BN_hex2bn(&rsa.e, e) == 0 { | ||
| 1210 | log.Fatal("Failed to set RSA e") | ||
| 1211 | } | ||
| 1212 | C.free(unsafe.Pointer(e)) | ||
| 1213 | |||
| 1214 | n := C.CString(wtg.N) | ||
| 1215 | if C.BN_hex2bn(&rsa.n, n) == 0 { | ||
| 1216 | log.Fatal("Failed to set RSA n") | ||
| 1217 | } | ||
| 1218 | C.free(unsafe.Pointer(n)) | ||
| 1219 | |||
| 1220 | h, err := hashFromString(wtg.SHA) | ||
| 1221 | if err != nil { | ||
| 1222 | log.Fatalf("Failed to get hash: %v", err) | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | sha, err := hashEvpMdFromString(wtg.SHA) | ||
| 1226 | if err != nil { | ||
| 1227 | log.Fatalf("Failed to get hash: %v", err) | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | mgfSha, err := hashEvpMdFromString(wtg.MGFSHA) | ||
| 1231 | if err != nil { | ||
| 1232 | log.Fatalf("Failed to get MGF hash: %v", err) | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | success := true | ||
| 1236 | for _, wt := range wtg.Tests { | ||
| 1237 | if !runRSASSATest(rsa, h, sha, mgfSha, wtg.SLen, wt) { | ||
| 1238 | success = false | ||
| 1239 | } | ||
| 1240 | } | ||
| 1241 | return success | ||
| 1242 | } | ||
| 1243 | |||
| 1108 | func runRSATest(rsa *C.RSA, nid int, h hash.Hash, wt *wycheproofTestRSA) bool { | 1244 | func runRSATest(rsa *C.RSA, nid int, h hash.Hash, wt *wycheproofTestRSA) bool { |
| 1109 | msg, err := hex.DecodeString(wt.Msg) | 1245 | msg, err := hex.DecodeString(wt.Msg) |
| 1110 | if err != nil { | 1246 | if err != nil { |
| @@ -1250,6 +1386,8 @@ func runTestVectors(path string) bool { | |||
| 1250 | wtg = &wycheproofTestGroupDSA{} | 1386 | wtg = &wycheproofTestGroupDSA{} |
| 1251 | case "ECDSA": | 1387 | case "ECDSA": |
| 1252 | wtg = &wycheproofTestGroupECDSA{} | 1388 | wtg = &wycheproofTestGroupECDSA{} |
| 1389 | case "RSASSA-PSS": | ||
| 1390 | wtg = &wycheproofTestGroupRSASSA{} | ||
| 1253 | case "RSASig": | 1391 | case "RSASig": |
| 1254 | wtg = &wycheproofTestGroupRSA{} | 1392 | wtg = &wycheproofTestGroupRSA{} |
| 1255 | case "X25519": | 1393 | case "X25519": |
| @@ -1292,6 +1430,10 @@ func runTestVectors(path string) bool { | |||
| 1292 | if !runECDSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupECDSA)) { | 1430 | if !runECDSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupECDSA)) { |
| 1293 | success = false | 1431 | success = false |
| 1294 | } | 1432 | } |
| 1433 | case "RSASSA-PSS": | ||
| 1434 | if !runRSASSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupRSASSA)) { | ||
| 1435 | success = false | ||
| 1436 | } | ||
| 1295 | case "RSASig": | 1437 | case "RSASig": |
| 1296 | if !runRSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupRSA)) { | 1438 | if !runRSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupRSA)) { |
| 1297 | success = false | 1439 | success = false |
| @@ -1323,7 +1465,7 @@ func main() { | |||
| 1323 | {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"}, | 1465 | {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"}, |
| 1324 | {"DSA", "dsa_test.json"}, | 1466 | {"DSA", "dsa_test.json"}, |
| 1325 | {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now. | 1467 | {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now. |
| 1326 | {"RSA signature", "rsa_signature_*test.json"}, | 1468 | {"RSA", "rsa_*test.json"}, |
| 1327 | {"X25519", "x25519_*test.json"}, | 1469 | {"X25519", "x25519_*test.json"}, |
| 1328 | } | 1470 | } |
| 1329 | 1471 | ||
