• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   *
3   * Copyright (C) 2017 The Android Open Source Project
4   *
5   * Licensed under the Apache License, Version 2.0 (the "License");
6   * you may not use this file except in compliance with the License.
7   * You may obtain a copy of the License at
8   *
9   *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  #include <random>
19  #include <string>
20  #include <vector>
21  
22  #include <ctype.h>
23  #include <errno.h>
24  #include <fcntl.h>
25  #include <getopt.h>
26  #include <inttypes.h>
27  #include <stdio.h>
28  #include <stdlib.h>
29  #include <string.h>
30  
31  #include <arpa/inet.h>
32  #include <net/if.h>
33  #include <netinet/in.h>
34  
35  #include <sys/socket.h>
36  #include <sys/stat.h>
37  #include <sys/types.h>
38  #include <sys/wait.h>
39  
40  #include <linux/in.h>
41  #include <linux/ipsec.h>
42  #include <linux/netlink.h>
43  #include <linux/xfrm.h>
44  
45  #define LOG_TAG "XfrmController"
46  #include <android-base/properties.h>
47  #include <android-base/stringprintf.h>
48  #include <android-base/strings.h>
49  #include <android-base/unique_fd.h>
50  #include <android/net/INetd.h>
51  #include <cutils/properties.h>
52  #include <log/log.h>
53  #include <log/log_properties.h>
54  #include "Fwmark.h"
55  #include "InterfaceController.h"
56  #include "NetdConstants.h"
57  #include "NetlinkCommands.h"
58  #include "Permission.h"
59  #include "XfrmController.h"
60  #include "android-base/stringprintf.h"
61  #include "android-base/strings.h"
62  #include "android-base/unique_fd.h"
63  #include "netdutils/DumpWriter.h"
64  #include "netdutils/Fd.h"
65  #include "netdutils/Slice.h"
66  #include "netdutils/Syscalls.h"
67  #include "netdutils/Utils.h"
68  
69  using android::netdutils::DumpWriter;
70  using android::netdutils::Fd;
71  using android::netdutils::getIfaceNames;
72  using android::netdutils::ScopedIndent;
73  using android::netdutils::Slice;
74  using android::netdutils::Status;
75  using android::netdutils::StatusOr;
76  using android::netdutils::Syscalls;
77  
78  namespace android {
79  namespace net {
80  
81  // Exposed for testing
82  constexpr uint32_t ALGO_MASK_AUTH_ALL = ~0;
83  // Exposed for testing
84  constexpr uint32_t ALGO_MASK_CRYPT_ALL = ~0;
85  // Exposed for testing
86  constexpr uint32_t ALGO_MASK_AEAD_ALL = ~0;
87  // Exposed for testing
88  constexpr uint8_t REPLAY_WINDOW_SIZE = 0;
89  // Exposed for testing
90  constexpr uint32_t REPLAY_WINDOW_SIZE_ESN = 4096;
91  
92  namespace {
93  
94  constexpr uint32_t RAND_SPI_MIN = 256;
95  constexpr uint32_t RAND_SPI_MAX = 0xFFFFFFFE;
96  
97  constexpr uint32_t INVALID_SPI = 0;
98  constexpr const char* INFO_KIND_VTI = "vti";
99  constexpr const char* INFO_KIND_VTI6 = "vti6";
100  constexpr const char* INFO_KIND_XFRMI = "xfrm";
101  constexpr int INFO_KIND_MAX_LEN = 8;
102  constexpr int LOOPBACK_IFINDEX = 1;
103  
104  bool mIsXfrmIntfSupported = false;
105  
isEngBuild()106  static inline bool isEngBuild() {
107      static const std::string sBuildType = android::base::GetProperty("ro.build.type", "user");
108      return sBuildType == "eng";
109  }
110  
111  #define XFRM_MSG_TRANS(x)                                                                          \
112      case x:                                                                                        \
113          return #x;
114  
xfrmMsgTypeToString(uint16_t msg)115  const char* xfrmMsgTypeToString(uint16_t msg) {
116      switch (msg) {
117          XFRM_MSG_TRANS(XFRM_MSG_NEWSA)
118          XFRM_MSG_TRANS(XFRM_MSG_DELSA)
119          XFRM_MSG_TRANS(XFRM_MSG_GETSA)
120          XFRM_MSG_TRANS(XFRM_MSG_NEWPOLICY)
121          XFRM_MSG_TRANS(XFRM_MSG_DELPOLICY)
122          XFRM_MSG_TRANS(XFRM_MSG_GETPOLICY)
123          XFRM_MSG_TRANS(XFRM_MSG_ALLOCSPI)
124          XFRM_MSG_TRANS(XFRM_MSG_ACQUIRE)
125          XFRM_MSG_TRANS(XFRM_MSG_EXPIRE)
126          XFRM_MSG_TRANS(XFRM_MSG_UPDPOLICY)
127          XFRM_MSG_TRANS(XFRM_MSG_UPDSA)
128          XFRM_MSG_TRANS(XFRM_MSG_POLEXPIRE)
129          XFRM_MSG_TRANS(XFRM_MSG_FLUSHSA)
130          XFRM_MSG_TRANS(XFRM_MSG_FLUSHPOLICY)
131          XFRM_MSG_TRANS(XFRM_MSG_NEWAE)
132          XFRM_MSG_TRANS(XFRM_MSG_GETAE)
133          XFRM_MSG_TRANS(XFRM_MSG_REPORT)
134          XFRM_MSG_TRANS(XFRM_MSG_MIGRATE)
135          XFRM_MSG_TRANS(XFRM_MSG_NEWSADINFO)
136          XFRM_MSG_TRANS(XFRM_MSG_GETSADINFO)
137          XFRM_MSG_TRANS(XFRM_MSG_GETSPDINFO)
138          XFRM_MSG_TRANS(XFRM_MSG_NEWSPDINFO)
139          XFRM_MSG_TRANS(XFRM_MSG_MAPPING)
140          default:
141              return "XFRM_MSG UNKNOWN";
142      }
143  }
144  
145  // actually const but cannot be declared as such for reasons
146  uint8_t kPadBytesArray[] = {0, 0, 0};
147  void* kPadBytes = static_cast<void*>(kPadBytesArray);
148  
149  #define LOG_HEX(__desc16__, __buf__, __len__)                                                      \
150      do {                                                                                           \
151          if (isEngBuild()) {                                                                        \
152              logHex(__desc16__, __buf__, __len__);                                                  \
153          }                                                                                          \
154      } while (0)
155  
156  #define LOG_IOV(__iov__)                                                                           \
157      do {                                                                                           \
158          if (isEngBuild()) {                                                                        \
159              logIov(__iov__);                                                                       \
160          }                                                                                          \
161      } while (0)
162  
logHex(const char * desc16,const char * buf,size_t len)163  void logHex(const char* desc16, const char* buf, size_t len) {
164      char* printBuf = new char[len * 2 + 1 + 26]; // len->ascii, +newline, +prefix strlen
165      int offset = 0;
166      if (desc16) {
167          sprintf(printBuf, "{%-16s}", desc16);
168          offset += 18; // prefix string length
169      }
170      sprintf(printBuf + offset, "[%4.4u]: ", (len > 9999) ? 9999 : (unsigned)len);
171      offset += 8;
172  
173      for (uint32_t j = 0; j < (uint32_t)len; j++) {
174          sprintf(&printBuf[j * 2 + offset], "%0.2x", (unsigned char)buf[j]);
175      }
176      ALOGD("%s", printBuf);
177      delete[] printBuf;
178  }
179  
logIov(const std::vector<iovec> & iov)180  void logIov(const std::vector<iovec>& iov) {
181      for (const iovec& row : iov) {
182          logHex(nullptr, reinterpret_cast<char*>(row.iov_base), row.iov_len);
183      }
184  }
185  
fillNlAttr(__u16 nlaType,size_t valueSize,nlattr * nlAttr)186  size_t fillNlAttr(__u16 nlaType, size_t valueSize, nlattr* nlAttr) {
187      size_t dataLen = valueSize;
188      int padLength = NLMSG_ALIGN(dataLen) - dataLen;
189      nlAttr->nla_len = (__u16)(dataLen + sizeof(nlattr));
190      nlAttr->nla_type = nlaType;
191      return padLength;
192  }
193  
fillNlAttrIpAddress(__u16 nlaType,int family,const std::string & value,nlattr * nlAttr,Slice ipAddress)194  size_t fillNlAttrIpAddress(__u16 nlaType, int family, const std::string& value, nlattr* nlAttr,
195                             Slice ipAddress) {
196      inet_pton(family, value.c_str(), ipAddress.base());
197      return fillNlAttr(nlaType, (family == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr), nlAttr);
198  }
199  
fillNlAttrU32(__u16 nlaType,uint32_t value,XfrmController::nlattr_payload_u32 * nlAttr)200  size_t fillNlAttrU32(__u16 nlaType, uint32_t value, XfrmController::nlattr_payload_u32* nlAttr) {
201      nlAttr->value = value;
202      return fillNlAttr(nlaType, sizeof(value), &nlAttr->hdr);
203  }
204  
205  // returns the address family, placing the string in the provided buffer
convertStringAddress(const std::string & addr,uint8_t * buffer)206  StatusOr<uint16_t> convertStringAddress(const std::string& addr, uint8_t* buffer) {
207      if (inet_pton(AF_INET, addr.c_str(), buffer) == 1) {
208          return AF_INET;
209      } else if (inet_pton(AF_INET6, addr.c_str(), buffer) == 1) {
210          return AF_INET6;
211      } else {
212          return Status(EAFNOSUPPORT);
213      }
214  }
215  
216  // TODO: Need to consider a way to refer to the sSycalls instance
getSyscallInstance()217  inline Syscalls& getSyscallInstance() { return netdutils::sSyscalls.get(); }
218  
219  class XfrmSocketImpl : public XfrmSocket {
220  private:
221      static constexpr int NLMSG_DEFAULTSIZE = 8192;
222  
223      union NetlinkResponse {
224          nlmsghdr hdr;
225          struct _err_ {
226              nlmsghdr hdr;
227              nlmsgerr err;
228          } err;
229  
230          struct _buf_ {
231              nlmsghdr hdr;
232              char buf[NLMSG_DEFAULTSIZE];
233          } buf;
234      };
235  
236  public:
open()237      netdutils::Status open() override {
238          mSock = openNetlinkSocket(NETLINK_XFRM);
239          if (mSock < 0) {
240              ALOGW("Could not get a new socket, line=%d", __LINE__);
241              return netdutils::statusFromErrno(-mSock, "Could not open netlink socket");
242          }
243  
244          return netdutils::status::ok;
245      }
246  
validateResponse(NetlinkResponse response,size_t len)247      static netdutils::Status validateResponse(NetlinkResponse response, size_t len) {
248          if (len < sizeof(nlmsghdr)) {
249              ALOGW("Invalid response message received over netlink");
250              return netdutils::statusFromErrno(EBADMSG, "Invalid message");
251          }
252  
253          switch (response.hdr.nlmsg_type) {
254              case NLMSG_NOOP:
255              case NLMSG_DONE:
256                  return netdutils::status::ok;
257              case NLMSG_OVERRUN:
258                  ALOGD("Netlink request overran kernel buffer");
259                  return netdutils::statusFromErrno(EBADMSG, "Kernel buffer overrun");
260              case NLMSG_ERROR:
261                  if (len < sizeof(NetlinkResponse::_err_)) {
262                      ALOGD("Netlink message received malformed error response");
263                      return netdutils::statusFromErrno(EBADMSG, "Malformed error response");
264                  }
265                  return netdutils::statusFromErrno(
266                      -response.err.err.error,
267                      "Error netlink message"); // Netlink errors are negative errno.
268              case XFRM_MSG_NEWSA:
269                  break;
270          }
271  
272          if (response.hdr.nlmsg_type < XFRM_MSG_BASE /*== NLMSG_MIN_TYPE*/ ||
273              response.hdr.nlmsg_type > XFRM_MSG_MAX) {
274              ALOGD("Netlink message responded with an out-of-range message ID");
275              return netdutils::statusFromErrno(EBADMSG, "Invalid message ID");
276          }
277  
278          // TODO Add more message validation here
279          return netdutils::status::ok;
280      }
281  
sendMessage(uint16_t nlMsgType,uint16_t nlMsgFlags,uint16_t nlMsgSeqNum,std::vector<iovec> * iovecs) const282      netdutils::Status sendMessage(uint16_t nlMsgType, uint16_t nlMsgFlags, uint16_t nlMsgSeqNum,
283                                    std::vector<iovec>* iovecs) const override {
284          nlmsghdr nlMsg = {
285              .nlmsg_type = nlMsgType,
286              .nlmsg_flags = nlMsgFlags,
287              .nlmsg_seq = nlMsgSeqNum,
288          };
289  
290          (*iovecs)[0].iov_base = &nlMsg;
291          (*iovecs)[0].iov_len = NLMSG_HDRLEN;
292          for (const iovec& iov : *iovecs) {
293              nlMsg.nlmsg_len += iov.iov_len;
294          }
295  
296          ALOGD("Sending Netlink XFRM Message: %s", xfrmMsgTypeToString(nlMsgType));
297          LOG_IOV(*iovecs);
298  
299          StatusOr<size_t> writeResult = getSyscallInstance().writev(mSock, *iovecs);
300          if (!isOk(writeResult)) {
301              ALOGE("netlink socket writev failed (%s)", toString(writeResult).c_str());
302              return writeResult;
303          }
304  
305          if (nlMsg.nlmsg_len != writeResult.value()) {
306              ALOGE("Invalid netlink message length sent %d", static_cast<int>(writeResult.value()));
307              return netdutils::statusFromErrno(EBADMSG, "Invalid message length");
308          }
309  
310          NetlinkResponse response = {};
311  
312          StatusOr<Slice> readResult =
313              getSyscallInstance().read(Fd(mSock), netdutils::makeSlice(response));
314          if (!isOk(readResult)) {
315              ALOGE("netlink response error (%s)", toString(readResult).c_str());
316              return readResult;
317          }
318  
319          LOG_HEX("netlink msg resp", reinterpret_cast<char*>(readResult.value().base()),
320                  readResult.value().size());
321  
322          Status validateStatus = validateResponse(response, readResult.value().size());
323          if (!isOk(validateStatus)) {
324              ALOGE("netlink response contains error (%s)", toString(validateStatus).c_str());
325          }
326  
327          return validateStatus;
328      }
329  };
330  
convertToXfrmAddr(const std::string & strAddr,xfrm_address_t * xfrmAddr)331  StatusOr<int> convertToXfrmAddr(const std::string& strAddr, xfrm_address_t* xfrmAddr) {
332      if (strAddr.length() == 0) {
333          memset(xfrmAddr, 0, sizeof(*xfrmAddr));
334          return AF_UNSPEC;
335      }
336  
337      if (inet_pton(AF_INET6, strAddr.c_str(), reinterpret_cast<void*>(xfrmAddr))) {
338          return AF_INET6;
339      } else if (inet_pton(AF_INET, strAddr.c_str(), reinterpret_cast<void*>(xfrmAddr))) {
340          return AF_INET;
341      } else {
342          return netdutils::statusFromErrno(EAFNOSUPPORT, "Invalid address family");
343      }
344  }
345  
fillXfrmNlaHdr(nlattr * hdr,uint16_t type,uint16_t len)346  void fillXfrmNlaHdr(nlattr* hdr, uint16_t type, uint16_t len) {
347      hdr->nla_type = type;
348      hdr->nla_len = len;
349  }
350  
fillXfrmCurLifetimeDefaults(xfrm_lifetime_cur * cur)351  void fillXfrmCurLifetimeDefaults(xfrm_lifetime_cur* cur) {
352      memset(reinterpret_cast<char*>(cur), 0, sizeof(*cur));
353  }
fillXfrmLifetimeDefaults(xfrm_lifetime_cfg * cfg)354  void fillXfrmLifetimeDefaults(xfrm_lifetime_cfg* cfg) {
355      cfg->soft_byte_limit = XFRM_INF;
356      cfg->hard_byte_limit = XFRM_INF;
357      cfg->soft_packet_limit = XFRM_INF;
358      cfg->hard_packet_limit = XFRM_INF;
359  }
360  
361  /*
362   * Allocate SPIs within an (inclusive) range of min-max.
363   * returns 0 (INVALID_SPI) once the entire range has been parsed.
364   */
365  class RandomSpi {
366  public:
RandomSpi(int min,int max)367      RandomSpi(int min, int max) : mMin(min) {
368          // Re-seeding should be safe because the seed itself is
369          // sufficiently random and we don't need secure random
370          std::mt19937 rnd = std::mt19937(std::random_device()());
371          mNext = std::uniform_int_distribution<>(1, INT_MAX)(rnd);
372          mSize = max - min + 1;
373          mCount = mSize;
374      }
375  
next()376      uint32_t next() {
377          if (!mCount)
378              return 0;
379          mCount--;
380          return (mNext++ % mSize) + mMin;
381      }
382  
383  private:
384      uint32_t mNext;
385      uint32_t mSize;
386      uint32_t mMin;
387      uint32_t mCount;
388  };
389  
390  } // namespace
391  
392  //
393  // Begin XfrmController Impl
394  //
395  //
XfrmController(void)396  XfrmController::XfrmController(void) {}
397  
398  // Test-only constructor allowing override of XFRM Interface support checks
XfrmController(bool xfrmIntfSupport)399  XfrmController::XfrmController(bool xfrmIntfSupport) {
400      mIsXfrmIntfSupported = xfrmIntfSupport;
401  }
402  
Init()403  netdutils::Status XfrmController::Init() {
404      RETURN_IF_NOT_OK(flushInterfaces());
405      mIsXfrmIntfSupported = isXfrmIntfSupported();
406  
407      XfrmSocketImpl sock;
408      RETURN_IF_NOT_OK(sock.open());
409      RETURN_IF_NOT_OK(flushSaDb(sock));
410      return flushPolicyDb(sock);
411  }
412  
flushInterfaces()413  netdutils::Status XfrmController::flushInterfaces() {
414      const auto& ifaces = getIfaceNames();
415      RETURN_IF_NOT_OK(ifaces);
416      const String8 ifPrefix8 = String8(INetd::IPSEC_INTERFACE_PREFIX().c_str());
417  
418      for (const std::string& iface : ifaces.value()) {
419          netdutils::Status status;
420          // Look for the reserved interface prefix, which must be in the name at position 0
421          if (android::base::StartsWith(iface.c_str(), ifPrefix8.c_str())) {
422              RETURN_IF_NOT_OK(ipSecRemoveTunnelInterface(iface));
423          }
424      }
425      return netdutils::status::ok;
426  }
427  
flushSaDb(const XfrmSocket & s)428  netdutils::Status XfrmController::flushSaDb(const XfrmSocket& s) {
429      struct xfrm_usersa_flush flushUserSa = {.proto = IPSEC_PROTO_ANY};
430  
431      std::vector<iovec> iov = {{nullptr, 0}, // reserved for the eventual addition of a NLMSG_HDR
432                                {&flushUserSa, sizeof(flushUserSa)}, // xfrm_usersa_flush structure
433                                {kPadBytes, NLMSG_ALIGN(sizeof(flushUserSa)) - sizeof(flushUserSa)}};
434  
435      return s.sendMessage(XFRM_MSG_FLUSHSA, NETLINK_REQUEST_FLAGS, 0, &iov);
436  }
437  
flushPolicyDb(const XfrmSocket & s)438  netdutils::Status XfrmController::flushPolicyDb(const XfrmSocket& s) {
439      std::vector<iovec> iov = {{nullptr, 0}}; // reserved for the eventual addition of a NLMSG_HDR
440      return s.sendMessage(XFRM_MSG_FLUSHPOLICY, NETLINK_REQUEST_FLAGS, 0, &iov);
441  }
442  
isXfrmIntfSupported()443  bool XfrmController::isXfrmIntfSupported() {
444      const char* IPSEC_TEST_INTF_NAME = "ipsec_test";
445      const int32_t XFRM_TEST_IF_ID = 0xFFFF;
446  
447      bool errored = false;
448      errored |=
449              ipSecAddXfrmInterface(IPSEC_TEST_INTF_NAME, XFRM_TEST_IF_ID, NETLINK_ROUTE_CREATE_FLAGS)
450                      .code();
451      errored |= ipSecRemoveTunnelInterface(IPSEC_TEST_INTF_NAME).code();
452      return !errored;
453  }
454  
ipSecSetEncapSocketOwner(int socketFd,int newUid,uid_t callerUid)455  netdutils::Status XfrmController::ipSecSetEncapSocketOwner(int socketFd, int newUid,
456                                                             uid_t callerUid) {
457      ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
458  
459      const int fd = socketFd;
460      struct stat info;
461      if (fstat(fd, &info)) {
462          return netdutils::statusFromErrno(errno, "Failed to stat socket file descriptor");
463      }
464      if (info.st_uid != callerUid) {
465          return netdutils::statusFromErrno(EPERM, "fchown disabled for non-owner calls");
466      }
467      if (S_ISSOCK(info.st_mode) == 0) {
468          return netdutils::statusFromErrno(EINVAL, "File descriptor was not a socket");
469      }
470  
471      int optval;
472      socklen_t optlen = sizeof(optval);
473      netdutils::Status status =
474              getSyscallInstance().getsockopt(Fd(fd), IPPROTO_UDP, UDP_ENCAP, &optval, &optlen);
475      if (status != netdutils::status::ok) {
476          return status;
477      }
478      if (optval != UDP_ENCAP_ESPINUDP && optval != UDP_ENCAP_ESPINUDP_NON_IKE) {
479          return netdutils::statusFromErrno(EINVAL, "Socket did not have UDP-encap sockopt set");
480      }
481      if (fchown(fd, newUid, -1)) {
482          return netdutils::statusFromErrno(errno, "Failed to fchown socket file descriptor");
483      }
484  
485      return netdutils::status::ok;
486  }
487  
ipSecAllocateSpi(int32_t transformId,const std::string & sourceAddress,const std::string & destinationAddress,int32_t inSpi,int32_t * outSpi)488  netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId,
489                                                     const std::string& sourceAddress,
490                                                     const std::string& destinationAddress,
491                                                     int32_t inSpi, int32_t* outSpi) {
492      ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
493      ALOGD("transformId=%d", transformId);
494      ALOGD("sourceAddress=%s", sourceAddress.c_str());
495      ALOGD("destinationAddress=%s", destinationAddress.c_str());
496      ALOGD("inSpi=%0.8x", inSpi);
497  
498      XfrmSaInfo saInfo{};
499      netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, INVALID_SPI, 0, 0,
500                                                 transformId, 0, &saInfo);
501      if (!isOk(ret)) {
502          return ret;
503      }
504  
505      XfrmSocketImpl sock;
506      netdutils::Status socketStatus = sock.open();
507      if (!isOk(socketStatus)) {
508          ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
509          return socketStatus;
510      }
511  
512      int minSpi = RAND_SPI_MIN, maxSpi = RAND_SPI_MAX;
513  
514      if (inSpi)
515          minSpi = maxSpi = inSpi;
516  
517      ret = allocateSpi(saInfo, minSpi, maxSpi, reinterpret_cast<uint32_t*>(outSpi), sock);
518      if (!isOk(ret)) {
519          // TODO: May want to return a new Status with a modified status string
520          ALOGD("Failed to Allocate an SPI, line=%d", __LINE__);
521          *outSpi = INVALID_SPI;
522      }
523  
524      return ret;
525  }
526  
ipSecAddSecurityAssociation(int32_t transformId,int32_t mode,const std::string & sourceAddress,const std::string & destinationAddress,int32_t underlyingNetId,int32_t spi,int32_t markValue,int32_t markMask,const std::string & authAlgo,const std::vector<uint8_t> & authKey,int32_t authTruncBits,const std::string & cryptAlgo,const std::vector<uint8_t> & cryptKey,int32_t cryptTruncBits,const std::string & aeadAlgo,const std::vector<uint8_t> & aeadKey,int32_t aeadIcvBits,int32_t encapType,int32_t encapLocalPort,int32_t encapRemotePort,int32_t xfrmInterfaceId)527  netdutils::Status XfrmController::ipSecAddSecurityAssociation(
528          int32_t transformId, int32_t mode, const std::string& sourceAddress,
529          const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
530          int32_t markValue, int32_t markMask, const std::string& authAlgo,
531          const std::vector<uint8_t>& authKey, int32_t authTruncBits, const std::string& cryptAlgo,
532          const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits, const std::string& aeadAlgo,
533          const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
534          int32_t encapLocalPort, int32_t encapRemotePort, int32_t xfrmInterfaceId) {
535      ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
536      ALOGD("transformId=%d", transformId);
537      ALOGD("mode=%d", mode);
538      ALOGD("sourceAddress=%s", sourceAddress.c_str());
539      ALOGD("destinationAddress=%s", destinationAddress.c_str());
540      ALOGD("underlyingNetworkId=%d", underlyingNetId);
541      ALOGD("spi=%0.8x", spi);
542      ALOGD("markValue=%x", markValue);
543      ALOGD("markMask=%x", markMask);
544      ALOGD("authAlgo=%s", authAlgo.c_str());
545      ALOGD("authTruncBits=%d", authTruncBits);
546      ALOGD("cryptAlgo=%s", cryptAlgo.c_str());
547      ALOGD("cryptTruncBits=%d,", cryptTruncBits);
548      ALOGD("aeadAlgo=%s", aeadAlgo.c_str());
549      ALOGD("aeadIcvBits=%d,", aeadIcvBits);
550      ALOGD("encapType=%d", encapType);
551      ALOGD("encapLocalPort=%d", encapLocalPort);
552      ALOGD("encapRemotePort=%d", encapRemotePort);
553      ALOGD("xfrmInterfaceId=%d", xfrmInterfaceId);
554  
555      XfrmSaInfo saInfo{};
556      netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, markValue,
557                                                 markMask, transformId, xfrmInterfaceId, &saInfo);
558      if (!isOk(ret)) {
559          return ret;
560      }
561  
562      saInfo.auth = XfrmAlgo{
563          .name = authAlgo, .key = authKey, .truncLenBits = static_cast<uint16_t>(authTruncBits)};
564  
565      saInfo.crypt = XfrmAlgo{
566          .name = cryptAlgo, .key = cryptKey, .truncLenBits = static_cast<uint16_t>(cryptTruncBits)};
567  
568      saInfo.aead = XfrmAlgo{
569          .name = aeadAlgo, .key = aeadKey, .truncLenBits = static_cast<uint16_t>(aeadIcvBits)};
570  
571      switch (static_cast<XfrmMode>(mode)) {
572          case XfrmMode::TRANSPORT:
573          case XfrmMode::TUNNEL:
574              saInfo.mode = static_cast<XfrmMode>(mode);
575              break;
576          default:
577              return netdutils::statusFromErrno(EINVAL, "Invalid xfrm mode");
578      }
579  
580      XfrmSocketImpl sock;
581      netdutils::Status socketStatus = sock.open();
582      if (!isOk(socketStatus)) {
583          ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
584          return socketStatus;
585      }
586  
587      switch (static_cast<XfrmEncapType>(encapType)) {
588          case XfrmEncapType::ESPINUDP:
589          case XfrmEncapType::ESPINUDP_NON_IKE:
590              // The ports are not used on input SAs, so this is OK to be wrong when
591              // direction is ultimately input.
592              saInfo.encap.srcPort = encapLocalPort;
593              saInfo.encap.dstPort = encapRemotePort;
594              [[fallthrough]];
595          case XfrmEncapType::NONE:
596              saInfo.encap.type = static_cast<XfrmEncapType>(encapType);
597              break;
598          default:
599              return netdutils::statusFromErrno(EINVAL, "Invalid encap type");
600      }
601  
602      saInfo.netId = underlyingNetId;
603  
604      ret = updateSecurityAssociation(saInfo, sock);
605      if (!isOk(ret)) {
606          ALOGD("Failed updating a Security Association, line=%d", __LINE__);
607      }
608  
609      return ret;
610  }
611  
ipSecDeleteSecurityAssociation(int32_t transformId,const std::string & sourceAddress,const std::string & destinationAddress,int32_t spi,int32_t markValue,int32_t markMask,int32_t xfrmInterfaceId)612  netdutils::Status XfrmController::ipSecDeleteSecurityAssociation(
613          int32_t transformId, const std::string& sourceAddress,
614          const std::string& destinationAddress, int32_t spi, int32_t markValue, int32_t markMask,
615          int32_t xfrmInterfaceId) {
616      ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
617      ALOGD("transformId=%d", transformId);
618      ALOGD("sourceAddress=%s", sourceAddress.c_str());
619      ALOGD("destinationAddress=%s", destinationAddress.c_str());
620      ALOGD("spi=%0.8x", spi);
621      ALOGD("markValue=%x", markValue);
622      ALOGD("markMask=%x", markMask);
623      ALOGD("xfrmInterfaceId=%d", xfrmInterfaceId);
624  
625      XfrmSaInfo saInfo{};
626      netdutils::Status ret = fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, markValue,
627                                                 markMask, transformId, xfrmInterfaceId, &saInfo);
628      if (!isOk(ret)) {
629          return ret;
630      }
631  
632      XfrmSocketImpl sock;
633      netdutils::Status socketStatus = sock.open();
634      if (!isOk(socketStatus)) {
635          ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
636          return socketStatus;
637      }
638  
639      ret = deleteSecurityAssociation(saInfo, sock);
640      if (!isOk(ret)) {
641          ALOGD("Failed to delete Security Association, line=%d", __LINE__);
642      }
643  
644      return ret;
645  }
646  
ipSecMigrate(int32_t transformId,int32_t selAddrFamily,int32_t direction,const std::string & oldSourceAddress,const std::string & oldDestinationAddress,const std::string & newSourceAddress,const std::string & newDestinationAddress,int32_t xfrmInterfaceId)647  netdutils::Status XfrmController::ipSecMigrate(int32_t transformId, int32_t selAddrFamily,
648                                                 int32_t direction,
649                                                 const std::string& oldSourceAddress,
650                                                 const std::string& oldDestinationAddress,
651                                                 const std::string& newSourceAddress,
652                                                 const std::string& newDestinationAddress,
653                                                 int32_t xfrmInterfaceId) {
654      ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
655      ALOGD("transformId=%d", transformId);
656      ALOGD("selAddrFamily=%d", selAddrFamily);
657      ALOGD("direction=%d", direction);
658      ALOGD("oldSourceAddress=%s", oldSourceAddress.c_str());
659      ALOGD("oldDestinationAddress=%s", oldDestinationAddress.c_str());
660      ALOGD("newSourceAddress=%s", newSourceAddress.c_str());
661      ALOGD("newDestinationAddress=%s", newDestinationAddress.c_str());
662      ALOGD("xfrmInterfaceId=%d", xfrmInterfaceId);
663  
664      XfrmSocketImpl sock;
665      Status socketStatus = sock.open();
666      if (!socketStatus.ok()) {
667          ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
668          return socketStatus;
669      }
670  
671      XfrmMigrateInfo migrateInfo{};
672      Status ret =
673              fillXfrmCommonInfo(oldSourceAddress, oldDestinationAddress, 0 /* spi */, 0 /* mark */,
674                                 0 /* markMask */, transformId, xfrmInterfaceId, &migrateInfo);
675  
676      if (!ret.ok()) {
677          ALOGD("Failed to fill in XfrmCommonInfo, line=%d", __LINE__);
678          return ret;
679      }
680  
681      migrateInfo.selAddrFamily = selAddrFamily;
682      migrateInfo.direction = static_cast<XfrmDirection>(direction);
683  
684      ret = fillXfrmEndpointPair(newSourceAddress, newDestinationAddress,
685                                 &migrateInfo.newEndpointInfo);
686      if (!ret.ok()) {
687          ALOGD("Failed to fill in XfrmEndpointPair, line=%d", __LINE__);
688          return ret;
689      }
690  
691      ret = migrate(migrateInfo, sock);
692  
693      if (!ret.ok()) {
694          ALOGD("Failed to migrate Security Association, line=%d", __LINE__);
695      }
696      return ret;
697  }
698  
fillXfrmEndpointPair(const std::string & sourceAddress,const std::string & destinationAddress,XfrmEndpointPair * endpointPair)699  netdutils::Status XfrmController::fillXfrmEndpointPair(const std::string& sourceAddress,
700                                                         const std::string& destinationAddress,
701                                                         XfrmEndpointPair* endpointPair) {
702      // Use the addresses to determine the address family and do validation
703      xfrm_address_t sourceXfrmAddr{}, destXfrmAddr{};
704      StatusOr<int> sourceFamily, destFamily;
705      sourceFamily = convertToXfrmAddr(sourceAddress, &sourceXfrmAddr);
706      destFamily = convertToXfrmAddr(destinationAddress, &destXfrmAddr);
707      if (!isOk(sourceFamily) || !isOk(destFamily)) {
708          return netdutils::statusFromErrno(
709                  EINVAL, "Invalid address " + sourceAddress + "/" + destinationAddress);
710      }
711  
712      if (destFamily.value() == AF_UNSPEC ||
713          (sourceFamily.value() != AF_UNSPEC && sourceFamily.value() != destFamily.value())) {
714          ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", sourceFamily.value(),
715                destFamily.value(), __LINE__);
716          return netdutils::statusFromErrno(EINVAL, "Invalid or mismatched address families");
717      }
718  
719      endpointPair->addrFamily = destFamily.value();
720  
721      endpointPair->dstAddr = destXfrmAddr;
722      endpointPair->srcAddr = sourceXfrmAddr;
723  
724      return netdutils::status::ok;
725  }
726  
fillXfrmCommonInfo(const std::string & sourceAddress,const std::string & destinationAddress,int32_t spi,int32_t markValue,int32_t markMask,int32_t transformId,int32_t xfrmInterfaceId,XfrmCommonInfo * info)727  netdutils::Status XfrmController::fillXfrmCommonInfo(const std::string& sourceAddress,
728                                                       const std::string& destinationAddress,
729                                                       int32_t spi, int32_t markValue,
730                                                       int32_t markMask, int32_t transformId,
731                                                       int32_t xfrmInterfaceId,
732                                                       XfrmCommonInfo* info) {
733      Status ret = fillXfrmEndpointPair(sourceAddress, destinationAddress, info);
734      if (!isOk(ret)) {
735          return ret;
736      }
737  
738      return fillXfrmCommonInfo(spi, markValue, markMask, transformId, xfrmInterfaceId, info);
739  }
740  
fillXfrmCommonInfo(int32_t spi,int32_t markValue,int32_t markMask,int32_t transformId,int32_t xfrmInterfaceId,XfrmCommonInfo * info)741  netdutils::Status XfrmController::fillXfrmCommonInfo(int32_t spi, int32_t markValue,
742                                                       int32_t markMask, int32_t transformId,
743                                                       int32_t xfrmInterfaceId,
744                                                       XfrmCommonInfo* info) {
745      info->transformId = transformId;
746      info->spi = htonl(spi);
747  
748      if (mIsXfrmIntfSupported) {
749          info->xfrm_if_id = xfrmInterfaceId;
750      } else {
751          info->mark.v = markValue;
752          info->mark.m = markMask;
753      }
754  
755      return netdutils::status::ok;
756  }
757  
ipSecApplyTransportModeTransform(int socketFd,int32_t transformId,int32_t direction,const std::string & sourceAddress,const std::string & destinationAddress,int32_t spi)758  netdutils::Status XfrmController::ipSecApplyTransportModeTransform(
759          int socketFd, int32_t transformId, int32_t direction, const std::string& sourceAddress,
760          const std::string& destinationAddress, int32_t spi) {
761      ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
762      ALOGD("transformId=%d", transformId);
763      ALOGD("direction=%d", direction);
764      ALOGD("sourceAddress=%s", sourceAddress.c_str());
765      ALOGD("destinationAddress=%s", destinationAddress.c_str());
766      ALOGD("spi=%0.8x", spi);
767  
768      StatusOr<sockaddr_storage> ret =
769              getSyscallInstance().getsockname<sockaddr_storage>(Fd(socketFd));
770      if (!isOk(ret)) {
771          ALOGE("Failed to get socket info in %s", __FUNCTION__);
772          return ret;
773      }
774      struct sockaddr_storage saddr = ret.value();
775  
776      XfrmSpInfo spInfo{};
777      netdutils::Status status = fillXfrmCommonInfo(sourceAddress, destinationAddress, spi, 0, 0,
778                                                    transformId, 0, &spInfo);
779      if (!isOk(status)) {
780          ALOGE("Couldn't build SA ID %s", __FUNCTION__);
781          return status;
782      }
783  
784      spInfo.selAddrFamily = spInfo.addrFamily;
785      spInfo.direction = static_cast<XfrmDirection>(direction);
786  
787      // Allow dual stack sockets. Dual stack sockets are guaranteed to never have an AF_INET source
788      // address; the source address would instead be an IPv4-mapped address. Thus, disallow AF_INET
789      // sockets with mismatched address families (All other cases are acceptable).
790      if (saddr.ss_family == AF_INET && spInfo.addrFamily != AF_INET) {
791          ALOGE("IPV4 socket address family(%d) should match IPV4 Transform "
792                "address family(%d)!",
793                saddr.ss_family, spInfo.addrFamily);
794          return netdutils::statusFromErrno(EINVAL, "Mismatched address family");
795      }
796  
797      struct {
798          xfrm_userpolicy_info info;
799          xfrm_user_tmpl tmpl;
800      } policy{};
801  
802      fillUserSpInfo(spInfo, &policy.info);
803      fillUserTemplate(spInfo, &policy.tmpl);
804  
805      LOG_HEX("XfrmUserPolicy", reinterpret_cast<char*>(&policy), sizeof(policy));
806  
807      int sockOpt, sockLayer;
808      switch (saddr.ss_family) {
809          case AF_INET:
810              sockOpt = IP_XFRM_POLICY;
811              sockLayer = SOL_IP;
812              break;
813          case AF_INET6:
814              sockOpt = IPV6_XFRM_POLICY;
815              sockLayer = SOL_IPV6;
816              break;
817          default:
818              return netdutils::statusFromErrno(EAFNOSUPPORT, "Invalid address family");
819      }
820  
821      status = getSyscallInstance().setsockopt(Fd(socketFd), sockLayer, sockOpt, policy);
822      if (!isOk(status)) {
823          ALOGE("Error setting socket option for XFRM! (%s)", toString(status).c_str());
824      }
825  
826      return status;
827  }
828  
ipSecRemoveTransportModeTransform(int socketFd)829  netdutils::Status XfrmController::ipSecRemoveTransportModeTransform(int socketFd) {
830      ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
831  
832      StatusOr<sockaddr_storage> ret =
833              getSyscallInstance().getsockname<sockaddr_storage>(Fd(socketFd));
834      if (!isOk(ret)) {
835          ALOGE("Failed to get socket info in %s! (%s)", __FUNCTION__, toString(ret).c_str());
836          return ret;
837      }
838  
839      int sockOpt, sockLayer;
840      switch (ret.value().ss_family) {
841          case AF_INET:
842              sockOpt = IP_XFRM_POLICY;
843              sockLayer = SOL_IP;
844              break;
845          case AF_INET6:
846              sockOpt = IPV6_XFRM_POLICY;
847              sockLayer = SOL_IPV6;
848              break;
849          default:
850              return netdutils::statusFromErrno(EAFNOSUPPORT, "Invalid address family");
851      }
852  
853      // Kernel will delete the security policy on this socket for both direction
854      // if optval is set to NULL and optlen is set to 0.
855      netdutils::Status status =
856              getSyscallInstance().setsockopt(Fd(socketFd), sockLayer, sockOpt, nullptr, 0);
857      if (!isOk(status)) {
858          ALOGE("Error removing socket option for XFRM! (%s)", toString(status).c_str());
859      }
860  
861      return status;
862  }
863  
ipSecAddSecurityPolicy(int32_t transformId,int32_t selAddrFamily,int32_t direction,const std::string & tmplSrcAddress,const std::string & tmplDstAddress,int32_t spi,int32_t markValue,int32_t markMask,int32_t xfrmInterfaceId)864  netdutils::Status XfrmController::ipSecAddSecurityPolicy(
865          int32_t transformId, int32_t selAddrFamily, int32_t direction,
866          const std::string& tmplSrcAddress, const std::string& tmplDstAddress, int32_t spi,
867          int32_t markValue, int32_t markMask, int32_t xfrmInterfaceId) {
868      return processSecurityPolicy(transformId, selAddrFamily, direction, tmplSrcAddress,
869                                   tmplDstAddress, spi, markValue, markMask, xfrmInterfaceId,
870                                   XFRM_MSG_NEWPOLICY);
871  }
872  
ipSecUpdateSecurityPolicy(int32_t transformId,int32_t selAddrFamily,int32_t direction,const std::string & tmplSrcAddress,const std::string & tmplDstAddress,int32_t spi,int32_t markValue,int32_t markMask,int32_t xfrmInterfaceId)873  netdutils::Status XfrmController::ipSecUpdateSecurityPolicy(
874          int32_t transformId, int32_t selAddrFamily, int32_t direction,
875          const std::string& tmplSrcAddress, const std::string& tmplDstAddress, int32_t spi,
876          int32_t markValue, int32_t markMask, int32_t xfrmInterfaceId) {
877      return processSecurityPolicy(transformId, selAddrFamily, direction, tmplSrcAddress,
878                                   tmplDstAddress, spi, markValue, markMask, xfrmInterfaceId,
879                                   XFRM_MSG_UPDPOLICY);
880  }
881  
ipSecDeleteSecurityPolicy(int32_t transformId,int32_t selAddrFamily,int32_t direction,int32_t markValue,int32_t markMask,int32_t xfrmInterfaceId)882  netdutils::Status XfrmController::ipSecDeleteSecurityPolicy(int32_t transformId,
883                                                              int32_t selAddrFamily,
884                                                              int32_t direction, int32_t markValue,
885                                                              int32_t markMask,
886                                                              int32_t xfrmInterfaceId) {
887      return processSecurityPolicy(transformId, selAddrFamily, direction, "", "", 0, markValue,
888                                   markMask, xfrmInterfaceId, XFRM_MSG_DELPOLICY);
889  }
890  
processSecurityPolicy(int32_t transformId,int32_t selAddrFamily,int32_t direction,const std::string & tmplSrcAddress,const std::string & tmplDstAddress,int32_t spi,int32_t markValue,int32_t markMask,int32_t xfrmInterfaceId,int32_t msgType)891  netdutils::Status XfrmController::processSecurityPolicy(
892          int32_t transformId, int32_t selAddrFamily, int32_t direction,
893          const std::string& tmplSrcAddress, const std::string& tmplDstAddress, int32_t spi,
894          int32_t markValue, int32_t markMask, int32_t xfrmInterfaceId, int32_t msgType) {
895      ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
896      ALOGD("selAddrFamily=%s", selAddrFamily == AF_INET6 ? "AF_INET6" : "AF_INET");
897      ALOGD("transformId=%d", transformId);
898      ALOGD("direction=%d", direction);
899      ALOGD("tmplSrcAddress=%s", tmplSrcAddress.c_str());
900      ALOGD("tmplDstAddress=%s", tmplDstAddress.c_str());
901      ALOGD("spi=%0.8x", spi);
902      ALOGD("markValue=%d", markValue);
903      ALOGD("markMask=%d", markMask);
904      ALOGD("msgType=%d", msgType);
905      ALOGD("xfrmInterfaceId=%d", xfrmInterfaceId);
906  
907      XfrmSpInfo spInfo{};
908      spInfo.mode = XfrmMode::TUNNEL;
909  
910      XfrmSocketImpl sock;
911      RETURN_IF_NOT_OK(sock.open());
912  
913      // Set the correct address families. Tunnel mode policies use wildcard selectors, while
914      // templates have addresses set. These may be different address families. This method is called
915      // separately for IPv4 and IPv6 policies, and thus only need to map a single inner address
916      // family to the outer address families.
917      spInfo.selAddrFamily = selAddrFamily;
918      spInfo.direction = static_cast<XfrmDirection>(direction);
919  
920      if (msgType == XFRM_MSG_DELPOLICY) {
921          RETURN_IF_NOT_OK(fillXfrmCommonInfo(spi, markValue, markMask, transformId, xfrmInterfaceId,
922                                              &spInfo));
923  
924          return deleteTunnelModeSecurityPolicy(spInfo, sock);
925      } else {
926          RETURN_IF_NOT_OK(fillXfrmCommonInfo(tmplSrcAddress, tmplDstAddress, spi, markValue,
927                                              markMask, transformId, xfrmInterfaceId, &spInfo));
928  
929          return updateTunnelModeSecurityPolicy(spInfo, sock, msgType);
930      }
931  }
932  
fillXfrmSelector(const int selAddrFamily,xfrm_selector * selector)933  void XfrmController::fillXfrmSelector(const int selAddrFamily, xfrm_selector* selector) {
934      selector->family = selAddrFamily;
935      selector->proto = AF_UNSPEC; // TODO: do we need to match the protocol? it's
936                                   // possible via the socket
937  }
938  
updateSecurityAssociation(const XfrmSaInfo & record,const XfrmSocket & sock)939  netdutils::Status XfrmController::updateSecurityAssociation(const XfrmSaInfo& record,
940                                                              const XfrmSocket& sock) {
941      xfrm_usersa_info usersa{};
942      nlattr_algo_crypt crypt{};
943      nlattr_algo_auth auth{};
944      nlattr_algo_aead aead{};
945      nlattr_xfrm_mark xfrmmark{};
946      nlattr_xfrm_output_mark xfrmoutputmark{};
947      nlattr_encap_tmpl encap{};
948      nlattr_xfrm_interface_id xfrm_if_id{};
949      nlattr_xfrm_replay_esn xfrm_replay_esn{};
950  
951      enum {
952          NLMSG_HDR,
953          USERSA,
954          USERSA_PAD,
955          CRYPT,
956          CRYPT_PAD,
957          AUTH,
958          AUTH_PAD,
959          AEAD,
960          AEAD_PAD,
961          MARK,
962          MARK_PAD,
963          OUTPUT_MARK,
964          OUTPUT_MARK_PAD,
965          ENCAP,
966          ENCAP_PAD,
967          INTF_ID,
968          INTF_ID_PAD,
969          REPLAY_ESN,  // Used to enable BMP (extended replay window) mode
970          REPLAY_ESN_PAD,
971      };
972  
973      std::vector<iovec> iov = {
974              {nullptr, 0},           // reserved for the eventual addition of a NLMSG_HDR
975              {&usersa, 0},           // main usersa_info struct
976              {kPadBytes, 0},         // up to NLMSG_ALIGNTO pad bytes of padding
977              {&crypt, 0},            // adjust size if crypt algo is present
978              {kPadBytes, 0},         // up to NLATTR_ALIGNTO pad bytes
979              {&auth, 0},             // adjust size if auth algo is present
980              {kPadBytes, 0},         // up to NLATTR_ALIGNTO pad bytes
981              {&aead, 0},             // adjust size if aead algo is present
982              {kPadBytes, 0},         // up to NLATTR_ALIGNTO pad bytes
983              {&xfrmmark, 0},         // adjust size if xfrm mark is present
984              {kPadBytes, 0},         // up to NLATTR_ALIGNTO pad bytes
985              {&xfrmoutputmark, 0},   // adjust size if xfrm output mark is present
986              {kPadBytes, 0},         // up to NLATTR_ALIGNTO pad bytes
987              {&encap, 0},            // adjust size if encapsulating
988              {kPadBytes, 0},         // up to NLATTR_ALIGNTO pad bytes
989              {&xfrm_if_id, 0},       // adjust size if interface ID is present
990              {kPadBytes, 0},         // up to NLATTR_ALIGNTO pad bytes
991              {&xfrm_replay_esn, 0},  // Always use BMP mode with a large replay window
992              {kPadBytes, 0},         // up to NLATTR_ALIGNTO pad bytes
993      };
994  
995      if (!record.aead.name.empty() && (!record.auth.name.empty() || !record.crypt.name.empty())) {
996          return netdutils::statusFromErrno(EINVAL, "Invalid xfrm algo selection; AEAD is mutually "
997                                                    "exclusive with both Authentication and "
998                                                    "Encryption");
999      }
1000  
1001      if (record.aead.key.size() > MAX_KEY_LENGTH || record.auth.key.size() > MAX_KEY_LENGTH ||
1002          record.crypt.key.size() > MAX_KEY_LENGTH) {
1003          return netdutils::statusFromErrno(EINVAL, "Key length invalid; exceeds MAX_KEY_LENGTH");
1004      }
1005  
1006      if (record.mode != XfrmMode::TUNNEL &&
1007          (record.xfrm_if_id != 0 || record.netId != 0 || record.mark.v != 0 || record.mark.m != 0)) {
1008          return netdutils::statusFromErrno(EINVAL,
1009                                            "xfrm_if_id, mark and netid parameters invalid "
1010                                            "for non tunnel-mode transform");
1011      } else if (record.mode == XfrmMode::TUNNEL && !mIsXfrmIntfSupported && record.xfrm_if_id != 0) {
1012          return netdutils::statusFromErrno(EINVAL, "xfrm_if_id set for VTI Security Association");
1013      }
1014  
1015      int len;
1016      len = iov[USERSA].iov_len = fillUserSaInfo(record, &usersa);
1017      iov[USERSA_PAD].iov_len = NLMSG_ALIGN(len) - len;
1018  
1019      len = iov[CRYPT].iov_len = fillNlAttrXfrmAlgoEnc(record.crypt, &crypt);
1020      iov[CRYPT_PAD].iov_len = NLA_ALIGN(len) - len;
1021  
1022      len = iov[AUTH].iov_len = fillNlAttrXfrmAlgoAuth(record.auth, &auth);
1023      iov[AUTH_PAD].iov_len = NLA_ALIGN(len) - len;
1024  
1025      len = iov[AEAD].iov_len = fillNlAttrXfrmAlgoAead(record.aead, &aead);
1026      iov[AEAD_PAD].iov_len = NLA_ALIGN(len) - len;
1027  
1028      len = iov[MARK].iov_len = fillNlAttrXfrmMark(record, &xfrmmark);
1029      iov[MARK_PAD].iov_len = NLA_ALIGN(len) - len;
1030  
1031      len = iov[OUTPUT_MARK].iov_len = fillNlAttrXfrmOutputMark(record, &xfrmoutputmark);
1032      iov[OUTPUT_MARK_PAD].iov_len = NLA_ALIGN(len) - len;
1033  
1034      len = iov[ENCAP].iov_len = fillNlAttrXfrmEncapTmpl(record, &encap);
1035      iov[ENCAP_PAD].iov_len = NLA_ALIGN(len) - len;
1036  
1037      len = iov[INTF_ID].iov_len = fillNlAttrXfrmIntfId(record.xfrm_if_id, &xfrm_if_id);
1038      iov[INTF_ID_PAD].iov_len = NLA_ALIGN(len) - len;
1039  
1040      len = iov[REPLAY_ESN].iov_len = fillNlAttrXfrmReplayEsn(&xfrm_replay_esn);
1041      iov[REPLAY_ESN_PAD].iov_len = NLA_ALIGN(len) - len;
1042  
1043      return sock.sendMessage(XFRM_MSG_UPDSA, NETLINK_REQUEST_FLAGS, 0, &iov);
1044  }
1045  
fillNlAttrXfrmAlgoEnc(const XfrmAlgo & inAlgo,nlattr_algo_crypt * algo)1046  int XfrmController::fillNlAttrXfrmAlgoEnc(const XfrmAlgo& inAlgo, nlattr_algo_crypt* algo) {
1047      if (inAlgo.name.empty()) { // Do not fill anything if algorithm not provided
1048          return 0;
1049      }
1050  
1051      int len = NLA_HDRLEN + sizeof(xfrm_algo);
1052      // Kernel always changes last char to null terminator; no safety checks needed.
1053      strncpy(algo->crypt.alg_name, inAlgo.name.c_str(), sizeof(algo->crypt.alg_name));
1054      algo->crypt.alg_key_len = inAlgo.key.size() * 8; // bits
1055      memcpy(algo->key, &inAlgo.key[0], inAlgo.key.size());
1056      len += inAlgo.key.size();
1057      fillXfrmNlaHdr(&algo->hdr, XFRMA_ALG_CRYPT, len);
1058      return len;
1059  }
1060  
fillNlAttrXfrmAlgoAuth(const XfrmAlgo & inAlgo,nlattr_algo_auth * algo)1061  int XfrmController::fillNlAttrXfrmAlgoAuth(const XfrmAlgo& inAlgo, nlattr_algo_auth* algo) {
1062      if (inAlgo.name.empty()) { // Do not fill anything if algorithm not provided
1063          return 0;
1064      }
1065  
1066      int len = NLA_HDRLEN + sizeof(xfrm_algo_auth);
1067      // Kernel always changes last char to null terminator; no safety checks needed.
1068      strncpy(algo->auth.alg_name, inAlgo.name.c_str(), sizeof(algo->auth.alg_name));
1069      algo->auth.alg_key_len = inAlgo.key.size() * 8; // bits
1070  
1071      // This is the extra field for ALG_AUTH_TRUNC
1072      algo->auth.alg_trunc_len = inAlgo.truncLenBits;
1073  
1074      memcpy(algo->key, &inAlgo.key[0], inAlgo.key.size());
1075      len += inAlgo.key.size();
1076  
1077      fillXfrmNlaHdr(&algo->hdr, XFRMA_ALG_AUTH_TRUNC, len);
1078      return len;
1079  }
1080  
fillNlAttrXfrmAlgoAead(const XfrmAlgo & inAlgo,nlattr_algo_aead * algo)1081  int XfrmController::fillNlAttrXfrmAlgoAead(const XfrmAlgo& inAlgo, nlattr_algo_aead* algo) {
1082      if (inAlgo.name.empty()) { // Do not fill anything if algorithm not provided
1083          return 0;
1084      }
1085  
1086      int len = NLA_HDRLEN + sizeof(xfrm_algo_aead);
1087      // Kernel always changes last char to null terminator; no safety checks needed.
1088      strncpy(algo->aead.alg_name, inAlgo.name.c_str(), sizeof(algo->aead.alg_name));
1089      algo->aead.alg_key_len = inAlgo.key.size() * 8; // bits
1090  
1091      // This is the extra field for ALG_AEAD. ICV length is the same as truncation length
1092      // for any AEAD algorithm.
1093      algo->aead.alg_icv_len = inAlgo.truncLenBits;
1094  
1095      memcpy(algo->key, &inAlgo.key[0], inAlgo.key.size());
1096      len += inAlgo.key.size();
1097  
1098      fillXfrmNlaHdr(&algo->hdr, XFRMA_ALG_AEAD, len);
1099      return len;
1100  }
1101  
fillNlAttrXfrmEncapTmpl(const XfrmSaInfo & record,nlattr_encap_tmpl * tmpl)1102  int XfrmController::fillNlAttrXfrmEncapTmpl(const XfrmSaInfo& record, nlattr_encap_tmpl* tmpl) {
1103      if (record.encap.type == XfrmEncapType::NONE) {
1104          return 0;
1105      }
1106  
1107      int len = NLA_HDRLEN + sizeof(xfrm_encap_tmpl);
1108      tmpl->tmpl.encap_type = static_cast<uint16_t>(record.encap.type);
1109      tmpl->tmpl.encap_sport = htons(record.encap.srcPort);
1110      tmpl->tmpl.encap_dport = htons(record.encap.dstPort);
1111      fillXfrmNlaHdr(&tmpl->hdr, XFRMA_ENCAP, len);
1112      return len;
1113  }
1114  
fillUserSaInfo(const XfrmSaInfo & record,xfrm_usersa_info * usersa)1115  int XfrmController::fillUserSaInfo(const XfrmSaInfo& record, xfrm_usersa_info* usersa) {
1116      // Use AF_UNSPEC for all SAs. In transport mode, kernel picks selector family based on
1117      // usersa->family, while in tunnel mode, the XFRM_STATE_AF_UNSPEC flag allows dual-stack SAs.
1118      fillXfrmSelector(AF_UNSPEC, &usersa->sel);
1119  
1120      usersa->id.proto = IPPROTO_ESP;
1121      usersa->id.spi = record.spi;
1122      usersa->id.daddr = record.dstAddr;
1123  
1124      usersa->saddr = record.srcAddr;
1125  
1126      fillXfrmLifetimeDefaults(&usersa->lft);
1127      fillXfrmCurLifetimeDefaults(&usersa->curlft);
1128      memset(&usersa->stats, 0, sizeof(usersa->stats)); // leave stats zeroed out
1129      usersa->reqid = record.transformId;
1130      usersa->family = record.addrFamily;
1131      usersa->mode = static_cast<uint8_t>(record.mode);
1132      usersa->replay_window = REPLAY_WINDOW_SIZE;
1133  
1134      if (record.mode == XfrmMode::TRANSPORT) {
1135          usersa->flags = 0; // TODO: should we actually set flags, XFRM_SA_XFLAG_DONT_ENCAP_DSCP?
1136      } else {
1137          usersa->flags = XFRM_STATE_AF_UNSPEC;
1138      }
1139  
1140      return sizeof(*usersa);
1141  }
1142  
fillUserSaId(const XfrmCommonInfo & record,xfrm_usersa_id * said)1143  int XfrmController::fillUserSaId(const XfrmCommonInfo& record, xfrm_usersa_id* said) {
1144      said->daddr = record.dstAddr;
1145      said->spi = record.spi;
1146      said->family = record.addrFamily;
1147      said->proto = IPPROTO_ESP;
1148  
1149      return sizeof(*said);
1150  }
1151  
deleteSecurityAssociation(const XfrmCommonInfo & record,const XfrmSocket & sock)1152  netdutils::Status XfrmController::deleteSecurityAssociation(const XfrmCommonInfo& record,
1153                                                              const XfrmSocket& sock) {
1154      xfrm_usersa_id said{};
1155      nlattr_xfrm_mark xfrmmark{};
1156      nlattr_xfrm_interface_id xfrm_if_id{};
1157  
1158      enum { NLMSG_HDR, USERSAID, USERSAID_PAD, MARK, MARK_PAD, INTF_ID, INTF_ID_PAD };
1159  
1160      std::vector<iovec> iov = {
1161              {nullptr, 0},      // reserved for the eventual addition of a NLMSG_HDR
1162              {&said, 0},        // main usersa_info struct
1163              {kPadBytes, 0},    // up to NLMSG_ALIGNTO pad bytes of padding
1164              {&xfrmmark, 0},    // adjust size if xfrm mark is present
1165              {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
1166              {&xfrm_if_id, 0},  // adjust size if interface ID is present
1167              {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
1168      };
1169  
1170      int len;
1171      len = iov[USERSAID].iov_len = fillUserSaId(record, &said);
1172      iov[USERSAID_PAD].iov_len = NLMSG_ALIGN(len) - len;
1173  
1174      len = iov[MARK].iov_len = fillNlAttrXfrmMark(record, &xfrmmark);
1175      iov[MARK_PAD].iov_len = NLA_ALIGN(len) - len;
1176  
1177      len = iov[INTF_ID].iov_len = fillNlAttrXfrmIntfId(record.xfrm_if_id, &xfrm_if_id);
1178      iov[INTF_ID_PAD].iov_len = NLA_ALIGN(len) - len;
1179  
1180      return sock.sendMessage(XFRM_MSG_DELSA, NETLINK_REQUEST_FLAGS, 0, &iov);
1181  }
1182  
migrate(const XfrmMigrateInfo & record,const XfrmSocket & sock)1183  netdutils::Status XfrmController::migrate(const XfrmMigrateInfo& record, const XfrmSocket& sock) {
1184      xfrm_userpolicy_id xfrm_policyid{};
1185      nlattr_xfrm_user_migrate xfrm_migrate{};
1186  
1187      __kernel_size_t lenPolicyId = fillUserPolicyId(record, &xfrm_policyid);
1188      __kernel_size_t lenXfrmMigrate = fillNlAttrXfrmMigrate(record, &xfrm_migrate);
1189  
1190      std::vector<iovec> iov = {
1191              {nullptr, 0},  // reserved for the eventual addition of a NLMSG_HDR
1192              {&xfrm_policyid, lenPolicyId},
1193              {kPadBytes, NLMSG_ALIGN(lenPolicyId) - lenPolicyId},
1194              {&xfrm_migrate, lenXfrmMigrate},
1195              {kPadBytes, NLMSG_ALIGN(lenXfrmMigrate) - lenXfrmMigrate},
1196      };
1197  
1198      return sock.sendMessage(XFRM_MSG_MIGRATE, NETLINK_REQUEST_FLAGS, 0, &iov);
1199  }
1200  
allocateSpi(const XfrmSaInfo & record,uint32_t minSpi,uint32_t maxSpi,uint32_t * outSpi,const XfrmSocket & sock)1201  netdutils::Status XfrmController::allocateSpi(const XfrmSaInfo& record, uint32_t minSpi,
1202                                                uint32_t maxSpi, uint32_t* outSpi,
1203                                                const XfrmSocket& sock) {
1204      xfrm_userspi_info spiInfo{};
1205  
1206      enum { NLMSG_HDR, USERSAID, USERSAID_PAD };
1207  
1208      std::vector<iovec> iov = {
1209          {nullptr, 0},      // reserved for the eventual addition of a NLMSG_HDR
1210          {&spiInfo, 0},  // main userspi_info struct
1211          {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
1212      };
1213  
1214      int len;
1215      if (fillUserSaInfo(record, &spiInfo.info) == 0) {
1216          ALOGE("Failed to fill transport SA Info");
1217      }
1218  
1219      len = iov[USERSAID].iov_len = sizeof(spiInfo);
1220      iov[USERSAID_PAD].iov_len = NLMSG_ALIGN(len) - len;
1221  
1222      RandomSpi spiGen = RandomSpi(minSpi, maxSpi);
1223      int spi;
1224      netdutils::Status ret;
1225      while ((spi = spiGen.next()) != INVALID_SPI) {
1226          spiInfo.min = spi;
1227          spiInfo.max = spi;
1228          ret = sock.sendMessage(XFRM_MSG_ALLOCSPI, NETLINK_REQUEST_FLAGS, 0, &iov);
1229  
1230          /* If the SPI is in use, we'll get ENOENT */
1231          if (netdutils::equalToErrno(ret, ENOENT))
1232              continue;
1233  
1234          if (isOk(ret)) {
1235              *outSpi = spi;
1236              ALOGD("Allocated an SPI: %x", *outSpi);
1237          } else {
1238              *outSpi = INVALID_SPI;
1239              ALOGE("SPI Allocation Failed with error %d", ret.code());
1240          }
1241  
1242          return ret;
1243      }
1244  
1245      // Should always be -ENOENT if we get here
1246      return ret;
1247  }
1248  
updateTunnelModeSecurityPolicy(const XfrmSpInfo & record,const XfrmSocket & sock,uint16_t msgType)1249  netdutils::Status XfrmController::updateTunnelModeSecurityPolicy(const XfrmSpInfo& record,
1250                                                                   const XfrmSocket& sock,
1251                                                                   uint16_t msgType) {
1252      xfrm_userpolicy_info userpolicy{};
1253      nlattr_user_tmpl usertmpl{};
1254      nlattr_xfrm_mark xfrmmark{};
1255      nlattr_xfrm_interface_id xfrm_if_id{};
1256  
1257      enum {
1258          NLMSG_HDR,
1259          USERPOLICY,
1260          USERPOLICY_PAD,
1261          USERTMPL,
1262          USERTMPL_PAD,
1263          MARK,
1264          MARK_PAD,
1265          INTF_ID,
1266          INTF_ID_PAD,
1267      };
1268  
1269      std::vector<iovec> iov = {
1270              {nullptr, 0},      // reserved for the eventual addition of a NLMSG_HDR
1271              {&userpolicy, 0},  // main xfrm_userpolicy_info struct
1272              {kPadBytes, 0},    // up to NLMSG_ALIGNTO pad bytes of padding
1273              {&usertmpl, 0},    // adjust size if xfrm_user_tmpl struct is present
1274              {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
1275              {&xfrmmark, 0},    // adjust size if xfrm mark is present
1276              {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
1277              {&xfrm_if_id, 0},  // adjust size if interface ID is present
1278              {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
1279      };
1280  
1281      int len;
1282      len = iov[USERPOLICY].iov_len = fillUserSpInfo(record, &userpolicy);
1283      iov[USERPOLICY_PAD].iov_len = NLMSG_ALIGN(len) - len;
1284  
1285      len = iov[USERTMPL].iov_len = fillNlAttrUserTemplate(record, &usertmpl);
1286      iov[USERTMPL_PAD].iov_len = NLA_ALIGN(len) - len;
1287  
1288      len = iov[MARK].iov_len = fillNlAttrXfrmMark(record, &xfrmmark);
1289      iov[MARK_PAD].iov_len = NLA_ALIGN(len) - len;
1290  
1291      len = iov[INTF_ID].iov_len = fillNlAttrXfrmIntfId(record.xfrm_if_id, &xfrm_if_id);
1292      iov[INTF_ID_PAD].iov_len = NLA_ALIGN(len) - len;
1293  
1294      return sock.sendMessage(msgType, NETLINK_REQUEST_FLAGS, 0, &iov);
1295  }
1296  
deleteTunnelModeSecurityPolicy(const XfrmSpInfo & record,const XfrmSocket & sock)1297  netdutils::Status XfrmController::deleteTunnelModeSecurityPolicy(const XfrmSpInfo& record,
1298                                                                   const XfrmSocket& sock) {
1299      xfrm_userpolicy_id policyid{};
1300      nlattr_xfrm_mark xfrmmark{};
1301      nlattr_xfrm_interface_id xfrm_if_id{};
1302  
1303      enum {
1304          NLMSG_HDR,
1305          USERPOLICYID,
1306          USERPOLICYID_PAD,
1307          MARK,
1308          MARK_PAD,
1309          INTF_ID,
1310          INTF_ID_PAD,
1311      };
1312  
1313      std::vector<iovec> iov = {
1314              {nullptr, 0},      // reserved for the eventual addition of a NLMSG_HDR
1315              {&policyid, 0},    // main xfrm_userpolicy_id struct
1316              {kPadBytes, 0},    // up to NLMSG_ALIGNTO pad bytes of padding
1317              {&xfrmmark, 0},    // adjust size if xfrm mark is present
1318              {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
1319              {&xfrm_if_id, 0},  // adjust size if interface ID is present
1320              {kPadBytes, 0},    // up to NLATTR_ALIGNTO pad bytes
1321      };
1322  
1323      int len = iov[USERPOLICYID].iov_len = fillUserPolicyId(record, &policyid);
1324      iov[USERPOLICYID_PAD].iov_len = NLMSG_ALIGN(len) - len;
1325  
1326      len = iov[MARK].iov_len = fillNlAttrXfrmMark(record, &xfrmmark);
1327      iov[MARK_PAD].iov_len = NLA_ALIGN(len) - len;
1328  
1329      len = iov[INTF_ID].iov_len = fillNlAttrXfrmIntfId(record.xfrm_if_id, &xfrm_if_id);
1330      iov[INTF_ID_PAD].iov_len = NLA_ALIGN(len) - len;
1331  
1332      return sock.sendMessage(XFRM_MSG_DELPOLICY, NETLINK_REQUEST_FLAGS, 0, &iov);
1333  }
1334  
fillUserSpInfo(const XfrmSpInfo & record,xfrm_userpolicy_info * usersp)1335  int XfrmController::fillUserSpInfo(const XfrmSpInfo& record, xfrm_userpolicy_info* usersp) {
1336      fillXfrmSelector(record.selAddrFamily, &usersp->sel);
1337      fillXfrmLifetimeDefaults(&usersp->lft);
1338      fillXfrmCurLifetimeDefaults(&usersp->curlft);
1339      /* if (index) index & 0x3 == dir -- must be true
1340       * xfrm_user.c:verify_newpolicy_info() */
1341      usersp->index = 0;
1342      usersp->dir = static_cast<uint8_t>(record.direction);
1343      usersp->action = XFRM_POLICY_ALLOW;
1344      usersp->flags = XFRM_POLICY_LOCALOK;
1345      usersp->share = XFRM_SHARE_UNIQUE;
1346      return sizeof(*usersp);
1347  }
1348  
fillUserTemplate(const XfrmSpInfo & record,xfrm_user_tmpl * tmpl)1349  void XfrmController::fillUserTemplate(const XfrmSpInfo& record, xfrm_user_tmpl* tmpl) {
1350      tmpl->id.daddr = record.dstAddr;
1351      tmpl->id.spi = record.spi;
1352      tmpl->id.proto = IPPROTO_ESP;
1353  
1354      tmpl->family = record.addrFamily;
1355      tmpl->saddr = record.srcAddr;
1356      tmpl->reqid = record.transformId;
1357      tmpl->mode = static_cast<uint8_t>(record.mode);
1358      tmpl->share = XFRM_SHARE_UNIQUE;
1359      tmpl->optional = 0; // if this is true, then a failed state lookup will be considered OK:
1360                          // http://lxr.free-electrons.com/source/net/xfrm/xfrm_policy.c#L1492
1361      tmpl->aalgos = ALGO_MASK_AUTH_ALL;  // TODO: if there's a bitmask somewhere of
1362                                          // algos, we should find it and apply it.
1363                                          // I can't find one.
1364      tmpl->ealgos = ALGO_MASK_CRYPT_ALL; // TODO: if there's a bitmask somewhere...
1365  }
1366  
fillNlAttrUserTemplate(const XfrmSpInfo & record,nlattr_user_tmpl * tmpl)1367  int XfrmController::fillNlAttrUserTemplate(const XfrmSpInfo& record, nlattr_user_tmpl* tmpl) {
1368      fillUserTemplate(record, &tmpl->tmpl);
1369  
1370      int len = NLA_HDRLEN + sizeof(xfrm_user_tmpl);
1371      fillXfrmNlaHdr(&tmpl->hdr, XFRMA_TMPL, len);
1372      return len;
1373  }
1374  
fillNlAttrXfrmMark(const XfrmCommonInfo & record,nlattr_xfrm_mark * mark)1375  int XfrmController::fillNlAttrXfrmMark(const XfrmCommonInfo& record, nlattr_xfrm_mark* mark) {
1376      // Do not set if we were not given a mark
1377      if (record.mark.v == 0 && record.mark.m == 0) {
1378          return 0;
1379      }
1380  
1381      mark->mark.v = record.mark.v; // set to 0 if it's not used
1382      mark->mark.m = record.mark.m; // set to 0 if it's not used
1383      int len = NLA_HDRLEN + sizeof(xfrm_mark);
1384      fillXfrmNlaHdr(&mark->hdr, XFRMA_MARK, len);
1385      return len;
1386  }
1387  
1388  // This function sets the output mark (or set-mark in newer kernels) to that of the underlying
1389  // Network's netid. This allows outbound IPsec Tunnel mode packets to be correctly directed to a
1390  // preselected underlying Network. Outbound packets are marked as protected from VPNs and have a
1391  // network explicitly selected to prevent interference or routing loops. Also sets permission flag
1392  // to PERMISSION_SYSTEM to allow use of background/restricted networks. Inbound packets have all
1393  // the flags and fields cleared to simulate the decapsulated packet being a fresh, unseen packet.
fillNlAttrXfrmOutputMark(const XfrmSaInfo & record,nlattr_xfrm_output_mark * output_mark)1394  int XfrmController::fillNlAttrXfrmOutputMark(const XfrmSaInfo& record,
1395                                               nlattr_xfrm_output_mark* output_mark) {
1396      // Only set for tunnel mode transforms
1397      if (record.mode != XfrmMode::TUNNEL) {
1398          return 0;
1399      }
1400  
1401      Fwmark fwmark;
1402  
1403      // Only outbound transforms have an underlying network set.
1404      if (record.netId != 0) {
1405          fwmark.netId = record.netId;
1406          fwmark.permission = PERMISSION_SYSTEM;
1407          fwmark.explicitlySelected = true;
1408          fwmark.protectedFromVpn = true;
1409      }
1410  
1411      // Else (inbound transforms), reset to default mark (empty); UID billing for inbound tunnel mode
1412      // transforms are exclusively done on inner packet, and therefore can never have been set.
1413  
1414      output_mark->outputMark = fwmark.intValue;
1415  
1416      int len = NLA_HDRLEN + sizeof(__u32);
1417      fillXfrmNlaHdr(&output_mark->hdr, XFRMA_OUTPUT_MARK, len);
1418      return len;
1419  }
1420  
fillNlAttrXfrmIntfId(const uint32_t intfIdValue,nlattr_xfrm_interface_id * intf_id)1421  int XfrmController::fillNlAttrXfrmIntfId(const uint32_t intfIdValue,
1422                                           nlattr_xfrm_interface_id* intf_id) {
1423      // Do not set if we were not given an interface id
1424      if (intfIdValue == 0) {
1425          return 0;
1426      }
1427  
1428      intf_id->if_id = intfIdValue;
1429      int len = NLA_HDRLEN + sizeof(__u32);
1430      fillXfrmNlaHdr(&intf_id->hdr, XFRMA_IF_ID, len);
1431      return len;
1432  }
1433  
fillNlAttrXfrmReplayEsn(nlattr_xfrm_replay_esn * replay_esn)1434  int XfrmController::fillNlAttrXfrmReplayEsn(nlattr_xfrm_replay_esn* replay_esn) {
1435      replay_esn->replay_state.replay_window = REPLAY_WINDOW_SIZE_ESN;
1436      replay_esn->replay_state.bmp_len = (REPLAY_WINDOW_SIZE_ESN + 31) / 32;
1437  
1438      // bmp array allocated in kernel, this does NOT account for that.
1439      const int len = NLA_HDRLEN + sizeof(xfrm_replay_state_esn);
1440      fillXfrmNlaHdr(&replay_esn->hdr, XFRMA_REPLAY_ESN_VAL, len);
1441      return len;
1442  }
1443  
fillNlAttrXfrmMigrate(const XfrmMigrateInfo & record,nlattr_xfrm_user_migrate * migrate)1444  int XfrmController::fillNlAttrXfrmMigrate(const XfrmMigrateInfo& record,
1445                                            nlattr_xfrm_user_migrate* migrate) {
1446      migrate->migrate.old_daddr = record.dstAddr;
1447      migrate->migrate.old_saddr = record.srcAddr;
1448      migrate->migrate.new_daddr = record.newEndpointInfo.dstAddr;
1449      migrate->migrate.new_saddr = record.newEndpointInfo.srcAddr;
1450      migrate->migrate.proto = IPPROTO_ESP;
1451      migrate->migrate.mode = static_cast<uint8_t>(XfrmMode::TUNNEL);
1452      migrate->migrate.reqid = record.transformId;
1453      migrate->migrate.old_family = record.addrFamily;
1454      migrate->migrate.new_family = record.newEndpointInfo.addrFamily;
1455  
1456      int len = NLA_HDRLEN + sizeof(xfrm_user_migrate);
1457      fillXfrmNlaHdr(&migrate->hdr, XFRMA_MIGRATE, len);
1458  
1459      return len;
1460  }
1461  
fillUserPolicyId(const XfrmSpInfo & record,xfrm_userpolicy_id * usersp)1462  int XfrmController::fillUserPolicyId(const XfrmSpInfo& record, xfrm_userpolicy_id* usersp) {
1463      // For DELPOLICY, when index is absent, selector is needed to match the policy
1464      fillXfrmSelector(record.selAddrFamily, &usersp->sel);
1465      usersp->dir = static_cast<uint8_t>(record.direction);
1466      return sizeof(*usersp);
1467  }
1468  
ipSecAddTunnelInterface(const std::string & deviceName,const std::string & localAddress,const std::string & remoteAddress,int32_t ikey,int32_t okey,int32_t interfaceId,bool isUpdate)1469  netdutils::Status XfrmController::ipSecAddTunnelInterface(const std::string& deviceName,
1470                                                            const std::string& localAddress,
1471                                                            const std::string& remoteAddress,
1472                                                            int32_t ikey, int32_t okey,
1473                                                            int32_t interfaceId, bool isUpdate) {
1474      ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
1475      ALOGD("deviceName=%s", deviceName.c_str());
1476      ALOGD("localAddress=%s", localAddress.c_str());
1477      ALOGD("remoteAddress=%s", remoteAddress.c_str());
1478      ALOGD("ikey=%0.8x", ikey);
1479      ALOGD("okey=%0.8x", okey);
1480      ALOGD("interfaceId=%0.8x", interfaceId);
1481      ALOGD("isUpdate=%d", isUpdate);
1482  
1483      uint16_t flags = isUpdate ? NETLINK_REQUEST_FLAGS : NETLINK_ROUTE_CREATE_FLAGS;
1484  
1485      if (mIsXfrmIntfSupported) {
1486          return ipSecAddXfrmInterface(deviceName, interfaceId, flags);
1487      } else {
1488          return ipSecAddVirtualTunnelInterface(deviceName, localAddress, remoteAddress, ikey, okey,
1489                                                flags);
1490      }
1491  }
1492  
ipSecAddXfrmInterface(const std::string & deviceName,int32_t interfaceId,uint16_t flags)1493  netdutils::Status XfrmController::ipSecAddXfrmInterface(const std::string& deviceName,
1494                                                          int32_t interfaceId, uint16_t flags) {
1495      ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
1496  
1497      if (deviceName.empty()) {
1498          return netdutils::statusFromErrno(EINVAL, "XFRM Interface deviceName empty");
1499      }
1500  
1501      ifinfomsg ifInfoMsg{};
1502  
1503      struct XfrmIntfCreateReq {
1504          nlattr ifNameNla;
1505          char ifName[IFNAMSIZ];  // Already aligned
1506  
1507          nlattr linkInfoNla;
1508          struct LinkInfo {
1509              nlattr infoKindNla;
1510              char infoKind[INFO_KIND_MAX_LEN];  // Already aligned
1511  
1512              nlattr infoDataNla;
1513              struct InfoData {
1514                  nlattr xfrmLinkNla;
1515                  uint32_t xfrmLink;
1516  
1517                  nlattr xfrmIfIdNla;
1518                  uint32_t xfrmIfId;
1519              } infoData;  // Already aligned
1520  
1521          } linkInfo;  // Already aligned
1522      } xfrmIntfCreateReq{
1523              .ifNameNla =
1524                      {
1525                              .nla_len = RTA_LENGTH(IFNAMSIZ),
1526                              .nla_type = IFLA_IFNAME,
1527                      },
1528              // Update .ifName via strlcpy
1529  
1530              .linkInfoNla =
1531                      {
1532                              .nla_len = RTA_LENGTH(sizeof(XfrmIntfCreateReq::LinkInfo)),
1533                              .nla_type = IFLA_LINKINFO,
1534                      },
1535              .linkInfo = {.infoKindNla =
1536                                   {
1537                                           .nla_len = RTA_LENGTH(INFO_KIND_MAX_LEN),
1538                                           .nla_type = IFLA_INFO_KIND,
1539                                   },
1540                           // Update .infoKind via strlcpy
1541  
1542                           .infoDataNla =
1543                                   {
1544                                           .nla_len = RTA_LENGTH(
1545                                                   sizeof(XfrmIntfCreateReq::LinkInfo::InfoData)),
1546                                           .nla_type = IFLA_INFO_DATA,
1547                                   },
1548                           .infoData = {
1549                                   .xfrmLinkNla =
1550                                           {
1551                                                   .nla_len = RTA_LENGTH(sizeof(uint32_t)),
1552                                                   .nla_type = IFLA_XFRM_LINK,
1553                                           },
1554                                   //   Always use LOOPBACK_IFINDEX, since we use output marks for
1555                                   //   route lookup instead. The use case of having a Network with
1556                                   //   loopback in it is unsupported in tunnel mode.
1557                                   .xfrmLink = static_cast<uint32_t>(LOOPBACK_IFINDEX),
1558  
1559                                   .xfrmIfIdNla =
1560                                           {
1561                                                   .nla_len = RTA_LENGTH(sizeof(uint32_t)),
1562                                                   .nla_type = IFLA_XFRM_IF_ID,
1563                                           },
1564                                   .xfrmIfId = static_cast<uint32_t>(interfaceId),
1565                           }}};
1566  
1567      strlcpy(xfrmIntfCreateReq.ifName, deviceName.c_str(), IFNAMSIZ);
1568      strlcpy(xfrmIntfCreateReq.linkInfo.infoKind, INFO_KIND_XFRMI, INFO_KIND_MAX_LEN);
1569  
1570      iovec iov[] = {
1571              {NULL, 0},  // reserved for the eventual addition of a NLMSG_HDR
1572              {&ifInfoMsg, sizeof(ifInfoMsg)},
1573  
1574              {&xfrmIntfCreateReq, sizeof(xfrmIntfCreateReq)},
1575      };
1576  
1577      // sendNetlinkRequest returns -errno
1578      int ret = -sendNetlinkRequest(RTM_NEWLINK, flags, iov, ARRAY_SIZE(iov), nullptr);
1579      return netdutils::statusFromErrno(ret, "Add/update xfrm interface");
1580  }
1581  
ipSecAddVirtualTunnelInterface(const std::string & deviceName,const std::string & localAddress,const std::string & remoteAddress,int32_t ikey,int32_t okey,uint16_t flags)1582  netdutils::Status XfrmController::ipSecAddVirtualTunnelInterface(const std::string& deviceName,
1583                                                                   const std::string& localAddress,
1584                                                                   const std::string& remoteAddress,
1585                                                                   int32_t ikey, int32_t okey,
1586                                                                   uint16_t flags) {
1587      ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
1588  
1589      if (deviceName.empty() || localAddress.empty() || remoteAddress.empty()) {
1590          return netdutils::statusFromErrno(EINVAL, "Required VTI creation parameter not provided");
1591      }
1592  
1593      uint8_t PADDING_BUFFER[] = {0, 0, 0, 0};
1594  
1595      // Find address family.
1596      uint8_t remAddr[sizeof(in6_addr)];
1597  
1598      StatusOr<uint16_t> statusOrRemoteFam = convertStringAddress(remoteAddress, remAddr);
1599      RETURN_IF_NOT_OK(statusOrRemoteFam);
1600  
1601      uint8_t locAddr[sizeof(in6_addr)];
1602      StatusOr<uint16_t> statusOrLocalFam = convertStringAddress(localAddress, locAddr);
1603      RETURN_IF_NOT_OK(statusOrLocalFam);
1604  
1605      if (statusOrLocalFam.value() != statusOrRemoteFam.value()) {
1606          return netdutils::statusFromErrno(EINVAL, "Local and remote address families do not match");
1607      }
1608  
1609      uint16_t family = statusOrLocalFam.value();
1610  
1611      ifinfomsg ifInfoMsg{};
1612  
1613      // Construct IFLA_IFNAME
1614      nlattr iflaIfName;
1615      char iflaIfNameStrValue[deviceName.length() + 1];
1616      size_t iflaIfNameLength =
1617          strlcpy(iflaIfNameStrValue, deviceName.c_str(), sizeof(iflaIfNameStrValue));
1618      size_t iflaIfNamePad = fillNlAttr(IFLA_IFNAME, iflaIfNameLength, &iflaIfName);
1619  
1620      // Construct IFLA_INFO_KIND
1621      // Constants "vti6" and "vti" enable the kernel to call different code paths,
1622      // (ip_tunnel.c, ip6_tunnel), based on the family.
1623      const std::string infoKindValue = (family == AF_INET6) ? INFO_KIND_VTI6 : INFO_KIND_VTI;
1624      nlattr iflaIfInfoKind;
1625      char infoKindValueStrValue[infoKindValue.length() + 1];
1626      size_t iflaIfInfoKindLength =
1627          strlcpy(infoKindValueStrValue, infoKindValue.c_str(), sizeof(infoKindValueStrValue));
1628      size_t iflaIfInfoKindPad = fillNlAttr(IFLA_INFO_KIND, iflaIfInfoKindLength, &iflaIfInfoKind);
1629  
1630      // Construct IFLA_VTI_LOCAL
1631      nlattr iflaVtiLocal;
1632      uint8_t binaryLocalAddress[sizeof(in6_addr)];
1633      size_t iflaVtiLocalPad =
1634          fillNlAttrIpAddress(IFLA_VTI_LOCAL, family, localAddress, &iflaVtiLocal,
1635                              netdutils::makeSlice(binaryLocalAddress));
1636  
1637      // Construct IFLA_VTI_REMOTE
1638      nlattr iflaVtiRemote;
1639      uint8_t binaryRemoteAddress[sizeof(in6_addr)];
1640      size_t iflaVtiRemotePad =
1641          fillNlAttrIpAddress(IFLA_VTI_REMOTE, family, remoteAddress, &iflaVtiRemote,
1642                              netdutils::makeSlice(binaryRemoteAddress));
1643  
1644      // Construct IFLA_VTI_OKEY
1645      nlattr_payload_u32 iflaVtiIKey;
1646      size_t iflaVtiIKeyPad = fillNlAttrU32(IFLA_VTI_IKEY, htonl(ikey), &iflaVtiIKey);
1647  
1648      // Construct IFLA_VTI_IKEY
1649      nlattr_payload_u32 iflaVtiOKey;
1650      size_t iflaVtiOKeyPad = fillNlAttrU32(IFLA_VTI_OKEY, htonl(okey), &iflaVtiOKey);
1651  
1652      int iflaInfoDataPayloadLength = iflaVtiLocal.nla_len + iflaVtiLocalPad + iflaVtiRemote.nla_len +
1653                                      iflaVtiRemotePad + iflaVtiIKey.hdr.nla_len + iflaVtiIKeyPad +
1654                                      iflaVtiOKey.hdr.nla_len + iflaVtiOKeyPad;
1655  
1656      // Construct IFLA_INFO_DATA
1657      nlattr iflaInfoData;
1658      size_t iflaInfoDataPad = fillNlAttr(IFLA_INFO_DATA, iflaInfoDataPayloadLength, &iflaInfoData);
1659  
1660      // Construct IFLA_LINKINFO
1661      nlattr iflaLinkInfo;
1662      size_t iflaLinkInfoPad = fillNlAttr(IFLA_LINKINFO,
1663                                          iflaInfoData.nla_len + iflaInfoDataPad +
1664                                              iflaIfInfoKind.nla_len + iflaIfInfoKindPad,
1665                                          &iflaLinkInfo);
1666  
1667      iovec iov[] = {
1668              {nullptr, 0},
1669              {&ifInfoMsg, sizeof(ifInfoMsg)},
1670  
1671              {&iflaIfName, sizeof(iflaIfName)},
1672              {iflaIfNameStrValue, iflaIfNameLength},
1673              {&PADDING_BUFFER, iflaIfNamePad},
1674  
1675              {&iflaLinkInfo, sizeof(iflaLinkInfo)},
1676  
1677              {&iflaIfInfoKind, sizeof(iflaIfInfoKind)},
1678              {infoKindValueStrValue, iflaIfInfoKindLength},
1679              {&PADDING_BUFFER, iflaIfInfoKindPad},
1680  
1681              {&iflaInfoData, sizeof(iflaInfoData)},
1682  
1683              {&iflaVtiLocal, sizeof(iflaVtiLocal)},
1684              {&binaryLocalAddress, (family == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr)},
1685              {&PADDING_BUFFER, iflaVtiLocalPad},
1686  
1687              {&iflaVtiRemote, sizeof(iflaVtiRemote)},
1688              {&binaryRemoteAddress, (family == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr)},
1689              {&PADDING_BUFFER, iflaVtiRemotePad},
1690  
1691              {&iflaVtiIKey, iflaVtiIKey.hdr.nla_len},
1692              {&PADDING_BUFFER, iflaVtiIKeyPad},
1693  
1694              {&iflaVtiOKey, iflaVtiOKey.hdr.nla_len},
1695              {&PADDING_BUFFER, iflaVtiOKeyPad},
1696  
1697              {&PADDING_BUFFER, iflaInfoDataPad},
1698  
1699              {&PADDING_BUFFER, iflaLinkInfoPad},
1700      };
1701  
1702      // sendNetlinkRequest returns -errno
1703      int ret = -1 * sendNetlinkRequest(RTM_NEWLINK, flags, iov, ARRAY_SIZE(iov), nullptr);
1704      return netdutils::statusFromErrno(ret, "Failed to add/update virtual tunnel interface");
1705  }
1706  
ipSecRemoveTunnelInterface(const std::string & deviceName)1707  netdutils::Status XfrmController::ipSecRemoveTunnelInterface(const std::string& deviceName) {
1708      ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
1709      ALOGD("deviceName=%s", deviceName.c_str());
1710  
1711      if (deviceName.empty()) {
1712          return netdutils::statusFromErrno(EINVAL, "Required parameter not provided");
1713      }
1714  
1715      uint8_t PADDING_BUFFER[] = {0, 0, 0, 0};
1716  
1717      ifinfomsg ifInfoMsg{};
1718      nlattr iflaIfName;
1719      char iflaIfNameStrValue[deviceName.length() + 1];
1720      size_t iflaIfNameLength =
1721          strlcpy(iflaIfNameStrValue, deviceName.c_str(), sizeof(iflaIfNameStrValue));
1722      size_t iflaIfNamePad = fillNlAttr(IFLA_IFNAME, iflaIfNameLength, &iflaIfName);
1723  
1724      iovec iov[] = {
1725          {nullptr, 0},
1726          {&ifInfoMsg, sizeof(ifInfoMsg)},
1727  
1728          {&iflaIfName, sizeof(iflaIfName)},
1729          {iflaIfNameStrValue, iflaIfNameLength},
1730          {&PADDING_BUFFER, iflaIfNamePad},
1731      };
1732  
1733      uint16_t action = RTM_DELLINK;
1734      uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
1735  
1736      // sendNetlinkRequest returns -errno
1737      int ret = -1 * sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov), nullptr);
1738      return netdutils::statusFromErrno(ret, "Error in deleting IpSec interface " + deviceName);
1739  }
1740  
dump(DumpWriter & dw)1741  void XfrmController::dump(DumpWriter& dw) {
1742      ScopedIndent indentForXfrmController(dw);
1743      dw.println("XfrmController");
1744  
1745      ScopedIndent indentForXfrmISupport(dw);
1746      dw.println("XFRM-I support: %d", mIsXfrmIntfSupported);
1747  }
1748  
1749  } // namespace net
1750  } // namespace android
1751