diff options
| author | tb <> | 2018-10-19 06:12:35 +0000 |
|---|---|---|
| committer | tb <> | 2018-10-19 06:12:35 +0000 |
| commit | 9a0b1fb2a2110ac6df630feaf0b27291182c2854 (patch) | |
| tree | 5234063fa611d9b85714eb64c7c83113322fa20c /src | |
| parent | 977bca551a9561a1abd8ca6c1d16b17fe8ba8e26 (diff) | |
| download | openbsd-9a0b1fb2a2110ac6df630feaf0b27291182c2854.tar.gz openbsd-9a0b1fb2a2110ac6df630feaf0b27291182c2854.tar.bz2 openbsd-9a0b1fb2a2110ac6df630feaf0b27291182c2854.zip | |
Run Wycheproof testvectors for AES Key Wrap without padding (RFC 3394)
against libcrypto. Currently contains caller-side length checks that
should really be done in the library. This will be fixed after an
upcoming commit to libcrypto.
Diffstat (limited to '')
| -rw-r--r-- | src/regress/lib/libcrypto/wycheproof/wycheproof.go | 148 |
1 files changed, 144 insertions, 4 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go index 16b38331ac..bf9d09fb09 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.84 2018/10/19 04:32:33 tb Exp $ */ | 1 | /* $OpenBSD: wycheproof.go,v 1.85 2018/10/19 06:12:35 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> |
| @@ -24,6 +24,7 @@ package main | |||
| 24 | 24 | ||
| 25 | #include <string.h> | 25 | #include <string.h> |
| 26 | 26 | ||
| 27 | #include <openssl/aes.h> | ||
| 27 | #include <openssl/bio.h> | 28 | #include <openssl/bio.h> |
| 28 | #include <openssl/bn.h> | 29 | #include <openssl/bn.h> |
| 29 | #include <openssl/cmac.h> | 30 | #include <openssl/cmac.h> |
| @@ -235,6 +236,22 @@ type wycheproofTestGroupECDSAWebCrypto struct { | |||
| 235 | Tests []*wycheproofTestECDSA `json:"tests"` | 236 | Tests []*wycheproofTestECDSA `json:"tests"` |
| 236 | } | 237 | } |
| 237 | 238 | ||
| 239 | type wycheproofTestKW struct { | ||
| 240 | TCID int `json:"tcId"` | ||
| 241 | Comment string `json:"comment"` | ||
| 242 | Key string `json:"key"` | ||
| 243 | Msg string `json:"msg"` | ||
| 244 | CT string `json:"ct"` | ||
| 245 | Result string `json:"result"` | ||
| 246 | Flags []string `json:"flags"` | ||
| 247 | } | ||
| 248 | |||
| 249 | type wycheproofTestGroupKW struct { | ||
| 250 | KeySize int `json:"keySize"` | ||
| 251 | Type string `json:"type"` | ||
| 252 | Tests []*wycheproofTestKW `json:"tests"` | ||
| 253 | } | ||
| 254 | |||
| 238 | type wycheproofTestRSA struct { | 255 | type wycheproofTestRSA struct { |
| 239 | TCID int `json:"tcId"` | 256 | TCID int `json:"tcId"` |
| 240 | Comment string `json:"comment"` | 257 | Comment string `json:"comment"` |
| @@ -361,9 +378,8 @@ func printAcceptableStatistics() { | |||
| 361 | sort.Strings(comments) | 378 | sort.Strings(comments) |
| 362 | for _, comment := range comments { | 379 | for _, comment := range comments { |
| 363 | prcomment := comment | 380 | prcomment := comment |
| 364 | if len(comment) > 42 { | 381 | if len(comment) > 45 { |
| 365 | prcomment = comment[0:42] | 382 | prcomment = comment[0:42] + "..." |
| 366 | prcomment += "..." | ||
| 367 | } | 383 | } |
| 368 | fmt.Printf("%-45v %5d\n", prcomment, acceptableComments[comment]) | 384 | fmt.Printf("%-45v %5d\n", prcomment, acceptableComments[comment]) |
| 369 | } | 385 | } |
| @@ -1675,6 +1691,123 @@ func runECDSAWebCryptoTestGroup(algorithm string, wtg *wycheproofTestGroupECDSAW | |||
| 1675 | return success | 1691 | return success |
| 1676 | } | 1692 | } |
| 1677 | 1693 | ||
| 1694 | func runKWTestWrap(keySize int, key []byte, keyLen int, msg []byte, msgLen int, ct []byte, ctLen int, wt *wycheproofTestKW) bool { | ||
| 1695 | var aesKey C.AES_KEY | ||
| 1696 | |||
| 1697 | ret := C.AES_set_encrypt_key((*C.uchar)(unsafe.Pointer(&key[0])), (C.int)(keySize), (*C.AES_KEY)(unsafe.Pointer(&aesKey))) | ||
| 1698 | if ret != 0 { | ||
| 1699 | fmt.Printf("FAIL: Test case %d (%q) %v - AES_set_encrypt_key() = %d, want %v\n", | ||
| 1700 | wt.TCID, wt.Comment, wt.Flags, int(ret), wt.Result) | ||
| 1701 | return false | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | outLen := msgLen + 8 | ||
| 1705 | out := make([]byte, outLen) | ||
| 1706 | // XXX remove workaround once fix to aes_wrap.c is committed | ||
| 1707 | ret = -1 | ||
| 1708 | if msgLen > 8 { | ||
| 1709 | ret = C.AES_wrap_key((*C.AES_KEY)(unsafe.Pointer(&aesKey)), nil, (*C.uchar)(unsafe.Pointer(&out[0])), (*C.uchar)(unsafe.Pointer(&msg[0])), (C.uint)(msgLen)) | ||
| 1710 | } | ||
| 1711 | success := false | ||
| 1712 | if ret == C.int(outLen) && bytes.Equal(out, ct) { | ||
| 1713 | if acceptableAudit && wt.Result == "acceptable" { | ||
| 1714 | gatherAcceptableStatistics(wt.TCID, wt.Comment, wt.Flags) | ||
| 1715 | } | ||
| 1716 | if wt.Result != "invalid" { | ||
| 1717 | success = true | ||
| 1718 | } | ||
| 1719 | } else if wt.Result != "valid" { | ||
| 1720 | success = true | ||
| 1721 | } | ||
| 1722 | if !success { | ||
| 1723 | fmt.Printf("FAIL: Test case %d (%q) %v - msgLen = %d, AES_wrap_key() = %d, want %v\n", | ||
| 1724 | wt.TCID, wt.Comment, wt.Flags, msgLen, int(ret), wt.Result) | ||
| 1725 | } | ||
| 1726 | return success | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | func runKWTestUnWrap(keySize int, key []byte, keyLen int, msg []byte, msgLen int, ct []byte, ctLen int, wt *wycheproofTestKW) bool { | ||
| 1730 | var aesKey C.AES_KEY | ||
| 1731 | |||
| 1732 | ret := C.AES_set_decrypt_key((*C.uchar)(unsafe.Pointer(&key[0])), (C.int)(keySize), (*C.AES_KEY)(unsafe.Pointer(&aesKey))) | ||
| 1733 | if ret != 0 { | ||
| 1734 | fmt.Printf("FAIL: Test case %d (%q) %v - AES_set_encrypt_key() = %d, want %v\n", | ||
| 1735 | wt.TCID, wt.Comment, wt.Flags, int(ret), wt.Result) | ||
| 1736 | return false | ||
| 1737 | } | ||
| 1738 | |||
| 1739 | out := make([]byte, ctLen) | ||
| 1740 | if ctLen == 0 { | ||
| 1741 | out = append(out, 0) | ||
| 1742 | } | ||
| 1743 | // XXX remove workaround once fix to aes_wrap.c is committed | ||
| 1744 | ret = -1 | ||
| 1745 | if ctLen > 16 { | ||
| 1746 | ret = C.AES_unwrap_key((*C.AES_KEY)(unsafe.Pointer(&aesKey)), nil, (*C.uchar)(unsafe.Pointer(&out[0])), (*C.uchar)(unsafe.Pointer(&ct[0])), (C.uint)(ctLen)) | ||
| 1747 | } | ||
| 1748 | success := false | ||
| 1749 | if ret == C.int(ctLen - 8) && bytes.Equal(out[0:ret], msg[0:ret]) { | ||
| 1750 | if acceptableAudit && wt.Result == "acceptable" { | ||
| 1751 | gatherAcceptableStatistics(wt.TCID, wt.Comment, wt.Flags) | ||
| 1752 | } | ||
| 1753 | if wt.Result != "invalid" { | ||
| 1754 | success = true | ||
| 1755 | } | ||
| 1756 | } else if wt.Result != "valid" { | ||
| 1757 | success = true | ||
| 1758 | } | ||
| 1759 | if !success { | ||
| 1760 | fmt.Printf("FAIL: Test case %d (%q) %v - keyLen = %d, AES_unwrap_key() = %d, want %v\n", | ||
| 1761 | wt.TCID, wt.Comment, wt.Flags, keyLen, int(ret), wt.Result) | ||
| 1762 | } | ||
| 1763 | return success | ||
| 1764 | } | ||
| 1765 | |||
| 1766 | func runKWTest(keySize int, wt *wycheproofTestKW) bool { | ||
| 1767 | key, err := hex.DecodeString(wt.Key) | ||
| 1768 | if err != nil { | ||
| 1769 | log.Fatalf("Failed to decode key %q: %v", wt.Key, err) | ||
| 1770 | } | ||
| 1771 | msg, err := hex.DecodeString(wt.Msg) | ||
| 1772 | if err != nil { | ||
| 1773 | log.Fatalf("Failed to decode msg %q: %v", wt.Msg, err) | ||
| 1774 | } | ||
| 1775 | ct, err := hex.DecodeString(wt.CT) | ||
| 1776 | if err != nil { | ||
| 1777 | log.Fatalf("Failed to decode ct %q: %v", wt.CT, err) | ||
| 1778 | } | ||
| 1779 | |||
| 1780 | keyLen, msgLen, ctLen := len(key), len(msg), len(ct) | ||
| 1781 | |||
| 1782 | if keyLen == 0 { | ||
| 1783 | key = append(key, 0) | ||
| 1784 | } | ||
| 1785 | if msgLen == 0 { | ||
| 1786 | msg = append(msg, 0) | ||
| 1787 | } | ||
| 1788 | if ctLen == 0 { | ||
| 1789 | ct = append(ct, 0) | ||
| 1790 | } | ||
| 1791 | |||
| 1792 | wrapSuccess := runKWTestWrap(keySize, key, keyLen, msg, msgLen, ct, ctLen, wt) | ||
| 1793 | unwrapSuccess := runKWTestUnWrap(keySize, key, keyLen, msg, msgLen, ct, ctLen, wt) | ||
| 1794 | |||
| 1795 | return wrapSuccess && unwrapSuccess | ||
| 1796 | } | ||
| 1797 | |||
| 1798 | func runKWTestGroup(algorithm string, wtg *wycheproofTestGroupKW) bool { | ||
| 1799 | fmt.Printf("Running %v test group %v with key size %d...\n", | ||
| 1800 | algorithm, wtg.Type, wtg.KeySize) | ||
| 1801 | |||
| 1802 | success := true | ||
| 1803 | for _, wt := range wtg.Tests { | ||
| 1804 | if !runKWTest(wtg.KeySize, wt) { | ||
| 1805 | success = false | ||
| 1806 | } | ||
| 1807 | } | ||
| 1808 | return success | ||
| 1809 | } | ||
| 1810 | |||
| 1678 | func runRSASSATest(rsa *C.RSA, h hash.Hash, sha *C.EVP_MD, mgfSha *C.EVP_MD, sLen int, wt *wycheproofTestRSASSA) bool { | 1811 | func runRSASSATest(rsa *C.RSA, h hash.Hash, sha *C.EVP_MD, mgfSha *C.EVP_MD, sLen int, wt *wycheproofTestRSASSA) bool { |
| 1679 | msg, err := hex.DecodeString(wt.Msg) | 1812 | msg, err := hex.DecodeString(wt.Msg) |
| 1680 | if err != nil { | 1813 | if err != nil { |
| @@ -1944,6 +2077,8 @@ func runTestVectors(path string, webcrypto bool) bool { | |||
| 1944 | } else { | 2077 | } else { |
| 1945 | wtg = &wycheproofTestGroupECDSA{} | 2078 | wtg = &wycheproofTestGroupECDSA{} |
| 1946 | } | 2079 | } |
| 2080 | case "KW": | ||
| 2081 | wtg = &wycheproofTestGroupKW{} | ||
| 1947 | case "RSASSA-PSS": | 2082 | case "RSASSA-PSS": |
| 1948 | wtg = &wycheproofTestGroupRSASSA{} | 2083 | wtg = &wycheproofTestGroupRSASSA{} |
| 1949 | case "RSASig": | 2084 | case "RSASig": |
| @@ -2004,6 +2139,10 @@ func runTestVectors(path string, webcrypto bool) bool { | |||
| 2004 | success = false | 2139 | success = false |
| 2005 | } | 2140 | } |
| 2006 | } | 2141 | } |
| 2142 | case "KW": | ||
| 2143 | if !runKWTestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupKW)) { | ||
| 2144 | success = false | ||
| 2145 | } | ||
| 2007 | case "RSASSA-PSS": | 2146 | case "RSASSA-PSS": |
| 2008 | if !runRSASSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupRSASSA)) { | 2147 | if !runRSASSATestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupRSASSA)) { |
| 2009 | success = false | 2148 | success = false |
| @@ -2047,6 +2186,7 @@ func main() { | |||
| 2047 | {"ECDHWebCrypto", "ecdh_w*_test.json"}, | 2186 | {"ECDHWebCrypto", "ecdh_w*_test.json"}, |
| 2048 | {"ECDSA", "ecdsa_[^w]*test.json"}, | 2187 | {"ECDSA", "ecdsa_[^w]*test.json"}, |
| 2049 | {"ECDSAWebCrypto", "ecdsa_w*_test.json"}, | 2188 | {"ECDSAWebCrypto", "ecdsa_w*_test.json"}, |
| 2189 | {"KW", "kw_test.json"}, | ||
| 2050 | {"RSA", "rsa_*test.json"}, | 2190 | {"RSA", "rsa_*test.json"}, |
| 2051 | {"X25519", "x25519_*test.json"}, | 2191 | {"X25519", "x25519_*test.json"}, |
| 2052 | } | 2192 | } |
