1 /* 2 * Copyright (C) 2017 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 */ 16 #ifndef _XFRM_CONTROLLER_H 17 #define _XFRM_CONTROLLER_H 18 19 #include <atomic> 20 #include <list> 21 #include <map> 22 #include <string> 23 #include <utility> // for pair 24 25 #include <linux/if_link.h> 26 #include <linux/if_tunnel.h> 27 #include <linux/netlink.h> 28 #include <linux/udp.h> 29 #include <linux/xfrm.h> 30 #include <sysutils/SocketClient.h> 31 32 #include "NetdConstants.h" 33 #include "netdutils/Slice.h" 34 #include "netdutils/Status.h" 35 36 namespace android { 37 namespace net { 38 39 // Exposed for testing 40 extern const uint32_t ALGO_MASK_AUTH_ALL; 41 // Exposed for testing 42 extern const uint32_t ALGO_MASK_CRYPT_ALL; 43 // Exposed for testing 44 extern const uint32_t ALGO_MASK_AEAD_ALL; 45 // Exposed for testing 46 extern const uint8_t REPLAY_WINDOW_SIZE; 47 48 // Suggest we avoid the smallest and largest ints 49 class XfrmMessage; 50 class TransportModeSecurityAssociation; 51 52 class XfrmSocket { 53 public: close()54 virtual void close() { 55 if (mSock >= 0) { 56 ::close(mSock); 57 } 58 mSock = -1; 59 } 60 61 virtual netdutils::Status open() = 0; 62 ~XfrmSocket()63 virtual ~XfrmSocket() { close(); } 64 65 // Sends the netlink message contained in iovecs. This populates iovecs[0] with 66 // a valid netlink message header. 67 virtual netdutils::Status sendMessage(uint16_t nlMsgType, uint16_t nlMsgFlags, 68 uint16_t nlMsgSeqNum, 69 std::vector<iovec>* iovecs) const = 0; 70 71 protected: 72 int mSock; 73 }; 74 75 enum struct XfrmDirection : uint8_t { 76 IN = XFRM_POLICY_IN, 77 OUT = XFRM_POLICY_OUT, 78 FORWARD = XFRM_POLICY_FWD, 79 MASK = XFRM_POLICY_MASK, 80 }; 81 82 enum struct XfrmMode : uint8_t { 83 TRANSPORT = XFRM_MODE_TRANSPORT, 84 TUNNEL = XFRM_MODE_TUNNEL, 85 }; 86 87 enum struct XfrmEncapType : uint16_t { 88 NONE = 0, 89 ESPINUDP_NON_IKE = UDP_ENCAP_ESPINUDP_NON_IKE, 90 ESPINUDP = UDP_ENCAP_ESPINUDP 91 }; 92 93 struct XfrmAlgo { 94 std::string name; 95 std::vector<uint8_t> key; 96 uint16_t truncLenBits; 97 }; 98 99 struct XfrmEncap { 100 XfrmEncapType type; 101 uint16_t srcPort; 102 uint16_t dstPort; 103 }; 104 105 // minimally sufficient structure to match either an SA or a Policy 106 struct XfrmId { 107 xfrm_address_t dstAddr; // network order 108 xfrm_address_t srcAddr; 109 int addrFamily; // AF_INET or AF_INET6 110 int transformId; // requestId 111 int spi; 112 xfrm_mark mark; 113 }; 114 115 struct XfrmSaInfo : XfrmId { 116 XfrmAlgo auth; 117 XfrmAlgo crypt; 118 XfrmAlgo aead; 119 int netId; 120 XfrmMode mode; 121 XfrmEncap encap; 122 }; 123 124 class XfrmController { 125 public: 126 XfrmController(); 127 128 static netdutils::Status Init(); 129 130 static netdutils::Status ipSecSetEncapSocketOwner(const android::base::unique_fd& socket, 131 int newUid, uid_t callerUid); 132 133 static netdutils::Status ipSecAllocateSpi(int32_t transformId, const std::string& localAddress, 134 const std::string& remoteAddress, int32_t inSpi, 135 int32_t* outSpi); 136 137 static netdutils::Status ipSecAddSecurityAssociation( 138 int32_t transformId, int32_t mode, const std::string& sourceAddress, 139 const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi, 140 int32_t markValue, int32_t markMask, const std::string& authAlgo, 141 const std::vector<uint8_t>& authKey, int32_t authTruncBits, const std::string& cryptAlgo, 142 const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits, const std::string& aeadAlgo, 143 const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType, 144 int32_t encapLocalPort, int32_t encapRemotePort); 145 146 static netdutils::Status ipSecDeleteSecurityAssociation(int32_t transformId, 147 const std::string& sourceAddress, 148 const std::string& destinationAddress, 149 int32_t spi, int32_t markValue, 150 int32_t markMask); 151 152 static netdutils::Status 153 ipSecApplyTransportModeTransform(const android::base::unique_fd& socket, int32_t transformId, 154 int32_t direction, const std::string& localAddress, 155 const std::string& remoteAddress, int32_t spi); 156 157 static netdutils::Status 158 ipSecRemoveTransportModeTransform(const android::base::unique_fd& socket); 159 160 static netdutils::Status ipSecAddSecurityPolicy(int32_t transformId, int32_t direction, 161 const std::string& sourceAddress, 162 const std::string& destinationAddress, 163 int32_t spi, int32_t markValue, 164 int32_t markMask); 165 166 static netdutils::Status ipSecUpdateSecurityPolicy(int32_t transformId, int32_t direction, 167 const std::string& sourceAddress, 168 const std::string& destinationAddress, 169 int32_t spi, int32_t markValue, 170 int32_t markMask); 171 172 static netdutils::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t direction, 173 const std::string& sourceAddress, 174 const std::string& destinationAddress, 175 int32_t markValue, int32_t markMask); 176 177 static int addVirtualTunnelInterface(const std::string& deviceName, 178 const std::string& localAddress, 179 const std::string& remoteAddress, int32_t ikey, 180 int32_t okey, bool isUpdate); 181 182 static int removeVirtualTunnelInterface(const std::string& deviceName); 183 184 // Some XFRM netlink attributes comprise a header, a struct, and some data 185 // after the struct. We wrap all of those in one struct for easier 186 // marshalling. The structs below must be ABI compatible with the kernel and 187 // are composed from kernel structures; thus, they use the kernel naming 188 // convention. 189 190 // Exposed for testing 191 static constexpr size_t MAX_KEY_LENGTH = 128; 192 193 // Container for the content of an XFRMA_ALG_CRYPT netlink attribute. 194 // Exposed for testing 195 struct nlattr_algo_crypt { 196 nlattr hdr; 197 xfrm_algo crypt; 198 uint8_t key[MAX_KEY_LENGTH]; 199 }; 200 201 // Container for the content of an XFRMA_ALG_AUTH_TRUNC netlink attribute. 202 // Exposed for testing 203 struct nlattr_algo_auth { 204 nlattr hdr; 205 xfrm_algo_auth auth; 206 uint8_t key[MAX_KEY_LENGTH]; 207 }; 208 209 // Container for the content of an XFRMA_TMPL netlink attribute. 210 // Exposed for testing 211 struct nlattr_algo_aead { 212 nlattr hdr; 213 xfrm_algo_aead aead; 214 uint8_t key[MAX_KEY_LENGTH]; 215 }; 216 217 // Exposed for testing 218 struct nlattr_user_tmpl { 219 nlattr hdr; 220 xfrm_user_tmpl tmpl; 221 }; 222 223 // Container for the content of an XFRMA_ENCAP netlink attribute. 224 // Exposed for testing 225 struct nlattr_encap_tmpl { 226 nlattr hdr; 227 xfrm_encap_tmpl tmpl; 228 }; 229 230 // Container for the content of an XFRMA_MARK netlink attribute. 231 // Exposed for testing 232 struct nlattr_xfrm_mark { 233 nlattr hdr; 234 xfrm_mark mark; 235 }; 236 237 // Container for the content of an XFRMA_OUTPUT_MARK netlink attribute. 238 // Exposed for testing 239 struct nlattr_xfrm_output_mark { 240 nlattr hdr; 241 __u32 outputMark; 242 }; 243 244 private: 245 /* 246 * Below is a redefinition of the xfrm_usersa_info struct that is part 247 * of the Linux uapi <linux/xfrm.h> to align the structures to a 64-bit 248 * boundary. 249 */ 250 #ifdef NETLINK_COMPAT32 251 // Shadow the kernel definition of xfrm_usersa_info with a 64-bit aligned version 252 struct xfrm_usersa_info : ::xfrm_usersa_info { 253 } __attribute__((aligned(8))); 254 // Shadow the kernel's version, using the aligned version of xfrm_usersa_info 255 struct xfrm_userspi_info { 256 struct xfrm_usersa_info info; 257 __u32 min; 258 __u32 max; 259 }; 260 261 /* 262 * Anyone who encounters a failure when sending netlink messages should look here 263 * first. Hitting the static_assert() below should be a strong hint that Android 264 * IPsec will probably not work with your current settings. 265 * 266 * Again, experimentally determined, the "flags" field should be the first byte in 267 * the final word of the xfrm_usersa_info struct. The check validates the size of 268 * the padding to be 7. 269 * 270 * This padding is verified to be correct on gcc/x86_64 kernel, and clang/x86 userspace. 271 */ 272 static_assert(sizeof(::xfrm_usersa_info) % 8 != 0, "struct xfrm_usersa_info has changed " 273 "alignment. Please consider whether this " 274 "patch is needed."); 275 static_assert(sizeof(xfrm_usersa_info) - offsetof(xfrm_usersa_info, flags) == 8, 276 "struct xfrm_usersa_info probably misaligned with kernel struct."); 277 static_assert(sizeof(xfrm_usersa_info) % 8 == 0, "struct xfrm_usersa_info_t is not 64-bit " 278 "aligned. Please consider whether this patch " 279 "is needed."); 280 static_assert(sizeof(::xfrm_userspi_info) - sizeof(::xfrm_usersa_info) == 281 sizeof(xfrm_userspi_info) - sizeof(xfrm_usersa_info), 282 "struct xfrm_userspi_info has changed and does not match the kernel struct."); 283 #endif 284 285 // helper function for filling in the XfrmId (and XfrmSaInfo) structure 286 static netdutils::Status fillXfrmId(const std::string& sourceAddress, 287 const std::string& destinationAddress, int32_t spi, 288 int32_t markValue, int32_t markMask, int32_t transformId, 289 XfrmId* xfrmId); 290 291 // Top level functions for managing a Transport Mode Transform 292 static netdutils::Status addTransportModeTransform(const XfrmSaInfo& record); 293 static int removeTransportModeTransform(const XfrmSaInfo& record); 294 295 // TODO(messagerefactor): FACTOR OUT ALL MESSAGE BUILDING CODE BELOW HERE 296 // Shared between SA and SP 297 static void fillXfrmSelector(const XfrmSaInfo& record, xfrm_selector* selector); 298 299 // Shared between Transport and Tunnel Mode 300 static int fillNlAttrXfrmAlgoEnc(const XfrmAlgo& in_algo, nlattr_algo_crypt* algo); 301 static int fillNlAttrXfrmAlgoAuth(const XfrmAlgo& in_algo, nlattr_algo_auth* algo); 302 static int fillNlAttrXfrmAlgoAead(const XfrmAlgo& in_algo, nlattr_algo_aead* algo); 303 static int fillNlAttrXfrmEncapTmpl(const XfrmSaInfo& record, nlattr_encap_tmpl* tmpl); 304 305 // Functions for updating a Transport Mode SA 306 static netdutils::Status updateSecurityAssociation(const XfrmSaInfo& record, 307 const XfrmSocket& sock); 308 static int fillUserSaInfo(const XfrmSaInfo& record, xfrm_usersa_info* usersa); 309 310 // Functions for deleting a Transport Mode SA 311 static netdutils::Status deleteSecurityAssociation(const XfrmId& record, 312 const XfrmSocket& sock); 313 static int fillUserSaId(const XfrmId& record, xfrm_usersa_id* said); 314 static int fillUserTemplate(const XfrmSaInfo& record, xfrm_user_tmpl* tmpl); 315 316 static int fillTransportModeUserSpInfo(const XfrmSaInfo& record, XfrmDirection direction, 317 xfrm_userpolicy_info* usersp); 318 static int fillNlAttrUserTemplate(const XfrmSaInfo& record, nlattr_user_tmpl* tmpl); 319 static int fillUserPolicyId(const XfrmSaInfo& record, XfrmDirection direction, 320 xfrm_userpolicy_id* policy_id); 321 static int fillNlAttrXfrmMark(const XfrmId& record, nlattr_xfrm_mark* mark); 322 static int fillNlAttrXfrmOutputMark(const __u32 output_mark_value, 323 nlattr_xfrm_output_mark* output_mark); 324 325 static netdutils::Status allocateSpi(const XfrmSaInfo& record, uint32_t minSpi, uint32_t maxSpi, 326 uint32_t* outSpi, const XfrmSocket& sock); 327 328 static netdutils::Status processSecurityPolicy(int32_t transformId, int32_t direction, 329 const std::string& localAddress, 330 const std::string& remoteAddress, int32_t spi, 331 int32_t markValue, int32_t markMask, 332 int32_t msgType); 333 static netdutils::Status updateTunnelModeSecurityPolicy(const XfrmSaInfo& record, 334 const XfrmSocket& sock, 335 XfrmDirection direction, 336 uint16_t msgType); 337 static netdutils::Status deleteTunnelModeSecurityPolicy(const XfrmSaInfo& record, 338 const XfrmSocket& sock, 339 XfrmDirection direction); 340 static netdutils::Status flushInterfaces(); 341 static netdutils::Status flushSaDb(const XfrmSocket& s); 342 static netdutils::Status flushPolicyDb(const XfrmSocket& s); 343 344 // END TODO(messagerefactor) 345 }; 346 347 } // namespace net 348 } // namespace android 349 350 #endif /* !defined(XFRM_CONTROLLER_H) */ 351