diff options
author | Theo Buehler <tb@cvs.openbsd.org> | 2018-09-01 05:56:25 +0000 |
---|---|---|
committer | Theo Buehler <tb@cvs.openbsd.org> | 2018-09-01 05:56:25 +0000 |
commit | d8891aabcba4873c640efd362145a1eadfcd9861 (patch) | |
tree | 6582486173f1eb9ce2311d004df21c1996e538af | |
parent | 57a5fe971780a661ad53c9c44d6508b09e736a62 (diff) |
Run Wycheproof RSASSA-PSS testvectors against libcrypto.
-rw-r--r-- | regress/lib/libcrypto/wycheproof/wycheproof.go | 146 |
1 files changed, 144 insertions, 2 deletions
diff --git a/regress/lib/libcrypto/wycheproof/wycheproof.go b/regress/lib/libcrypto/wycheproof/wycheproof.go index 70dd99b6cde..21c9d1aae1b 100644 --- a/regress/lib/libcrypto/wycheproof/wycheproof.go +++ b/regress/lib/libcrypto/wycheproof/wycheproof.go @@ -1,4 +1,4 @@ -/* $OpenBSD: wycheproof.go,v 1.37 2018/08/29 19:22:32 tb Exp $ */ +/* $OpenBSD: wycheproof.go,v 1.38 2018/09/01 05:56:24 tb Exp $ */ /* * Copyright (c) 2018 Joel Sing <jsing@openbsd.org> * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> @@ -210,6 +210,30 @@ type wycheproofTestGroupRSA struct { Tests []*wycheproofTestRSA `json:"tests"` } +type wycheproofTestRSASSA struct { + TCID int `json:"tcId"` + Comment string `json:"comment"` + Msg string `json:"msg"` + Sig string `json:"sig"` + Result string `json:"result"` + Flags []string `json:"flags"` +} + +type wycheproofTestGroupRSASSA struct { + E string `json:"e"` + KeyASN string `json:"keyAsn"` + KeyDER string `json:"keyDer"` + KeyPEM string `json:"keyPem"` + KeySize int `json:"keysize"` + MGF string `json:"mgf"` + MGFSHA string `json:"mgfSha"` + N string `json:"n"` + SLen int `json:"sLen"` + SHA string `json:"sha"` + Type string `json:"type"` + Tests []*wycheproofTestRSASSA `json:"tests"` +} + type wycheproofTestX25519 struct { TCID int `json:"tcId"` Comment string `json:"comment"` @@ -282,6 +306,23 @@ func hashFromString(hs string) (hash.Hash, error) { } } +func hashEvpMdFromString(hs string) (*C.EVP_MD, error) { + switch hs { + case "SHA-1": + return C.EVP_sha1(), nil + case "SHA-224": + return C.EVP_sha224(), nil + case "SHA-256": + return C.EVP_sha256(), nil + case "SHA-384": + return C.EVP_sha384(), nil + case "SHA-512": + return C.EVP_sha512(), nil + default: + return nil, fmt.Errorf("unknown hash %q", hs) + } +} + 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 { var action string if doEncrypt == 1 { @@ -1105,6 +1146,101 @@ func runECDSATestGroup(algorithm string, wtg *wycheproofTestGroupECDSA) bool { return success } +func runRSASSATest(rsa *C.RSA, h hash.Hash, sha *C.EVP_MD, mgfSha *C.EVP_MD, sLen int, wt *wycheproofTestRSASSA) bool { + msg, err := hex.DecodeString(wt.Msg) + if err != nil { + log.Fatalf("Failed to decode message %q: %v", wt.Msg, err) + } + + h.Reset() + h.Write(msg) + msg = h.Sum(nil) + + sig, err := hex.DecodeString(wt.Sig) + if err != nil { + log.Fatalf("Failed to decode signature %q: %v", wt.Sig, err) + } + + msgLen, sigLen := len(msg), len(sig) + if msgLen == 0 { + msg = append(msg, 0) + } + if sigLen == 0 { + sig = append(sig, 0) + } + + sigOut := make([]byte, sigLen) + if sigLen == 0 { + sigOut = append(sigOut, 0) + } + + 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) + if ret == -1 { + if wt.Result == "invalid" { + return true + } + fmt.Printf("FAIL: Test case %d (%q) - RSA_public_decrypt() = %d, want %v\n", wt.TCID, wt.Comment, int(ret), wt.Result) + return false + } + + 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)) + + // XXX: audit acceptable cases... + success := false + if ret == 1 && (wt.Result == "valid" || wt.Result == "acceptable") { + success = true + } else if ret == 0 && (wt.Result == "invalid" || wt.Result == "acceptable") { + success = true + } else { + fmt.Printf("FAIL: Test case %d (%q) - RSA_verify_PKCS1_PSS_mgf1() = %d, want %v\n", wt.TCID, wt.Comment, int(ret), wt.Result) + } + return success +} + +func runRSASSATestGroup(algorithm string, wtg *wycheproofTestGroupRSASSA) bool { + fmt.Printf("Running %v test group %v with key size %d and %v...\n", algorithm, wtg.Type, wtg.KeySize, wtg.SHA) + rsa := C.RSA_new() + if rsa == nil { + log.Fatal("RSA_new failed") + } + defer C.RSA_free(rsa) + + e := C.CString(wtg.E) + if C.BN_hex2bn(&rsa.e, e) == 0 { + log.Fatal("Failed to set RSA e") + } + C.free(unsafe.Pointer(e)) + + n := C.CString(wtg.N) + if C.BN_hex2bn(&rsa.n, n) == 0 { + log.Fatal("Failed to set RSA n") + } + C.free(unsafe.Pointer(n)) + + h, err := hashFromString(wtg.SHA) + if err != nil { + log.Fatalf("Failed to get hash: %v", err) + } + + sha, err := hashEvpMdFromString(wtg.SHA) + if err != nil { + log.Fatalf("Failed to get hash: %v", err) + } + + mgfSha, err := hashEvpMdFromString(wtg.MGFSHA) + if err != nil { + log.Fatalf("Failed to get MGF hash: %v", err) + } + + success := true + for _, wt := range wtg.Tests { + if !runRSASSATest(rsa, h, sha, mgfSha, wtg.SLen, wt) { + success = false + } + } + return success +} + func runRSATest(rsa *C.RSA, nid int, h hash.Hash, wt *wycheproofTestRSA) bool { msg, err := hex.DecodeString(wt.Msg) if err != nil { @@ -1250,6 +1386,8 @@ func runTestVectors(path string) bool { wtg = &wycheproofTestGroupDSA{} case "ECDSA": wtg = &wycheproofTestGroupECDSA{} + case "RSASSA-PSS": + wtg = &wycheproofTestGroupRSASSA{} case "RSASig": wtg = &wycheproofTestGroupRSA{} case "X25519": @@ -1292,6 +1430,10 @@ func runTestVectors(path string) bool { if !runECDSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupECDSA)) { success = false } + case "RSASSA-PSS": + if !runRSASSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupRSASSA)) { + success = false + } case "RSASig": if !runRSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupRSA)) { success = false @@ -1323,7 +1465,7 @@ func main() { {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"}, {"DSA", "dsa_test.json"}, {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now. - {"RSA signature", "rsa_signature_*test.json"}, + {"RSA", "rsa_*test.json"}, {"X25519", "x25519_*test.json"}, } |