Home | History | Annotate | Download | only in server
      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 <string>
     19 #include <vector>
     20 
     21 #include <ctype.h>
     22 #include <errno.h>
     23 #include <fcntl.h>
     24 #include <getopt.h>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 #include <inttypes.h>
     29 
     30 #include <arpa/inet.h>
     31 #include <netinet/in.h>
     32 
     33 #include <sys/socket.h>
     34 #include <sys/stat.h>
     35 #include <sys/types.h>
     36 #include <sys/wait.h>
     37 
     38 #include <linux/in.h>
     39 #include <linux/netlink.h>
     40 #include <linux/xfrm.h>
     41 
     42 #include "android-base/stringprintf.h"
     43 #include "android-base/strings.h"
     44 #include "android-base/unique_fd.h"
     45 #define LOG_TAG "XfrmController"
     46 #include "NetdConstants.h"
     47 #include "NetlinkCommands.h"
     48 #include "ResponseCode.h"
     49 #include "XfrmController.h"
     50 #include <cutils/log.h>
     51 #include <cutils/properties.h>
     52 #include <logwrap/logwrap.h>
     53 
     54 #define VDBG 1 // STOPSHIP if true
     55 
     56 namespace android {
     57 namespace net {
     58 
     59 namespace {
     60 
     61 constexpr uint32_t ALGO_MASK_AUTH_ALL = ~0;
     62 constexpr uint32_t ALGO_MASK_CRYPT_ALL = ~0;
     63 
     64 constexpr uint8_t REPLAY_WINDOW_SIZE = 4;
     65 
     66 constexpr uint32_t RAND_SPI_MIN = 1;
     67 constexpr uint32_t RAND_SPI_MAX = 0xFFFFFFFE;
     68 
     69 constexpr uint32_t INVALID_SPI = 0;
     70 
     71 #define XFRM_MSG_TRANS(x)                                                                          \
     72     case x:                                                                                        \
     73         return #x;
     74 
     75 const char* xfrmMsgTypeToString(uint16_t msg) {
     76     switch (msg) {
     77         XFRM_MSG_TRANS(XFRM_MSG_NEWSA)
     78         XFRM_MSG_TRANS(XFRM_MSG_DELSA)
     79         XFRM_MSG_TRANS(XFRM_MSG_GETSA)
     80         XFRM_MSG_TRANS(XFRM_MSG_NEWPOLICY)
     81         XFRM_MSG_TRANS(XFRM_MSG_DELPOLICY)
     82         XFRM_MSG_TRANS(XFRM_MSG_GETPOLICY)
     83         XFRM_MSG_TRANS(XFRM_MSG_ALLOCSPI)
     84         XFRM_MSG_TRANS(XFRM_MSG_ACQUIRE)
     85         XFRM_MSG_TRANS(XFRM_MSG_EXPIRE)
     86         XFRM_MSG_TRANS(XFRM_MSG_UPDPOLICY)
     87         XFRM_MSG_TRANS(XFRM_MSG_UPDSA)
     88         XFRM_MSG_TRANS(XFRM_MSG_POLEXPIRE)
     89         XFRM_MSG_TRANS(XFRM_MSG_FLUSHSA)
     90         XFRM_MSG_TRANS(XFRM_MSG_FLUSHPOLICY)
     91         XFRM_MSG_TRANS(XFRM_MSG_NEWAE)
     92         XFRM_MSG_TRANS(XFRM_MSG_GETAE)
     93         XFRM_MSG_TRANS(XFRM_MSG_REPORT)
     94         XFRM_MSG_TRANS(XFRM_MSG_MIGRATE)
     95         XFRM_MSG_TRANS(XFRM_MSG_NEWSADINFO)
     96         XFRM_MSG_TRANS(XFRM_MSG_GETSADINFO)
     97         XFRM_MSG_TRANS(XFRM_MSG_GETSPDINFO)
     98         XFRM_MSG_TRANS(XFRM_MSG_NEWSPDINFO)
     99         XFRM_MSG_TRANS(XFRM_MSG_MAPPING)
    100         default:
    101             return "XFRM_MSG UNKNOWN";
    102     }
    103 }
    104 
    105 // actually const but cannot be declared as such for reasons
    106 uint8_t kPadBytesArray[] = {0, 0, 0};
    107 void* kPadBytes = static_cast<void*>(kPadBytesArray);
    108 
    109 #if VDBG
    110 #define LOG_HEX(__desc16__, __buf__, __len__) \
    111     do{ logHex(__desc16__, __buf__, __len__); }while(0)
    112 #define LOG_IOV(__iov__, __iov_len__) \
    113     do{ logIov(__iov__, __iov_len__); }while(0)
    114 
    115 void logHex(const char* desc16, const char* buf, size_t len) {
    116     char* printBuf = new char[len * 2 + 1 + 26]; // len->ascii, +newline, +prefix strlen
    117     int offset = 0;
    118     if (desc16) {
    119         sprintf(printBuf, "{%-16s}", desc16);
    120         offset += 18; // prefix string length
    121     }
    122     sprintf(printBuf + offset, "[%4.4u]: ", (len > 9999) ? 9999 : (unsigned)len);
    123     offset += 8;
    124 
    125     for (uint32_t j = 0; j < (uint32_t)len; j++) {
    126         sprintf(&printBuf[j * 2 + offset], "%0.2x", buf[j]);
    127     }
    128     ALOGD("%s", printBuf);
    129     delete[] printBuf;
    130 }
    131 
    132 void logIov(const iovec* iov, size_t iovLen) {
    133     for (uint32_t i = 0; i < (uint32_t)iovLen; i++) {
    134         const iovec* row = &iov[i];
    135         logHex(0, reinterpret_cast<char*>(row->iov_base), row->iov_len);
    136     }
    137 }
    138 
    139 #else
    140 #define LOG_HEX(__desc16__, __buf__, __len__)
    141 #define LOG_IOV(__iov__, __iov_len__)
    142 #endif
    143 
    144 class XfrmSocketImpl : public XfrmSocket {
    145 private:
    146     static constexpr int NLMSG_DEFAULTSIZE = 8192;
    147 
    148     union NetlinkResponse {
    149         nlmsghdr hdr;
    150         struct _err_ {
    151             nlmsghdr hdr;
    152             nlmsgerr err;
    153         } err;
    154 
    155         struct _buf_ {
    156             nlmsghdr hdr;
    157             char buf[NLMSG_DEFAULTSIZE];
    158         } buf;
    159     };
    160 
    161 public:
    162     virtual bool open() {
    163         mSock = openNetlinkSocket(NETLINK_XFRM);
    164         if (mSock <= 0) {
    165             ALOGW("Could not get a new socket, line=%d", __LINE__);
    166             return false;
    167         }
    168 
    169         return true;
    170     }
    171 
    172     static int validateResponse(NetlinkResponse response, size_t len) {
    173         if (len < sizeof(nlmsghdr)) {
    174             ALOGW("Invalid response message received over netlink");
    175             return -EBADMSG;
    176         }
    177 
    178         switch (response.hdr.nlmsg_type) {
    179             case NLMSG_NOOP:
    180             case NLMSG_DONE:
    181                 return 0;
    182             case NLMSG_OVERRUN:
    183                 ALOGD("Netlink request overran kernel buffer");
    184                 return -EBADMSG;
    185             case NLMSG_ERROR:
    186                 if (len < sizeof(NetlinkResponse::_err_)) {
    187                     ALOGD("Netlink message received malformed error response");
    188                     return -EBADMSG;
    189                 }
    190                 return response.err.err.error; // Netlink errors are negative errno.
    191             case XFRM_MSG_NEWSA:
    192                 break;
    193         }
    194 
    195         if (response.hdr.nlmsg_type < XFRM_MSG_BASE /*== NLMSG_MIN_TYPE*/ ||
    196             response.hdr.nlmsg_type > XFRM_MSG_MAX) {
    197             ALOGD("Netlink message responded with an out-of-range message ID");
    198             return -EBADMSG;
    199         }
    200 
    201         // TODO Add more message validation here
    202         return 0;
    203     }
    204 
    205     virtual int sendMessage(uint16_t nlMsgType, uint16_t nlMsgFlags, uint16_t nlMsgSeqNum,
    206                             iovec* iov, int iovLen) const {
    207         nlmsghdr nlMsg = {
    208             .nlmsg_type = nlMsgType, .nlmsg_flags = nlMsgFlags, .nlmsg_seq = nlMsgSeqNum,
    209         };
    210 
    211         iov[0].iov_base = &nlMsg;
    212         iov[0].iov_len = NLMSG_HDRLEN;
    213         for (int i = 0; i < iovLen; ++i) {
    214             nlMsg.nlmsg_len += iov[i].iov_len;
    215         }
    216 
    217         ALOGD("Sending Netlink XFRM Message: %s", xfrmMsgTypeToString(nlMsgType));
    218         if (VDBG)
    219             LOG_IOV(iov, iovLen);
    220 
    221         int ret;
    222 
    223         if (writev(mSock, iov, iovLen) < 0) {
    224             ALOGE("netlink socket writev failed (%s)", strerror(errno));
    225             return -errno;
    226         }
    227 
    228         NetlinkResponse* response = new NetlinkResponse{};
    229 
    230         if ((ret = recv(mSock, response, sizeof(*response), 0)) < 0) {
    231             ALOGE("netlink response contains error (%s)", strerror(errno));
    232             delete response;
    233             return -errno;
    234         }
    235 
    236         LOG_HEX("netlink msg resp", reinterpret_cast<char*>(response), ret);
    237 
    238         ret = validateResponse(*response, ret);
    239         delete response;
    240         if (ret < 0)
    241             ALOGE("netlink response contains error (%s)", strerror(-ret));
    242         return ret;
    243     }
    244 };
    245 
    246 int convertToXfrmAddr(const std::string& strAddr, xfrm_address_t* xfrmAddr) {
    247     if (strAddr.length() == 0) {
    248         memset(xfrmAddr, 0, sizeof(*xfrmAddr));
    249         return AF_UNSPEC;
    250     }
    251 
    252     if (inet_pton(AF_INET6, strAddr.c_str(), reinterpret_cast<void*>(xfrmAddr))) {
    253         return AF_INET6;
    254     } else if (inet_pton(AF_INET, strAddr.c_str(), reinterpret_cast<void*>(xfrmAddr))) {
    255         return AF_INET;
    256     } else {
    257         return -EAFNOSUPPORT;
    258     }
    259 }
    260 
    261 void fillXfrmNlaHdr(nlattr* hdr, uint16_t type, uint16_t len) {
    262     hdr->nla_type = type;
    263     hdr->nla_len = len;
    264 }
    265 
    266 void fillXfrmCurLifetimeDefaults(xfrm_lifetime_cur* cur) {
    267     memset(reinterpret_cast<char*>(cur), 0, sizeof(*cur));
    268 }
    269 void fillXfrmLifetimeDefaults(xfrm_lifetime_cfg* cfg) {
    270     cfg->soft_byte_limit = XFRM_INF;
    271     cfg->hard_byte_limit = XFRM_INF;
    272     cfg->soft_packet_limit = XFRM_INF;
    273     cfg->hard_packet_limit = XFRM_INF;
    274 }
    275 
    276 /*
    277  * Allocate SPIs within an (inclusive) range of min-max.
    278  * returns 0 (INVALID_SPI) once the entire range has been parsed.
    279  */
    280 class RandomSpi {
    281 public:
    282     RandomSpi(int min, int max) : mMin(min) {
    283         time_t t;
    284         srand((unsigned int)time(&t));
    285         // TODO: more random random
    286         mNext = rand();
    287         mSize = max - min + 1;
    288         mCount = mSize;
    289     }
    290 
    291     uint32_t next() {
    292         if (!mCount)
    293             return 0;
    294         mCount--;
    295         return (mNext++ % mSize) + mMin;
    296     }
    297 
    298 private:
    299     uint32_t mNext;
    300     uint32_t mSize;
    301     uint32_t mMin;
    302     uint32_t mCount;
    303 };
    304 
    305 } // namespace
    306 
    307 //
    308 // Begin XfrmController Impl
    309 //
    310 //
    311 XfrmController::XfrmController(void) {}
    312 
    313 int XfrmController::ipSecAllocateSpi(int32_t transformId, int32_t direction,
    314                                      const std::string& localAddress,
    315                                      const std::string& remoteAddress, int32_t inSpi,
    316                                      int32_t* outSpi) {
    317 
    318     ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
    319     ALOGD("transformId=%d", transformId);
    320     ALOGD("direction=%d", direction);
    321     ALOGD("localAddress=%s", localAddress.c_str());
    322     ALOGD("remoteAddress=%s", remoteAddress.c_str());
    323     ALOGD("inSpi=%0.8x", inSpi);
    324 
    325     XfrmSaInfo saInfo{};
    326     int ret;
    327 
    328     if ((ret = fillXfrmSaId(direction, localAddress, remoteAddress, INVALID_SPI, &saInfo)) < 0) {
    329         return ret;
    330     }
    331 
    332     XfrmSocketImpl sock;
    333     if (!sock.open()) {
    334         ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
    335         return -1; // TODO: return right error; for whatever reason the sock
    336                    // failed to open
    337     }
    338 
    339     int minSpi = RAND_SPI_MIN, maxSpi = RAND_SPI_MAX;
    340 
    341     if (inSpi)
    342         minSpi = maxSpi = inSpi;
    343     ret = allocateSpi(saInfo, minSpi, maxSpi, reinterpret_cast<uint32_t*>(outSpi), sock);
    344     if (ret < 0) {
    345         ALOGD("Failed to Allocate an SPI, line=%d", __LINE__);
    346         *outSpi = INVALID_SPI;
    347     }
    348 
    349     return ret;
    350 }
    351 
    352 int XfrmController::ipSecAddSecurityAssociation(
    353     int32_t transformId, int32_t mode, int32_t direction, const std::string& localAddress,
    354     const std::string& remoteAddress, int64_t /* underlyingNetworkHandle */, int32_t spi,
    355     const std::string& authAlgo, const std::vector<uint8_t>& authKey, int32_t authTruncBits,
    356     const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits,
    357     int32_t encapType, int32_t encapLocalPort, int32_t encapRemotePort, int32_t* allocatedSpi) {
    358     android::RWLock::AutoWLock lock(mLock);
    359 
    360     ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
    361     ALOGD("transformId=%d", transformId);
    362     ALOGD("mode=%d", mode);
    363     ALOGD("direction=%d", direction);
    364     ALOGD("localAddress=%s", localAddress.c_str());
    365     ALOGD("remoteAddress=%s", remoteAddress.c_str());
    366     ALOGD("spi=%0.8x", spi);
    367     ALOGD("authAlgo=%s", authAlgo.c_str());
    368     ALOGD("authTruncBits=%d", authTruncBits);
    369     ALOGD("cryptAlgo=%s", cryptAlgo.c_str());
    370     ALOGD("cryptTruncBits=%d,", cryptTruncBits);
    371     ALOGD("encapType=%d", encapType);
    372     ALOGD("encapLocalPort=%d", encapLocalPort);
    373     ALOGD("encapRemotePort=%d", encapRemotePort);
    374 
    375     XfrmSaInfo saInfo{};
    376     int ret;
    377 
    378     if ((ret = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saInfo)) < 0) {
    379         return ret;
    380     }
    381 
    382     saInfo.transformId = transformId;
    383 
    384     // STOPSHIP : range check the key lengths to prevent puncturing and overflow
    385     saInfo.auth = XfrmAlgo{
    386         .name = authAlgo, .key = authKey, .truncLenBits = static_cast<uint16_t>(authTruncBits)};
    387 
    388     saInfo.crypt = XfrmAlgo{
    389         .name = cryptAlgo, .key = cryptKey, .truncLenBits = static_cast<uint16_t>(cryptTruncBits)};
    390 
    391     saInfo.direction = static_cast<XfrmDirection>(direction);
    392 
    393     switch (static_cast<XfrmMode>(mode)) {
    394         case XfrmMode::TRANSPORT:
    395         case XfrmMode::TUNNEL:
    396             saInfo.mode = static_cast<XfrmMode>(mode);
    397             break;
    398         default:
    399             return -EINVAL;
    400     }
    401 
    402     XfrmSocketImpl sock;
    403     if (!sock.open()) {
    404         ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
    405         return -1; // TODO: return right error; for whatever reason the sock
    406                    // failed to open
    407     }
    408 
    409     ret = createTransportModeSecurityAssociation(saInfo, sock);
    410     if (ret < 0) {
    411         ALOGD("Failed creating a Security Association, line=%d", __LINE__);
    412         return ret; // something went wrong creating the SA
    413     }
    414 
    415     *allocatedSpi = spi;
    416     return 0;
    417 }
    418 
    419 int XfrmController::ipSecDeleteSecurityAssociation(int32_t transformId, int32_t direction,
    420                                                    const std::string& localAddress,
    421                                                    const std::string& remoteAddress, int32_t spi) {
    422 
    423     ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
    424     ALOGD("transformId=%d", transformId);
    425     ALOGD("direction=%d", direction);
    426     ALOGD("localAddress=%s", localAddress.c_str());
    427     ALOGD("remoteAddress=%s", remoteAddress.c_str());
    428     ALOGD("spi=%0.8x", spi);
    429 
    430     XfrmSaId saId;
    431     int ret;
    432 
    433     if ((ret = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saId)) < 0) {
    434         return ret;
    435     }
    436 
    437     XfrmSocketImpl sock;
    438     if (!sock.open()) {
    439         ALOGD("Sock open failed for XFRM, line=%d", __LINE__);
    440         return -1; // TODO: return right error; for whatever reason the sock
    441                    // failed to open
    442     }
    443 
    444     ret = deleteSecurityAssociation(saId, sock);
    445     if (ret < 0) {
    446         ALOGD("Failed to delete Security Association, line=%d", __LINE__);
    447         return ret; // something went wrong deleting the SA
    448     }
    449 
    450     return ret;
    451 }
    452 
    453 int XfrmController::fillXfrmSaId(int32_t direction, const std::string& localAddress,
    454                                  const std::string& remoteAddress, int32_t spi, XfrmSaId* xfrmId) {
    455     xfrm_address_t localXfrmAddr{}, remoteXfrmAddr{};
    456 
    457     int addrFamilyLocal, addrFamilyRemote;
    458     addrFamilyRemote = convertToXfrmAddr(remoteAddress, &remoteXfrmAddr);
    459     addrFamilyLocal = convertToXfrmAddr(localAddress, &localXfrmAddr);
    460     if (addrFamilyRemote < 0 || addrFamilyLocal < 0) {
    461         return -EINVAL;
    462     }
    463 
    464     if (addrFamilyRemote == AF_UNSPEC ||
    465         (addrFamilyLocal != AF_UNSPEC && addrFamilyLocal != addrFamilyRemote)) {
    466         ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", addrFamilyLocal,
    467               addrFamilyRemote, __LINE__);
    468         return -EINVAL;
    469     }
    470 
    471     xfrmId->addrFamily = addrFamilyRemote;
    472 
    473     xfrmId->spi = htonl(spi);
    474 
    475     switch (static_cast<XfrmDirection>(direction)) {
    476         case XfrmDirection::IN:
    477             xfrmId->dstAddr = localXfrmAddr;
    478             xfrmId->srcAddr = remoteXfrmAddr;
    479             break;
    480 
    481         case XfrmDirection::OUT:
    482             xfrmId->dstAddr = remoteXfrmAddr;
    483             xfrmId->srcAddr = localXfrmAddr;
    484             break;
    485 
    486         default:
    487             ALOGD("Invalid XFRM direction, line=%d", __LINE__);
    488             // Invalid direction for Transport mode transform: time to bail
    489             return -EINVAL;
    490     }
    491     return 0;
    492 }
    493 
    494 int XfrmController::ipSecApplyTransportModeTransform(const android::base::unique_fd& socket,
    495                                                      int32_t transformId, int32_t direction,
    496                                                      const std::string& localAddress,
    497                                                      const std::string& remoteAddress,
    498                                                      int32_t spi) {
    499     ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
    500     ALOGD("transformId=%d", transformId);
    501     ALOGD("direction=%d", direction);
    502     ALOGD("localAddress=%s", localAddress.c_str());
    503     ALOGD("remoteAddress=%s", remoteAddress.c_str());
    504     ALOGD("spi=%0.8x", spi);
    505 
    506     struct sockaddr_storage saddr;
    507 
    508     socklen_t len = sizeof(saddr);
    509     int err;
    510     int userSocket = socket.get();
    511 
    512     if ((err = getsockname(userSocket, reinterpret_cast<struct sockaddr*>(&saddr), &len)) < 0) {
    513         ALOGE("Failed to get socket info in %s", __FUNCTION__);
    514         return -err;
    515     }
    516 
    517     XfrmSaInfo saInfo{};
    518     saInfo.transformId = transformId;
    519     saInfo.direction = static_cast<XfrmDirection>(direction);
    520     saInfo.spi = spi;
    521 
    522     if ((err = fillXfrmSaId(direction, localAddress, remoteAddress, spi, &saInfo)) < 0) {
    523         ALOGE("Couldn't build SA ID %s", __FUNCTION__);
    524         return -err;
    525     }
    526 
    527     if (saInfo.addrFamily != saddr.ss_family) {
    528         ALOGE("Transform address family(%d) differs from socket address "
    529                 "family(%d)!",
    530                 saInfo.addrFamily, saddr.ss_family);
    531         return -EINVAL;
    532     }
    533 
    534     struct {
    535         xfrm_userpolicy_info info;
    536         xfrm_user_tmpl tmpl;
    537     } policy{};
    538 
    539     fillTransportModeUserSpInfo(saInfo, &policy.info);
    540     fillUserTemplate(saInfo, &policy.tmpl);
    541 
    542     LOG_HEX("XfrmUserPolicy", reinterpret_cast<char*>(&policy), sizeof(policy));
    543 
    544     int sockOpt, sockLayer;
    545     switch (saInfo.addrFamily) {
    546         case AF_INET:
    547             sockOpt = IP_XFRM_POLICY;
    548             sockLayer = SOL_IP;
    549             break;
    550         case AF_INET6:
    551             sockOpt = IPV6_XFRM_POLICY;
    552             sockLayer = SOL_IPV6;
    553             break;
    554         default:
    555             return -EAFNOSUPPORT;
    556     }
    557 
    558     err = setsockopt(userSocket, sockLayer, sockOpt, &policy, sizeof(policy));
    559     if (err < 0) {
    560         err = errno;
    561         ALOGE("Error setting socket option for XFRM! (%s)", strerror(err));
    562     }
    563 
    564     return -err;
    565 }
    566 
    567 int XfrmController::ipSecRemoveTransportModeTransform(const android::base::unique_fd& socket) {
    568     (void)socket;
    569     return 0;
    570 }
    571 
    572 void XfrmController::fillTransportModeSelector(const XfrmSaInfo& record, xfrm_selector* selector) {
    573     selector->family = record.addrFamily;
    574     selector->proto = AF_UNSPEC;      // TODO: do we need to match the protocol? it's
    575                                       // possible via the socket
    576     selector->ifindex = record.netId; // TODO : still need to sort this out
    577 }
    578 
    579 int XfrmController::createTransportModeSecurityAssociation(const XfrmSaInfo& record,
    580                                                            const XfrmSocket& sock) {
    581     xfrm_usersa_info usersa{};
    582     nlattr_algo_crypt crypt{};
    583     nlattr_algo_auth auth{};
    584 
    585     enum { NLMSG_HDR, USERSA, USERSA_PAD, CRYPT, CRYPT_PAD, AUTH, AUTH_PAD, iovLen };
    586 
    587     iovec iov[] = {
    588         {NULL, 0},      // reserved for the eventual addition of a NLMSG_HDR
    589         {&usersa, 0},   // main usersa_info struct
    590         {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
    591         {&crypt, 0},    // adjust size if crypt algo is present
    592         {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
    593         {&auth, 0},     // adjust size if auth algo is present
    594         {kPadBytes, 0}, // up to NLATTR_ALIGNTO pad bytes
    595     };
    596 
    597     int len;
    598     len = iov[USERSA].iov_len = fillUserSaInfo(record, &usersa);
    599     iov[USERSA_PAD].iov_len = NLMSG_ALIGN(len) - len;
    600 
    601     len = iov[CRYPT].iov_len = fillNlAttrXfrmAlgoEnc(record.crypt, &crypt);
    602     iov[CRYPT_PAD].iov_len = NLA_ALIGN(len) - len;
    603 
    604     len = iov[AUTH].iov_len = fillNlAttrXfrmAlgoAuth(record.auth, &auth);
    605     iov[AUTH_PAD].iov_len = NLA_ALIGN(len) - len;
    606 
    607     return sock.sendMessage(XFRM_MSG_UPDSA, NETLINK_REQUEST_FLAGS, 0, iov, iovLen);
    608 }
    609 
    610 int XfrmController::fillNlAttrXfrmAlgoEnc(const XfrmAlgo& inAlgo, nlattr_algo_crypt* algo) {
    611     int len = NLA_HDRLEN + sizeof(xfrm_algo);
    612     strncpy(algo->crypt.alg_name, inAlgo.name.c_str(), sizeof(algo->crypt.alg_name));
    613     algo->crypt.alg_key_len = inAlgo.key.size() * 8;      // bits
    614     memcpy(algo->key, &inAlgo.key[0], inAlgo.key.size()); // FIXME :safety checks
    615     len += inAlgo.key.size();
    616     fillXfrmNlaHdr(&algo->hdr, XFRMA_ALG_CRYPT, len);
    617     return len;
    618 }
    619 
    620 int XfrmController::fillNlAttrXfrmAlgoAuth(const XfrmAlgo& inAlgo, nlattr_algo_auth* algo) {
    621     int len = NLA_HDRLEN + sizeof(xfrm_algo_auth);
    622     strncpy(algo->auth.alg_name, inAlgo.name.c_str(), sizeof(algo->auth.alg_name));
    623     algo->auth.alg_key_len = inAlgo.key.size() * 8; // bits
    624 
    625     // This is the extra field for ALG_AUTH_TRUNC
    626     algo->auth.alg_trunc_len = inAlgo.truncLenBits;
    627 
    628     memcpy(algo->key, &inAlgo.key[0], inAlgo.key.size()); // FIXME :safety checks
    629     len += inAlgo.key.size();
    630 
    631     fillXfrmNlaHdr(&algo->hdr, XFRMA_ALG_AUTH_TRUNC, len);
    632     return len;
    633 }
    634 
    635 int XfrmController::fillUserSaInfo(const XfrmSaInfo& record, xfrm_usersa_info* usersa) {
    636     fillTransportModeSelector(record, &usersa->sel);
    637 
    638     usersa->id.proto = IPPROTO_ESP;
    639     usersa->id.spi = record.spi;
    640     usersa->id.daddr = record.dstAddr;
    641 
    642     usersa->saddr = record.srcAddr;
    643 
    644     fillXfrmLifetimeDefaults(&usersa->lft);
    645     fillXfrmCurLifetimeDefaults(&usersa->curlft);
    646     memset(&usersa->stats, 0, sizeof(usersa->stats)); // leave stats zeroed out
    647     usersa->reqid = record.transformId;
    648     usersa->family = record.addrFamily;
    649     usersa->mode = static_cast<uint8_t>(record.mode);
    650     usersa->replay_window = REPLAY_WINDOW_SIZE;
    651     usersa->flags = 0; // TODO: should we actually set flags, XFRM_SA_XFLAG_DONT_ENCAP_DSCP?
    652     return sizeof(*usersa);
    653 }
    654 
    655 int XfrmController::fillUserSaId(const XfrmSaId& record, xfrm_usersa_id* said) {
    656     said->daddr = record.dstAddr;
    657     said->spi = record.spi;
    658     said->family = record.addrFamily;
    659     said->proto = IPPROTO_ESP;
    660 
    661     return sizeof(*said);
    662 }
    663 
    664 int XfrmController::deleteSecurityAssociation(const XfrmSaId& record, const XfrmSocket& sock) {
    665     xfrm_usersa_id said{};
    666 
    667     enum { NLMSG_HDR, USERSAID, USERSAID_PAD, iovLen };
    668 
    669     iovec iov[] = {
    670         {NULL, 0},      // reserved for the eventual addition of a NLMSG_HDR
    671         {&said, 0},     // main usersa_info struct
    672         {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
    673     };
    674 
    675     int len;
    676     len = iov[USERSAID].iov_len = fillUserSaId(record, &said);
    677     iov[USERSAID_PAD].iov_len = NLMSG_ALIGN(len) - len;
    678 
    679     return sock.sendMessage(XFRM_MSG_DELSA, NETLINK_REQUEST_FLAGS, 0, iov, iovLen);
    680 }
    681 
    682 int XfrmController::allocateSpi(const XfrmSaInfo& record, uint32_t minSpi, uint32_t maxSpi,
    683                                 uint32_t* outSpi, const XfrmSocket& sock) {
    684     xfrm_userspi_info spiInfo{};
    685 
    686     enum { NLMSG_HDR, USERSAID, USERSAID_PAD, iovLen };
    687 
    688     iovec iov[] = {
    689         {NULL, 0},      // reserved for the eventual addition of a NLMSG_HDR
    690         {&spiInfo, 0},  // main userspi_info struct
    691         {kPadBytes, 0}, // up to NLMSG_ALIGNTO pad bytes of padding
    692     };
    693 
    694     int len;
    695     if (fillUserSaInfo(record, &spiInfo.info) == 0) {
    696         ALOGE("Failed to fill transport SA Info");
    697     }
    698 
    699     len = iov[USERSAID].iov_len = sizeof(spiInfo);
    700     iov[USERSAID_PAD].iov_len = NLMSG_ALIGN(len) - len;
    701 
    702     RandomSpi spiGen = RandomSpi(minSpi, maxSpi);
    703     int spi, ret;
    704     while ((spi = spiGen.next()) != INVALID_SPI) {
    705         spiInfo.min = spi;
    706         spiInfo.max = spi;
    707         ret = sock.sendMessage(XFRM_MSG_ALLOCSPI, NETLINK_REQUEST_FLAGS, 0, iov, iovLen);
    708 
    709         /* If the SPI is in use, we'll get ENOENT */
    710         if (ret == -ENOENT)
    711             continue;
    712 
    713         if (ret == 0) {
    714             *outSpi = spi;
    715             ALOGD("Allocated an SPI: %d", *outSpi);
    716         } else {
    717             *outSpi = INVALID_SPI;
    718             ALOGE("SPI Allocation Failed with error %d", ret);
    719         }
    720 
    721         return ret;
    722     }
    723 
    724     // Should always be -ENOENT if we get here
    725     return ret;
    726 }
    727 
    728 int XfrmController::fillTransportModeUserSpInfo(const XfrmSaInfo& record,
    729                                                 xfrm_userpolicy_info* usersp) {
    730     fillTransportModeSelector(record, &usersp->sel);
    731     fillXfrmLifetimeDefaults(&usersp->lft);
    732     fillXfrmCurLifetimeDefaults(&usersp->curlft);
    733     /* if (index) index & 0x3 == dir -- must be true xfrm_user.c:verify_newpolicy_info() */
    734     usersp->index = 0;
    735     usersp->dir = static_cast<uint8_t>(record.direction);
    736     usersp->action = XFRM_POLICY_ALLOW;
    737     usersp->flags = XFRM_POLICY_LOCALOK;
    738     usersp->share = XFRM_SHARE_UNIQUE;
    739     return sizeof(*usersp);
    740 }
    741 
    742 int XfrmController::fillUserTemplate(const XfrmSaInfo& record, xfrm_user_tmpl* tmpl) {
    743     tmpl->id.daddr = record.dstAddr;
    744     tmpl->id.spi = record.spi;
    745     tmpl->id.proto = IPPROTO_ESP;
    746 
    747     tmpl->family = record.addrFamily;
    748     tmpl->saddr = record.srcAddr;
    749     tmpl->reqid = record.transformId;
    750     tmpl->mode = static_cast<uint8_t>(record.mode);
    751     tmpl->share = XFRM_SHARE_UNIQUE;
    752     tmpl->optional = 0; // if this is true, then a failed state lookup will be considered OK:
    753                         // http://lxr.free-electrons.com/source/net/xfrm/xfrm_policy.c#L1492
    754     tmpl->aalgos = ALGO_MASK_AUTH_ALL;  // TODO: if there's a bitmask somewhere of
    755                                         // algos, we should find it and apply it.
    756                                         // I can't find one.
    757     tmpl->ealgos = ALGO_MASK_CRYPT_ALL; // TODO: if there's a bitmask somewhere...
    758     return 0;
    759 }
    760 
    761 } // namespace net
    762 } // namespace android
    763