summaryrefslogtreecommitdiffstats
path: root/net/test
diff options
context:
space:
mode:
authorYan Yan <evitayan@google.com>2020-08-03 10:24:01 -0700
committerYan Yan <evitayan@google.com>2020-09-24 11:30:20 -0700
commitc8567e2f6c91b3713e3db106f496f22247428a7f (patch)
tree5e26e7fd69d15c1f7081975d9ad5c6bdc9503926 /net/test
parentf1210e99275ffc932755731d02504c02bd8ed26d (diff)
downloadkernel_tests-c8567e2f6c91b3713e3db106f496f22247428a7f.tar.gz
kernel_tests-c8567e2f6c91b3713e3db106f496f22247428a7f.tar.bz2
kernel_tests-c8567e2f6c91b3713e3db106f496f22247428a7f.zip
Kernel tests for AES-CTR, AES-XCBC, ChaChaPoly
Tested on 4.19: - without config set, tests were bypassed - with config set, tests ran and passed Tested on 5.9 (android-mainline) - without config set, tests ran and failed - with config set, tests ran and passed Bug: 161717358 Test: xfrm_algorithm_test.py Signed-off-by: Yan Yan <evitayan@google.com> Change-Id: I12cd15f00ae9b3f8cc793d4b7200f895f63c2e12
Diffstat (limited to 'net/test')
-rwxr-xr-xnet/test/net_test.py2
-rwxr-xr-xnet/test/xfrm.py3
-rwxr-xr-xnet/test/xfrm_algorithm_test.py155
3 files changed, 132 insertions, 28 deletions
diff --git a/net/test/net_test.py b/net/test/net_test.py
index 1c9c1c47..50b24b77 100755
--- a/net/test/net_test.py
+++ b/net/test/net_test.py
@@ -91,7 +91,7 @@ AID_INET = 3003
KERN_INFO = 6
LINUX_VERSION = csocket.LinuxVersion()
-
+LINUX_ANY_VERSION = (0, 0)
def GetWildcardAddress(version):
return {4: "0.0.0.0", 6: "::"}[version]
diff --git a/net/test/xfrm.py b/net/test/xfrm.py
index d8f5ffec..c63d2a28 100755
--- a/net/test/xfrm.py
+++ b/net/test/xfrm.py
@@ -123,12 +123,15 @@ XFRM_STATE_AF_UNSPEC = 32
# XFRM algorithm names, as defined in net/xfrm/xfrm_algo.c.
XFRM_EALG_CBC_AES = "cbc(aes)"
+XFRM_EALG_CTR_AES = "rfc3686(ctr(aes))"
XFRM_AALG_HMAC_MD5 = "hmac(md5)"
XFRM_AALG_HMAC_SHA1 = "hmac(sha1)"
XFRM_AALG_HMAC_SHA256 = "hmac(sha256)"
XFRM_AALG_HMAC_SHA384 = "hmac(sha384)"
XFRM_AALG_HMAC_SHA512 = "hmac(sha512)"
+XFRM_AALG_AUTH_XCBC_AES = "xcbc(aes)"
XFRM_AEAD_GCM_AES = "rfc4106(gcm(aes))"
+XFRM_AEAD_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)"
# Data structure formats.
# These aren't constants, they're classes. So, pylint: disable=invalid-name
diff --git a/net/test/xfrm_algorithm_test.py b/net/test/xfrm_algorithm_test.py
index c2f836c4..8a50fdec 100755
--- a/net/test/xfrm_algorithm_test.py
+++ b/net/test/xfrm_algorithm_test.py
@@ -30,29 +30,43 @@ from tun_twister import TapTwister
import util
import xfrm
import xfrm_base
+import xfrm_test
+
+ANY_KVER = net_test.LINUX_ANY_VERSION
# List of encryption algorithms for use in ParamTests.
CRYPT_ALGOS = [
- xfrm.XfrmAlgo((xfrm.XFRM_EALG_CBC_AES, 128)),
- xfrm.XfrmAlgo((xfrm.XFRM_EALG_CBC_AES, 192)),
- xfrm.XfrmAlgo((xfrm.XFRM_EALG_CBC_AES, 256)),
+ (xfrm.XfrmAlgo((xfrm.XFRM_EALG_CBC_AES, 128)), ANY_KVER),
+ (xfrm.XfrmAlgo((xfrm.XFRM_EALG_CBC_AES, 192)), ANY_KVER),
+ (xfrm.XfrmAlgo((xfrm.XFRM_EALG_CBC_AES, 256)), ANY_KVER),
+ # RFC 3686 specifies that key length must be 128, 192 or 256 bits, with
+ # an additional 4 bytes (32 bits) of nonce. A fresh nonce value MUST be
+ # assigned for each SA.
+ # CTR-AES is enforced since kernel version 5.8
+ (xfrm.XfrmAlgo((xfrm.XFRM_EALG_CTR_AES, 128+32)), (5, 8)),
+ (xfrm.XfrmAlgo((xfrm.XFRM_EALG_CTR_AES, 192+32)), (5, 8)),
+ (xfrm.XfrmAlgo((xfrm.XFRM_EALG_CTR_AES, 256+32)), (5, 8)),
]
# List of auth algorithms for use in ParamTests.
AUTH_ALGOS = [
# RFC 4868 specifies that the only supported truncation length is half the
# hash size.
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_MD5, 128, 96)),
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA1, 160, 96)),
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA256, 256, 128)),
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA384, 384, 192)),
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA512, 512, 256)),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_MD5, 128, 96)), ANY_KVER),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA1, 160, 96)), ANY_KVER),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA256, 256, 128)), ANY_KVER),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA384, 384, 192)), ANY_KVER),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA512, 512, 256)), ANY_KVER),
# Test larger truncation lengths for good measure.
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_MD5, 128, 128)),
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA1, 160, 160)),
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA256, 256, 256)),
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA384, 384, 384)),
- xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA512, 512, 512)),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_MD5, 128, 128)), ANY_KVER),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA1, 160, 160)), ANY_KVER),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA256, 256, 256)), ANY_KVER),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA384, 384, 384)), ANY_KVER),
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_HMAC_SHA512, 512, 512)), ANY_KVER),
+ # RFC 3566 specifies that the only supported truncation length
+ # is 96 bits.
+ # XCBC-AES is enforced since kernel version 5.8
+ (xfrm.XfrmAlgoAuth((xfrm.XFRM_AALG_AUTH_XCBC_AES, 128, 96)), (5, 8)),
]
# List of aead algorithms for use in ParamTests.
@@ -61,17 +75,88 @@ AEAD_ALGOS = [
# with an additional 4 bytes (32 bits) of salt. The salt must be unique
# for each new SA using the same key.
# RFC 4106 specifies that ICV length must be 8, 12, or 16 bytes
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 128+32, 8*8)),
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 128+32, 12*8)),
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 128+32, 16*8)),
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 192+32, 8*8)),
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 192+32, 12*8)),
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 192+32, 16*8)),
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 256+32, 8*8)),
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 256+32, 12*8)),
- xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 256+32, 16*8)),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 128+32, 8*8)), ANY_KVER),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 128+32, 12*8)), ANY_KVER),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 128+32, 16*8)), ANY_KVER),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 192+32, 8*8)), ANY_KVER),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 192+32, 12*8)), ANY_KVER),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 192+32, 16*8)), ANY_KVER),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 256+32, 8*8)), ANY_KVER),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 256+32, 12*8)), ANY_KVER),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_GCM_AES, 256+32, 16*8)), ANY_KVER),
+ # RFC 7634 specifies that key length must be 256 bits, with an additional
+ # 4 bytes (32 bits) of nonce. A fresh nonce value MUST be assigned for
+ # each SA. RFC 7634 also specifies that ICV length must be 16 bytes.
+ # ChaCha20-Poly1305 is enforced since kernel version 5.8
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_CHACHA20_POLY1305, 256+32, 16*8)), (5, 8)),
]
+def GenerateKey(key_len):
+ if key_len % 8 != 0:
+ raise ValueError("Invalid key length in bits: " + str(key_len))
+ return os.urandom(key_len / 8)
+
+# Does the kernel support this algorithm?
+def HaveAlgo(crypt_algo, auth_algo, aead_algo):
+ try:
+ test_xfrm = xfrm.Xfrm()
+ test_xfrm.FlushSaInfo()
+ test_xfrm.FlushPolicyInfo()
+
+ test_xfrm.AddSaInfo(
+ src=xfrm_test.TEST_ADDR1,
+ dst=xfrm_test.TEST_ADDR2,
+ spi=xfrm_test.TEST_SPI,
+ mode=xfrm.XFRM_MODE_TRANSPORT,
+ reqid=100,
+ encryption=(crypt_algo,
+ GenerateKey(crypt_algo.key_len)) if crypt_algo else None,
+ auth_trunc=(auth_algo,
+ GenerateKey(auth_algo.key_len)) if auth_algo else None,
+ aead=(aead_algo, GenerateKey(aead_algo.key_len)) if aead_algo else None,
+ encap=None,
+ mark=None,
+ output_mark=None)
+
+ test_xfrm.FlushSaInfo()
+ test_xfrm.FlushPolicyInfo()
+
+ return True
+ except IOError as err:
+ if err.errno == ENOSYS:
+ return False
+ else:
+ print("Unexpected error:", err.errno)
+ return True
+
+# Dictionary to record the algorithm state. Mark the state True if this
+# algorithm is enforced or enabled on this kernel. Otherwise, mark it
+# False.
+algoState = {}
+
+def AlgoEnforcedOrEnabled(crypt, auth, aead, target_algo, target_kernel):
+ if algoState.get(target_algo) is None:
+ algoState[target_algo] = net_test.LINUX_VERSION >= target_kernel or HaveAlgo(
+ crypt, auth, aead)
+ return algoState.get(target_algo)
+
+# Return true if this algorithm should be enforced or is enabled on this kernel
+def AuthEnforcedOrEnabled(authCase):
+ auth = authCase[0]
+ crypt = xfrm.XfrmAlgo(("ecb(cipher_null)", 0))
+ return AlgoEnforcedOrEnabled(crypt, auth, None, auth.name, authCase[1])
+
+# Return true if this algorithm should be enforced or is enabled on this kernel
+def CryptEnforcedOrEnabled(cryptCase):
+ crypt = cryptCase[0]
+ auth = xfrm.XfrmAlgoAuth(("digest_null", 0, 0))
+ return AlgoEnforcedOrEnabled(crypt, auth, None, crypt.name, cryptCase[1])
+
+# Return true if this algorithm should be enforced or is enabled on this kernel
+def AeadEnforcedOrEnabled(aeadCase):
+ aead = aeadCase[0]
+ return AlgoEnforcedOrEnabled(None, None, aead, aead.name, aeadCase[1])
+
def InjectTests():
XfrmAlgorithmTest.InjectTests()
@@ -92,18 +177,21 @@ class XfrmAlgorithmTest(xfrm_base.XfrmLazyTest):
util.InjectParameterizedTest(cls, param_list, cls.TestNameGenerator)
@staticmethod
- def TestNameGenerator(version, proto, auth, crypt, aead):
+ def TestNameGenerator(version, proto, authCase, cryptCase, aeadCase):
# Produce a unique and readable name for each test. e.g.
# testSocketPolicySimple_cbc-aes_256_hmac-sha512_512_256_IPv6_UDP
param_string = ""
- if crypt is not None:
+ if cryptCase is not None:
+ crypt = cryptCase[0]
param_string += "%s_%d_" % (crypt.name, crypt.key_len)
- if auth is not None:
+ if authCase is not None:
+ auth = authCase[0]
param_string += "%s_%d_%d_" % (auth.name, auth.key_len,
auth.trunc_len)
- if aead is not None:
+ if aeadCase is not None:
+ aead = aeadCase[0]
param_string += "%s_%d_%d_" % (aead.name, aead.key_len,
aead.icv_len)
@@ -111,9 +199,22 @@ class XfrmAlgorithmTest(xfrm_base.XfrmLazyTest):
"UDP" if proto == SOCK_DGRAM else "TCP")
return param_string
- def ParamTestSocketPolicySimple(self, version, proto, auth, crypt, aead):
+ def ParamTestSocketPolicySimple(self, version, proto, authCase, cryptCase, aeadCase):
"""Test two-way traffic using transport mode and socket policies."""
+ # Bypass the test if any algorithm going to be tested is not enforced
+ # or enabled on this kernel
+ if authCase is not None and not AuthEnforcedOrEnabled(authCase):
+ return
+ if cryptCase is not None and not CryptEnforcedOrEnabled(cryptCase):
+ return
+ if aeadCase is not None and not AeadEnforcedOrEnabled(aeadCase):
+ return
+
+ auth = authCase[0] if authCase else None
+ crypt = cryptCase[0] if cryptCase else None
+ aead = aeadCase[0] if aeadCase else None
+
def AssertEncrypted(packet):
# This gives a free pass to ICMP and ICMPv6 packets, which show up
# nondeterministically in tests.