1# 2# Copyright 2018 - The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import binascii 17import os 18import re 19 20from acts_contrib.test_utils.net import connectivity_const as cconst 21from acts import asserts 22 23PKTS = 5 24 25 26def make_key(len_bits): 27 asserts.assert_true( 28 len_bits % 8 == 0, "Unexpected key length. Should be a multiple " 29 "of 8, got %s" % len_bits) 30 return binascii.hexlify(os.urandom(int(len_bits / 8))).decode() 31 32 33def allocate_spis(ad, ip_a, ip_b, in_spi=None, out_spi=None): 34 """ Allocate in and out SPIs for android device 35 36 Args: 37 1. ad : android device object 38 2. ip_a : local IP address for In SPI 39 3. ip_b : remote IP address for Out SPI 40 4. in_spi : Generate In SPI with this value 41 5. out_spi : Generate Out SPI with this value 42 43 Returns: 44 List of In and Out SPI 45 """ 46 in_spi_key = ad.droid.ipSecAllocateSecurityParameterIndex(ip_a, in_spi) 47 in_spi = ad.droid.ipSecGetSecurityParameterIndex(in_spi_key) 48 ad.log.info("In SPI: %s" % hex(in_spi)) 49 50 out_spi_key = ad.droid.ipSecAllocateSecurityParameterIndex(ip_b, out_spi) 51 out_spi = ad.droid.ipSecGetSecurityParameterIndex(out_spi_key) 52 ad.log.info("Out SPI: %s" % hex(out_spi)) 53 54 asserts.assert_true(in_spi and out_spi, "Failed to allocate SPIs") 55 return [in_spi_key, out_spi_key] 56 57 58def release_spis(ad, spis): 59 """ Destroy SPIs 60 61 Args: 62 1. ad : android device object 63 2. spis : list of SPI keys to destroy 64 """ 65 for spi_key in spis: 66 ad.droid.ipSecReleaseSecurityParameterIndex(spi_key) 67 spi = ad.droid.ipSecGetSecurityParameterIndex(spi_key) 68 asserts.assert_true(not spi, "Failed to release SPI") 69 70 71def create_transport_mode_transforms(ad, 72 spis, 73 ip_a, 74 ip_b, 75 crypt_algo, 76 crypt_key, 77 auth_algo, 78 auth_key, 79 trunc_bit, 80 udp_encap_sock=None): 81 """ Create transport mode transforms on the device 82 83 Args: 84 1. ad : android device object 85 2. spis : spi keys of the SPIs created 86 3. ip_a : local IP addr 87 4. ip_b : remote IP addr 88 5. crypt_key : encryption key 89 6. auth_key : authentication key 90 7. udp_encap_sock : set udp encapsulation for ESP packets 91 92 Returns: 93 List of In and Out Transforms 94 """ 95 in_transform = ad.droid.ipSecCreateTransportModeTransform( 96 crypt_algo, crypt_key, auth_algo, auth_key, trunc_bit, spis[0], ip_b, 97 udp_encap_sock) 98 ad.log.info("In Transform: %s" % in_transform) 99 out_transform = ad.droid.ipSecCreateTransportModeTransform( 100 crypt_algo, crypt_key, auth_algo, auth_key, trunc_bit, spis[1], ip_a, 101 udp_encap_sock) 102 ad.log.info("Out Transform: %s" % out_transform) 103 asserts.assert_true(in_transform and out_transform, 104 "Failed to create transforms") 105 return [in_transform, out_transform] 106 107 108def destroy_transport_mode_transforms(ad, transforms): 109 """ Destroy transforms on the device 110 111 Args: 112 1. ad : android device object 113 2. transforms : list to transform keys to destroy 114 """ 115 for transform in transforms: 116 ad.droid.ipSecDestroyTransportModeTransform(transform) 117 status = ad.droid.ipSecGetTransformStatus(transform) 118 ad.log.info("Transform status: %s" % status) 119 asserts.assert_true(not status, "Failed to destroy transform") 120 121 122def apply_transport_mode_transforms_file_descriptors(ad, fd, transforms): 123 """ Apply transpot mode transform to FileDescriptor object 124 125 Args: 126 1. ad - android device object 127 2. fd - FileDescriptor key 128 3. transforms - list of in and out transforms 129 """ 130 in_transform = ad.droid.ipSecApplyTransportModeTransformFileDescriptor( 131 fd, cconst.DIRECTION_IN, transforms[0]) 132 out_transform = ad.droid.ipSecApplyTransportModeTransformFileDescriptor( 133 fd, cconst.DIRECTION_OUT, transforms[1]) 134 asserts.assert_true(in_transform and out_transform, 135 "Failed to apply transform") 136 ip_xfrm_state = ad.adb.shell("ip -s xfrm state") 137 ad.log.info("XFRM STATE:\n%s\n" % ip_xfrm_state) 138 ip_xfrm_policy = ad.adb.shell("ip -s xfrm policy") 139 ad.log.info("XFRM POLICY:\n%s\n" % ip_xfrm_policy) 140 141 142def remove_transport_mode_transforms_file_descriptors(ad, fd): 143 """ Remove transport mode transform from FileDescriptor object 144 145 Args: 146 1. ad - android device object 147 2. socket - FileDescriptor key 148 """ 149 status = ad.droid.ipSecRemoveTransportModeTransformsFileDescriptor(fd) 150 asserts.assert_true(status, "Failed to remove transform") 151 152 153def apply_transport_mode_transforms_datagram_socket(ad, socket, transforms): 154 """ Apply transport mode transform to DatagramSocket object 155 156 Args: 157 1. ad - android device object 158 2. socket - DatagramSocket object key 159 3. transforms - list of in and out transforms 160 """ 161 in_tfrm_status = ad.droid.ipSecApplyTransportModeTransformDatagramSocket( 162 socket, cconst.DIRECTION_IN, transforms[0]) 163 out_tfrm_status = ad.droid.ipSecApplyTransportModeTransformDatagramSocket( 164 socket, cconst.DIRECTION_OUT, transforms[1]) 165 asserts.assert_true(in_tfrm_status and out_tfrm_status, 166 "Failed to apply transform") 167 168 ip_xfrm_state = ad.adb.shell("ip -s xfrm state") 169 ad.log.info("XFRM STATE:\n%s\n" % ip_xfrm_state) 170 171 172def remove_transport_mode_transforms_datagram_socket(ad, socket): 173 """ Remove transport mode transform from DatagramSocket object 174 175 Args: 176 1. ad - android device object 177 2. socket - DatagramSocket object key 178 """ 179 status = ad.droid.ipSecRemoveTransportModeTransformsDatagramSocket(socket) 180 asserts.assert_true(status, "Failed to remove transform") 181 182 183def apply_transport_mode_transforms_socket(ad, socket, transforms): 184 """ Apply transport mode transform to Socket object 185 186 Args: 187 1. ad - android device object 188 2. socket - Socket object key 189 3. transforms - list of in and out transforms 190 """ 191 in_tfrm_status = ad.droid.ipSecApplyTransportModeTransformSocket( 192 socket, cconst.DIRECTION_IN, transforms[0]) 193 out_tfrm_status = ad.droid.ipSecApplyTransportModeTransformSocket( 194 socket, cconst.DIRECTION_OUT, transforms[1]) 195 asserts.assert_true(in_tfrm_status and out_tfrm_status, 196 "Failed to apply transform") 197 198 ip_xfrm_state = ad.adb.shell("ip -s xfrm state") 199 ad.log.info("XFRM STATE:\n%s\n" % ip_xfrm_state) 200 201 202def remove_transport_mode_transforms_socket(ad, socket): 203 """ Remove transport mode transform from Socket object 204 205 Args: 206 1. ad - android device object 207 2. socket - Socket object key 208 """ 209 status = ad.droid.ipSecRemoveTransportModeTransformsSocket(socket) 210 asserts.assert_true(status, "Failed to remove transform") 211 212 213def verify_esp_packets(ads): 214 """ Verify that encrypted ESP packets are sent 215 216 Args: 217 1. ads - Verify ESP packets on all devices 218 """ 219 for ad in ads: 220 ip_xfrm_state = ad.adb.shell("ip -s xfrm state") 221 ad.log.info("XFRM STATE on %s:\n%s\n" % (ad.serial, ip_xfrm_state)) 222 pattern = re.findall(r'\d+\(packets\)', ip_xfrm_state) 223 esp_pkts = False 224 for _ in pattern: 225 if int(_.split('(')[0]) >= PKTS: 226 esp_pkts = True 227 break 228 asserts.assert_true(esp_pkts, "Could not find ESP pkts") 229 230 231def generate_random_crypt_auth_combo(): 232 """ Generate every possible combination of crypt and auth keys, 233 auth algo, trunc bits supported by IpSecManager 234 """ 235 crypt_key_length = [128, 192, 256] 236 auth_method_key = { 237 cconst.AUTH_HMAC_MD5: 128, 238 cconst.AUTH_HMAC_SHA1: 160, 239 cconst.AUTH_HMAC_SHA256: 256, 240 cconst.AUTH_HMAC_SHA384: 384, 241 cconst.AUTH_HMAC_SHA512: 512 242 } 243 auth_method_trunc = { 244 cconst.AUTH_HMAC_MD5: list(range(96, 136, 8)), 245 cconst.AUTH_HMAC_SHA1: list(range(96, 168, 8)), 246 cconst.AUTH_HMAC_SHA256: list(range(96, 264, 8)), 247 cconst.AUTH_HMAC_SHA384: list(range(192, 392, 8)), 248 cconst.AUTH_HMAC_SHA512: list(range(256, 520, 8)) 249 } 250 return_list = [] 251 for c in crypt_key_length: 252 for k in auth_method_key.keys(): 253 auth_key = auth_method_key[k] 254 lst = auth_method_trunc[k] 255 for t in lst: 256 combo = [] 257 combo.append(c) 258 combo.append(k) 259 combo.append(auth_key) 260 combo.append(t) 261 return_list.append(combo) 262 263 return return_list 264