diff options
author | tb <> | 2018-10-19 06:12:35 +0000 |
---|---|---|
committer | tb <> | 2018-10-19 06:12:35 +0000 |
commit | bd9d0fa01a7b5e725f3ae942e2d42284412f124f (patch) | |
tree | 5234063fa611d9b85714eb64c7c83113322fa20c | |
parent | 77f800f7d1369066cc202768be42c85b07c9f78d (diff) | |
download | openbsd-bd9d0fa01a7b5e725f3ae942e2d42284412f124f.tar.gz openbsd-bd9d0fa01a7b5e725f3ae942e2d42284412f124f.tar.bz2 openbsd-bd9d0fa01a7b5e725f3ae942e2d42284412f124f.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.
-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 | } |