Make Transforms Unidirectional

Convert the IpSecTransform from being a bi-directional
pair of SAs to a unidirectional single SA. This CL
also removes the concept of "direction from SAs meaning
that a IpSecTransform may now be applied to a socket
in either direction.

-Remove direction parameter from SAs and SPIs.
-Convert to using source and destination rather than
 local and remote addresses.

Bug: 71717213
Test: CTS - IpSecManagerTest
Change-Id: I7150c2b03057e18a7d9d3edff302baf10e1ee729
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index 24ccee4..648c7c0 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -352,18 +352,18 @@
     if (info.st_uid != callerUid) {
         return netdutils::statusFromErrno(EPERM, "fchown disabled for non-owner calls");
     }
-    if (S_ISSOCK(info.st_mode) == 0){
+    if (S_ISSOCK(info.st_mode) == 0) {
         return netdutils::statusFromErrno(EINVAL, "File descriptor was not a socket");
     }
 
     int optval;
     socklen_t optlen;
-    netdutils::Status status = getSyscallInstance().getsockopt(Fd(socket), IPPROTO_UDP, UDP_ENCAP,
-                                                               &optval, &optlen);
+    netdutils::Status status =
+        getSyscallInstance().getsockopt(Fd(socket), IPPROTO_UDP, UDP_ENCAP, &optval, &optlen);
     if (status != netdutils::status::ok) {
         return status;
     }
-    if (optval != UDP_ENCAP_ESPINUDP && optval != UDP_ENCAP_ESPINUDP_NON_IKE){
+    if (optval != UDP_ENCAP_ESPINUDP && optval != UDP_ENCAP_ESPINUDP_NON_IKE) {
         return netdutils::statusFromErrno(EINVAL, "Socket did not have UDP-encap sockopt set");
     }
     if (fchown(fd, newUid, -1)) {
@@ -373,20 +373,19 @@
     return netdutils::status::ok;
 }
 
-netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId, int32_t direction,
-                                                   const std::string& localAddress,
-                                                   const std::string& remoteAddress, int32_t inSpi,
-                                                   int32_t* outSpi) {
+netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId,
+                                                   const std::string& sourceAddress,
+                                                   const std::string& destinationAddress,
+                                                   int32_t inSpi, int32_t* outSpi) {
     ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
     ALOGD("transformId=%d", transformId);
-    ALOGD("direction=%d", direction);
-    ALOGD("localAddress=%s", localAddress.c_str());
-    ALOGD("remoteAddress=%s", remoteAddress.c_str());
+    ALOGD("sourceAddress=%s", sourceAddress.c_str());
+    ALOGD("destinationAddress=%s", destinationAddress.c_str());
     ALOGD("inSpi=%0.8x", inSpi);
 
     XfrmSaInfo saInfo{};
     netdutils::Status ret =
-        fillXfrmId(direction, localAddress, remoteAddress, INVALID_SPI, transformId, &saInfo);
+        fillXfrmId(sourceAddress, destinationAddress, INVALID_SPI, transformId, &saInfo);
     if (!isOk(ret)) {
         return ret;
     }
@@ -414,8 +413,8 @@
 }
 
 netdutils::Status XfrmController::ipSecAddSecurityAssociation(
-    int32_t transformId, int32_t mode, int32_t direction, const std::string& localAddress,
-    const std::string& remoteAddress, int64_t underlyingNetworkHandle, int32_t spi,
+    int32_t transformId, int32_t mode, const std::string& sourceAddress,
+    const std::string& destinationAddress, int64_t underlyingNetworkHandle, int32_t spi,
     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,
@@ -423,9 +422,8 @@
     ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
     ALOGD("transformId=%d", transformId);
     ALOGD("mode=%d", mode);
-    ALOGD("direction=%d", direction);
-    ALOGD("localAddress=%s", localAddress.c_str());
-    ALOGD("remoteAddress=%s", remoteAddress.c_str());
+    ALOGD("sourceAddress=%s", sourceAddress.c_str());
+    ALOGD("destinationAddress=%s", destinationAddress.c_str());
     ALOGD("underlyingNetworkHandle=%" PRIx64, underlyingNetworkHandle);
     ALOGD("spi=%0.8x", spi);
     ALOGD("authAlgo=%s", authAlgo.c_str());
@@ -440,7 +438,7 @@
 
     XfrmSaInfo saInfo{};
     netdutils::Status ret =
-        fillXfrmId(direction, localAddress, remoteAddress, spi, transformId, &saInfo);
+        fillXfrmId(sourceAddress, destinationAddress, spi, transformId, &saInfo);
     if (!isOk(ret)) {
         return ret;
     }
@@ -454,8 +452,6 @@
     saInfo.aead = XfrmAlgo{
         .name = aeadAlgo, .key = aeadKey, .truncLenBits = static_cast<uint16_t>(aeadIcvBits)};
 
-    saInfo.direction = static_cast<XfrmDirection>(direction);
-
     switch (static_cast<XfrmMode>(mode)) {
         case XfrmMode::TRANSPORT:
         case XfrmMode::TUNNEL:
@@ -478,18 +474,10 @@
             if (saInfo.addrFamily != AF_INET) {
                 return netdutils::statusFromErrno(EAFNOSUPPORT, "IPv6 encap not supported");
             }
-            switch (saInfo.direction) {
-                case XfrmDirection::IN:
-                    saInfo.encap.srcPort = encapRemotePort;
-                    saInfo.encap.dstPort = encapLocalPort;
-                    break;
-                case XfrmDirection::OUT:
-                    saInfo.encap.srcPort = encapLocalPort;
-                    saInfo.encap.dstPort = encapRemotePort;
-                    break;
-                default:
-                    return netdutils::statusFromErrno(EINVAL, "Invalid direction");
-            }
+            // The ports are not used on input SAs, so this is OK to be wrong when
+            // direction is ultimately input.
+            saInfo.encap.srcPort = encapLocalPort;
+            saInfo.encap.dstPort = encapRemotePort;
         // fall through
         case XfrmEncapType::NONE:
             saInfo.encap.type = static_cast<XfrmEncapType>(encapType);
@@ -506,21 +494,18 @@
     return ret;
 }
 
-netdutils::Status XfrmController::ipSecDeleteSecurityAssociation(int32_t transformId,
-                                                                 int32_t direction,
-                                                                 const std::string& localAddress,
-                                                                 const std::string& remoteAddress,
-                                                                 int32_t spi) {
+netdutils::Status
+XfrmController::ipSecDeleteSecurityAssociation(int32_t transformId,
+                                               const std::string& sourceAddress,
+                                               const std::string& destinationAddress, int32_t spi) {
     ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
     ALOGD("transformId=%d", transformId);
-    ALOGD("direction=%d", direction);
-    ALOGD("localAddress=%s", localAddress.c_str());
-    ALOGD("remoteAddress=%s", remoteAddress.c_str());
+    ALOGD("sourceAddress=%s", sourceAddress.c_str());
+    ALOGD("destinationAddress=%s", destinationAddress.c_str());
     ALOGD("spi=%0.8x", spi);
 
     XfrmId saId{};
-    netdutils::Status ret =
-        fillXfrmId(direction, localAddress, remoteAddress, spi, transformId, &saId);
+    netdutils::Status ret = fillXfrmId(sourceAddress, destinationAddress, spi, transformId, &saId);
     if (!isOk(ret)) {
         return ret;
     }
@@ -540,61 +525,45 @@
     return ret;
 }
 
-netdutils::Status XfrmController::fillXfrmId(int32_t direction, const std::string& localAddress,
-                                             const std::string& remoteAddress, int32_t spi,
+netdutils::Status XfrmController::fillXfrmId(const std::string& sourceAddress,
+                                             const std::string& destinationAddress, int32_t spi,
                                              int32_t transformId, XfrmId* xfrmId) {
     // Fill the straightforward fields first
     xfrmId->transformId = transformId;
-    xfrmId->direction = static_cast<XfrmDirection>(direction);
     xfrmId->spi = htonl(spi);
 
     // Use the addresses to determine the address family and do validation
-    xfrm_address_t localXfrmAddr{}, remoteXfrmAddr{};
-    StatusOr<int> addrFamilyLocal, addrFamilyRemote;
-    addrFamilyRemote = convertToXfrmAddr(remoteAddress, &remoteXfrmAddr);
-    addrFamilyLocal = convertToXfrmAddr(localAddress, &localXfrmAddr);
-    if (!isOk(addrFamilyRemote) || !isOk(addrFamilyLocal)) {
-        return netdutils::statusFromErrno(EINVAL,
-                                          "Invalid address " + localAddress + "/" + remoteAddress);
+    xfrm_address_t sourceXfrmAddr{}, destXfrmAddr{};
+    StatusOr<int> sourceFamily, destFamily;
+    sourceFamily = convertToXfrmAddr(sourceAddress, &sourceXfrmAddr);
+    destFamily = convertToXfrmAddr(destinationAddress, &destXfrmAddr);
+    if (!isOk(sourceFamily) || !isOk(destFamily)) {
+        return netdutils::statusFromErrno(EINVAL, "Invalid address " + sourceAddress + "/" +
+                                                      destinationAddress);
     }
 
-    if (addrFamilyRemote.value() == AF_UNSPEC ||
-        (addrFamilyLocal.value() != AF_UNSPEC &&
-         addrFamilyLocal.value() != addrFamilyRemote.value())) {
-        ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", addrFamilyLocal.value(),
-              addrFamilyRemote.value(), __LINE__);
+    if (destFamily.value() == AF_UNSPEC ||
+        (sourceFamily.value() != AF_UNSPEC && sourceFamily.value() != destFamily.value())) {
+        ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", sourceFamily.value(),
+              destFamily.value(), __LINE__);
         return netdutils::statusFromErrno(EINVAL, "Invalid or mismatched address families");
     }
 
-    xfrmId->addrFamily = addrFamilyRemote.value();
+    xfrmId->addrFamily = destFamily.value();
 
-    switch (static_cast<XfrmDirection>(direction)) {
-        case XfrmDirection::IN:
-            xfrmId->dstAddr = localXfrmAddr;
-            xfrmId->srcAddr = remoteXfrmAddr;
-            break;
-
-        case XfrmDirection::OUT:
-            xfrmId->dstAddr = remoteXfrmAddr;
-            xfrmId->srcAddr = localXfrmAddr;
-            break;
-
-        default:
-            ALOGD("Invalid XFRM direction, line=%d", __LINE__);
-            // Invalid direction for Transport mode transform: time to bail
-            return netdutils::statusFromErrno(EINVAL, "Invalid direction");
-    }
+    xfrmId->dstAddr = destXfrmAddr;
+    xfrmId->srcAddr = sourceXfrmAddr;
     return netdutils::status::ok;
 }
 
 netdutils::Status XfrmController::ipSecApplyTransportModeTransform(
     const android::base::unique_fd& socket, int32_t transformId, int32_t direction,
-    const std::string& localAddress, const std::string& remoteAddress, int32_t spi) {
+    const std::string& sourceAddress, const std::string& destinationAddress, int32_t spi) {
     ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
     ALOGD("transformId=%d", transformId);
     ALOGD("direction=%d", direction);
-    ALOGD("localAddress=%s", localAddress.c_str());
-    ALOGD("remoteAddress=%s", remoteAddress.c_str());
+    ALOGD("sourceAddress=%s", sourceAddress.c_str());
+    ALOGD("destinationAddress=%s", destinationAddress.c_str());
     ALOGD("spi=%0.8x", spi);
 
     StatusOr<sockaddr_storage> ret = getSyscallInstance().getsockname<sockaddr_storage>(Fd(socket));
@@ -606,7 +575,7 @@
 
     XfrmSaInfo saInfo{};
     netdutils::Status status =
-        fillXfrmId(direction, localAddress, remoteAddress, spi, transformId, &saInfo);
+        fillXfrmId(sourceAddress, destinationAddress, spi, transformId, &saInfo);
     if (!isOk(status)) {
         ALOGE("Couldn't build SA ID %s", __FUNCTION__);
         return status;
@@ -624,7 +593,7 @@
         xfrm_user_tmpl tmpl;
     } policy{};
 
-    fillTransportModeUserSpInfo(saInfo, &policy.info);
+    fillTransportModeUserSpInfo(saInfo, static_cast<XfrmDirection>(direction), &policy.info);
     fillUserTemplate(saInfo, &policy.tmpl);
 
     LOG_HEX("XfrmUserPolicy", reinterpret_cast<char*>(&policy), sizeof(policy));
@@ -900,7 +869,7 @@
     return ret;
 }
 
-int XfrmController::fillTransportModeUserSpInfo(const XfrmSaInfo& record,
+int XfrmController::fillTransportModeUserSpInfo(const XfrmSaInfo& record, XfrmDirection direction,
                                                 xfrm_userpolicy_info* usersp) {
     fillTransportModeSelector(record, &usersp->sel);
     fillXfrmLifetimeDefaults(&usersp->lft);
@@ -908,7 +877,7 @@
     /* if (index) index & 0x3 == dir -- must be true
      * xfrm_user.c:verify_newpolicy_info() */
     usersp->index = 0;
-    usersp->dir = static_cast<uint8_t>(record.direction);
+    usersp->dir = static_cast<uint8_t>(direction);
     usersp->action = XFRM_POLICY_ALLOW;
     usersp->flags = XFRM_POLICY_LOCALOK;
     usersp->share = XFRM_SHARE_UNIQUE;