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