[BACK]Return to ip_esp.c CVS log [TXT][DIR] Up to [local] / sys / netinet

Annotation of sys/netinet/ip_esp.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ip_esp.c,v 1.100 2006/12/15 09:32:30 otto Exp $ */
                      2: /*
                      3:  * The authors of this code are John Ioannidis (ji@tla.org),
                      4:  * Angelos D. Keromytis (kermit@csd.uch.gr) and
                      5:  * Niels Provos (provos@physnet.uni-hamburg.de).
                      6:  *
                      7:  * The original version of this code was written by John Ioannidis
                      8:  * for BSD/OS in Athens, Greece, in November 1995.
                      9:  *
                     10:  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
                     11:  * by Angelos D. Keromytis.
                     12:  *
                     13:  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
                     14:  * and Niels Provos.
                     15:  *
                     16:  * Additional features in 1999 by Angelos D. Keromytis.
                     17:  *
                     18:  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
                     19:  * Angelos D. Keromytis and Niels Provos.
                     20:  * Copyright (c) 2001 Angelos D. Keromytis.
                     21:  *
                     22:  * Permission to use, copy, and modify this software with or without fee
                     23:  * is hereby granted, provided that this entire notice is included in
                     24:  * all copies of any software which is or includes a copy or
                     25:  * modification of this software.
                     26:  * You may use this code under the GNU public license if you so wish. Please
                     27:  * contribute changes back to the authors under this freer than GPL license
                     28:  * so that we may further the use of strong encryption without limitations to
                     29:  * all.
                     30:  *
                     31:  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
                     32:  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
                     33:  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
                     34:  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
                     35:  * PURPOSE.
                     36:  */
                     37:
                     38: #include "pfsync.h"
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/mbuf.h>
                     43: #include <sys/socket.h>
                     44:
                     45: #include <net/if.h>
                     46: #include <net/bpf.h>
                     47:
                     48: #include <dev/rndvar.h>
                     49:
                     50: #ifdef INET
                     51: #include <netinet/in.h>
                     52: #include <netinet/in_systm.h>
                     53: #include <netinet/ip.h>
                     54: #include <netinet/ip_var.h>
                     55: #endif /* INET */
                     56:
                     57: #ifdef INET6
                     58: #ifndef INET
                     59: #include <netinet/in.h>
                     60: #endif
                     61: #include <netinet/ip6.h>
                     62: #endif /* INET6 */
                     63:
                     64: #include <netinet/ip_ipsp.h>
                     65: #include <netinet/ip_esp.h>
                     66: #include <net/pfkeyv2.h>
                     67: #include <net/if_enc.h>
                     68:
                     69: #if NPFSYNC > 0
                     70: #include <net/pfvar.h>
                     71: #include <net/if_pfsync.h>
                     72: #endif /* NPFSYNC > 0 */
                     73:
                     74: #include <crypto/cryptodev.h>
                     75: #include <crypto/xform.h>
                     76:
                     77: #include "bpfilter.h"
                     78:
                     79: #ifdef ENCDEBUG
                     80: #define DPRINTF(x)     if (encdebug) printf x
                     81: #else
                     82: #define DPRINTF(x)
                     83: #endif
                     84:
                     85: struct espstat espstat;
                     86:
                     87: /*
                     88:  * esp_attach() is called from the transformation initialization code.
                     89:  */
                     90: int
                     91: esp_attach()
                     92: {
                     93:        return 0;
                     94: }
                     95:
                     96: /*
                     97:  * esp_init() is called when an SPI is being set up.
                     98:  */
                     99: int
                    100: esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
                    101: {
                    102:        struct enc_xform *txform = NULL;
                    103:        struct auth_hash *thash = NULL;
                    104:        struct cryptoini cria, crie;
                    105:
                    106:        if (!ii->ii_encalg && !ii->ii_authalg) {
                    107:                DPRINTF(("esp_init(): neither authentication nor encryption "
                    108:                    "algorithm given"));
                    109:                return EINVAL;
                    110:        }
                    111:
                    112:        if (ii->ii_encalg) {
                    113:                switch (ii->ii_encalg) {
                    114:                case SADB_EALG_NULL:
                    115:                        txform = &enc_xform_null;
                    116:                        break;
                    117:
                    118:                case SADB_EALG_DESCBC:
                    119:                        txform = &enc_xform_des;
                    120:                        break;
                    121:
                    122:                case SADB_EALG_3DESCBC:
                    123:                        txform = &enc_xform_3des;
                    124:                        break;
                    125:
                    126:                case SADB_X_EALG_AES:
                    127:                        txform = &enc_xform_rijndael128;
                    128:                        break;
                    129:
                    130:                case SADB_X_EALG_AESCTR:
                    131:                        txform = &enc_xform_aes_ctr;
                    132:                        break;
                    133:
                    134:                case SADB_X_EALG_BLF:
                    135:                        txform = &enc_xform_blf;
                    136:                        break;
                    137:
                    138:                case SADB_X_EALG_CAST:
                    139:                        txform = &enc_xform_cast5;
                    140:                        break;
                    141:
                    142:                case SADB_X_EALG_SKIPJACK:
                    143:                        txform = &enc_xform_skipjack;
                    144:                        break;
                    145:
                    146:                default:
                    147:                        DPRINTF(("esp_init(): unsupported encryption algorithm %d specified\n", ii->ii_encalg));
                    148:                        return EINVAL;
                    149:                }
                    150:
                    151:                if (ii->ii_enckeylen < txform->minkey) {
                    152:                        DPRINTF(("esp_init(): keylength %d too small (min length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->minkey, txform->name));
                    153:                        return EINVAL;
                    154:                }
                    155:
                    156:                if (ii->ii_enckeylen > txform->maxkey) {
                    157:                        DPRINTF(("esp_init(): keylength %d too large (max length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->maxkey, txform->name));
                    158:                        return EINVAL;
                    159:                }
                    160:
                    161:                tdbp->tdb_encalgxform = txform;
                    162:
                    163:                DPRINTF(("esp_init(): initialized TDB with enc algorithm %s\n",
                    164:                    txform->name));
                    165:
                    166:                tdbp->tdb_ivlen = txform->ivsize;
                    167:                if (tdbp->tdb_flags & TDBF_HALFIV)
                    168:                        tdbp->tdb_ivlen /= 2;
                    169:        }
                    170:
                    171:        if (ii->ii_authalg) {
                    172:                switch (ii->ii_authalg) {
                    173:                case SADB_AALG_MD5HMAC:
                    174:                        thash = &auth_hash_hmac_md5_96;
                    175:                        break;
                    176:
                    177:                case SADB_AALG_SHA1HMAC:
                    178:                        thash = &auth_hash_hmac_sha1_96;
                    179:                        break;
                    180:
                    181:                case SADB_X_AALG_RIPEMD160HMAC:
                    182:                        thash = &auth_hash_hmac_ripemd_160_96;
                    183:                        break;
                    184:
                    185:                case SADB_X_AALG_SHA2_256:
                    186:                        thash = &auth_hash_hmac_sha2_256_96;
                    187:                        break;
                    188:
                    189:                case SADB_X_AALG_SHA2_384:
                    190:                        thash = &auth_hash_hmac_sha2_384_96;
                    191:                        break;
                    192:
                    193:                case SADB_X_AALG_SHA2_512:
                    194:                        thash = &auth_hash_hmac_sha2_512_96;
                    195:                        break;
                    196:
                    197:                default:
                    198:                        DPRINTF(("esp_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg));
                    199:                        return EINVAL;
                    200:                }
                    201:
                    202:                if (ii->ii_authkeylen != thash->keysize) {
                    203:                        DPRINTF(("esp_init(): keylength %d doesn't match algorithm %s keysize (%d)\n", ii->ii_authkeylen, thash->name, thash->keysize));
                    204:                        return EINVAL;
                    205:                }
                    206:
                    207:                tdbp->tdb_authalgxform = thash;
                    208:
                    209:                DPRINTF(("esp_init(): initialized TDB with hash algorithm %s\n",
                    210:                    thash->name));
                    211:        }
                    212:
                    213:        tdbp->tdb_xform = xsp;
                    214:        tdbp->tdb_bitmap = 0;
                    215:        tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
                    216:
                    217:        /* Initialize crypto session */
                    218:        if (tdbp->tdb_encalgxform) {
                    219:                /* Save the raw keys */
                    220:                tdbp->tdb_emxkeylen = ii->ii_enckeylen;
                    221:                MALLOC(tdbp->tdb_emxkey, u_int8_t *, tdbp->tdb_emxkeylen,
                    222:                    M_XDATA, M_WAITOK);
                    223:                bcopy(ii->ii_enckey, tdbp->tdb_emxkey, tdbp->tdb_emxkeylen);
                    224:
                    225:                bzero(&crie, sizeof(crie));
                    226:
                    227:                crie.cri_alg = tdbp->tdb_encalgxform->type;
                    228:
                    229:                if (tdbp->tdb_authalgxform)
                    230:                        crie.cri_next = &cria;
                    231:                else
                    232:                        crie.cri_next = NULL;
                    233:
                    234:                crie.cri_klen = ii->ii_enckeylen * 8;
                    235:                crie.cri_key = ii->ii_enckey;
                    236:                /* XXX Rounds ? */
                    237:        }
                    238:
                    239:        if (tdbp->tdb_authalgxform) {
                    240:                /* Save the raw keys */
                    241:                tdbp->tdb_amxkeylen = ii->ii_authkeylen;
                    242:                MALLOC(tdbp->tdb_amxkey, u_int8_t *, tdbp->tdb_amxkeylen, M_XDATA,
                    243:                    M_WAITOK);
                    244:                bcopy(ii->ii_authkey, tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
                    245:
                    246:                bzero(&cria, sizeof(cria));
                    247:
                    248:                cria.cri_alg = tdbp->tdb_authalgxform->type;
                    249:                cria.cri_next = NULL;
                    250:                cria.cri_klen = ii->ii_authkeylen * 8;
                    251:                cria.cri_key = ii->ii_authkey;
                    252:        }
                    253:
                    254:        return crypto_newsession(&tdbp->tdb_cryptoid,
                    255:            (tdbp->tdb_encalgxform ? &crie : &cria), 0);
                    256: }
                    257:
                    258: /*
                    259:  * Paranoia.
                    260:  */
                    261: int
                    262: esp_zeroize(struct tdb *tdbp)
                    263: {
                    264:        int err;
                    265:
                    266:        if (tdbp->tdb_amxkey) {
                    267:                bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
                    268:                FREE(tdbp->tdb_amxkey, M_XDATA);
                    269:                tdbp->tdb_amxkey = NULL;
                    270:        }
                    271:
                    272:        if (tdbp->tdb_emxkey) {
                    273:                bzero(tdbp->tdb_emxkey, tdbp->tdb_emxkeylen);
                    274:                FREE(tdbp->tdb_emxkey, M_XDATA);
                    275:                tdbp->tdb_emxkey = NULL;
                    276:        }
                    277:
                    278:        err = crypto_freesession(tdbp->tdb_cryptoid);
                    279:        tdbp->tdb_cryptoid = 0;
                    280:        return err;
                    281: }
                    282:
                    283: #define MAXBUFSIZ (AH_ALEN_MAX > ESP_MAX_IVS ? AH_ALEN_MAX : ESP_MAX_IVS)
                    284:
                    285: /*
                    286:  * ESP input processing, called (eventually) through the protocol switch.
                    287:  */
                    288: int
                    289: esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
                    290: {
                    291:        struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
                    292:        struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
                    293:        struct tdb_crypto *tc;
                    294:        int plen, alen, hlen;
                    295:        struct m_tag *mtag;
                    296:        u_int32_t btsx;
                    297:
                    298:        struct cryptodesc *crde = NULL, *crda = NULL;
                    299:        struct cryptop *crp;
                    300:
                    301:        /* Determine the ESP header length */
                    302:        if (tdb->tdb_flags & TDBF_NOREPLAY)
                    303:                hlen = sizeof(u_int32_t) + tdb->tdb_ivlen; /* "old" ESP */
                    304:        else
                    305:                hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; /* "new" ESP */
                    306:
                    307:        if (esph)
                    308:                alen = AH_HMAC_HASHLEN;
                    309:        else
                    310:                alen = 0;
                    311:
                    312:        plen = m->m_pkthdr.len - (skip + hlen + alen);
                    313:        if (plen <= 0) {
                    314:                DPRINTF(("esp_input: invalid payload length\n"));
                    315:                espstat.esps_badilen++;
                    316:                m_freem(m);
                    317:                return EINVAL;
                    318:        }
                    319:
                    320:        if (espx) {
                    321:                /*
                    322:                 * Verify payload length is multiple of encryption algorithm
                    323:                 * block size.
                    324:                 */
                    325:                if (plen & (espx->blocksize - 1)) {
                    326:                        DPRINTF(("esp_input(): payload of %d octets not a multiple of %d octets, SA %s/%08x\n", plen, espx->blocksize, ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    327:                        espstat.esps_badilen++;
                    328:                        m_freem(m);
                    329:                        return EINVAL;
                    330:                }
                    331:        }
                    332:
                    333:        /* Replay window checking, if appropriate -- no value commitment. */
                    334:        if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
                    335:                m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
                    336:                    (unsigned char *) &btsx);
                    337:                btsx = ntohl(btsx);
                    338:
                    339:                switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl),
                    340:                    tdb->tdb_wnd, &(tdb->tdb_bitmap), 0)) {
                    341:                case 0: /* All's well */
                    342:                        break;
                    343:
                    344:                case 1:
                    345:                        m_freem(m);
                    346:                        DPRINTF(("esp_input(): replay counter wrapped for SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    347:                        espstat.esps_wrap++;
                    348:                        return EACCES;
                    349:
                    350:                case 2:
                    351:                case 3:
                    352:                        DPRINTF(("esp_input(): duplicate packet received in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    353:                        m_freem(m);
                    354:                        return EACCES;
                    355:
                    356:                default:
                    357:                        m_freem(m);
                    358:                        DPRINTF(("esp_input(): bogus value from checkreplaywindow32() in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    359:                        espstat.esps_replay++;
                    360:                        return EACCES;
                    361:                }
                    362:        }
                    363:
                    364:        /* Update the counters */
                    365:        tdb->tdb_cur_bytes += m->m_pkthdr.len - skip - hlen - alen;
                    366:        espstat.esps_ibytes += m->m_pkthdr.len - skip - hlen - alen;
                    367:
                    368:        /* Hard expiration */
                    369:        if ((tdb->tdb_flags & TDBF_BYTES) &&
                    370:            (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
                    371:                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                    372:                tdb_delete(tdb);
                    373:                m_freem(m);
                    374:                return ENXIO;
                    375:        }
                    376:
                    377:        /* Notify on soft expiration */
                    378:        if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
                    379:            (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
                    380:                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
                    381:                tdb->tdb_flags &= ~TDBF_SOFT_BYTES;       /* Turn off checking */
                    382:        }
                    383:
                    384: #ifdef notyet
                    385:        /* Find out if we've already done crypto */
                    386:        for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
                    387:             mtag != NULL;
                    388:             mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) {
                    389:                struct tdb_ident *tdbi;
                    390:
                    391:                tdbi = (struct tdb_ident *) (mtag + 1);
                    392:                if (tdbi->proto == tdb->tdb_sproto && tdbi->spi == tdb->tdb_spi &&
                    393:                    !bcmp(&tdbi->dst, &tdb->tdb_dst, sizeof(union sockaddr_union)))
                    394:                        break;
                    395:        }
                    396: #else
                    397:        mtag = NULL;
                    398: #endif
                    399:
                    400:        /* Get crypto descriptors */
                    401:        crp = crypto_getreq(esph && espx ? 2 : 1);
                    402:        if (crp == NULL) {
                    403:                m_freem(m);
                    404:                DPRINTF(("esp_input(): failed to acquire crypto descriptors\n"));
                    405:                espstat.esps_crypto++;
                    406:                return ENOBUFS;
                    407:        }
                    408:
                    409:        /* Get IPsec-specific opaque pointer */
                    410:        if (esph == NULL || mtag != NULL)
                    411:                MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
                    412:                    M_XDATA, M_NOWAIT);
                    413:        else
                    414:                MALLOC(tc, struct tdb_crypto *,
                    415:                    sizeof(struct tdb_crypto) + alen, M_XDATA, M_NOWAIT);
                    416:        if (tc == NULL) {
                    417:                m_freem(m);
                    418:                crypto_freereq(crp);
                    419:                DPRINTF(("esp_input(): failed to allocate tdb_crypto\n"));
                    420:                espstat.esps_crypto++;
                    421:                return ENOBUFS;
                    422:        }
                    423:
                    424:        bzero(tc, sizeof(struct tdb_crypto));
                    425:        tc->tc_ptr = (caddr_t) mtag;
                    426:
                    427:        if (esph) {
                    428:                crda = crp->crp_desc;
                    429:                crde = crda->crd_next;
                    430:
                    431:                /* Authentication descriptor */
                    432:                crda->crd_skip = skip;
                    433:                crda->crd_len = m->m_pkthdr.len - (skip + alen);
                    434:                crda->crd_inject = m->m_pkthdr.len - alen;
                    435:
                    436:                crda->crd_alg = esph->type;
                    437:                crda->crd_key = tdb->tdb_amxkey;
                    438:                crda->crd_klen = tdb->tdb_amxkeylen * 8;
                    439:
                    440:                /* Copy the authenticator */
                    441:                if (mtag == NULL)
                    442:                        m_copydata(m, m->m_pkthdr.len - alen, alen, (caddr_t) (tc + 1));
                    443:        } else
                    444:                crde = crp->crp_desc;
                    445:
                    446:        /* Crypto operation descriptor */
                    447:        crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
                    448:        crp->crp_flags = CRYPTO_F_IMBUF;
                    449:        crp->crp_buf = (caddr_t) m;
                    450:        crp->crp_callback = (int (*) (struct cryptop *)) esp_input_cb;
                    451:        crp->crp_sid = tdb->tdb_cryptoid;
                    452:        crp->crp_opaque = (caddr_t) tc;
                    453:
                    454:        /* These are passed as-is to the callback */
                    455:        tc->tc_skip = skip;
                    456:        tc->tc_protoff = protoff;
                    457:        tc->tc_spi = tdb->tdb_spi;
                    458:        tc->tc_proto = tdb->tdb_sproto;
                    459:        bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
                    460:
                    461:        /* Decryption descriptor */
                    462:        if (espx) {
                    463:                crde->crd_skip = skip + hlen;
                    464:                crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
                    465:                crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
                    466:
                    467:                if (tdb->tdb_flags & TDBF_HALFIV) {
                    468:                        /* Copy half-IV from packet */
                    469:                        m_copydata(m, crde->crd_inject, tdb->tdb_ivlen, crde->crd_iv);
                    470:
                    471:                        /* Cook IV */
                    472:                        for (btsx = 0; btsx < tdb->tdb_ivlen; btsx++)
                    473:                                crde->crd_iv[tdb->tdb_ivlen + btsx] = ~crde->crd_iv[btsx];
                    474:
                    475:                        crde->crd_flags |= CRD_F_IV_EXPLICIT;
                    476:                }
                    477:
                    478:                crde->crd_alg = espx->type;
                    479:                crde->crd_key = tdb->tdb_emxkey;
                    480:                crde->crd_klen = tdb->tdb_emxkeylen * 8;
                    481:                /* XXX Rounds ? */
                    482:        }
                    483:
                    484:        if (mtag == NULL)
                    485:                return crypto_dispatch(crp);
                    486:        else
                    487:                return esp_input_cb(crp);
                    488: }
                    489:
                    490: /*
                    491:  * ESP input callback, called directly by the crypto driver.
                    492:  */
                    493: int
                    494: esp_input_cb(void *op)
                    495: {
                    496:        u_int8_t lastthree[3], aalg[AH_HMAC_HASHLEN];
                    497:        int s, hlen, roff, skip, protoff, error;
                    498:        struct mbuf *m1, *mo, *m;
                    499:        struct auth_hash *esph;
                    500:        struct tdb_crypto *tc;
                    501:        struct cryptop *crp;
                    502:        struct m_tag *mtag;
                    503:        struct tdb *tdb;
                    504:        u_int32_t btsx;
                    505:        caddr_t ptr;
                    506:
                    507:        crp = (struct cryptop *) op;
                    508:
                    509:        tc = (struct tdb_crypto *) crp->crp_opaque;
                    510:        skip = tc->tc_skip;
                    511:        protoff = tc->tc_protoff;
                    512:        mtag = (struct m_tag *) tc->tc_ptr;
                    513:
                    514:        m = (struct mbuf *) crp->crp_buf;
                    515:        if (m == NULL) {
                    516:                /* Shouldn't happen... */
                    517:                FREE(tc, M_XDATA);
                    518:                crypto_freereq(crp);
                    519:                espstat.esps_crypto++;
                    520:                DPRINTF(("esp_input_cb(): bogus returned buffer from crypto\n"));
                    521:                return (EINVAL);
                    522:        }
                    523:
                    524:        s = spltdb();
                    525:
                    526:        tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
                    527:        if (tdb == NULL) {
                    528:                FREE(tc, M_XDATA);
                    529:                espstat.esps_notdb++;
                    530:                DPRINTF(("esp_input_cb(): TDB is expired while in crypto"));
                    531:                error = EPERM;
                    532:                goto baddone;
                    533:        }
                    534:
                    535:        esph = (struct auth_hash *) tdb->tdb_authalgxform;
                    536:
                    537:        /* Check for crypto errors */
                    538:        if (crp->crp_etype) {
                    539:                if (crp->crp_etype == EAGAIN) {
                    540:                        /* Reset the session ID */
                    541:                        if (tdb->tdb_cryptoid != 0)
                    542:                                tdb->tdb_cryptoid = crp->crp_sid;
                    543:                        splx(s);
                    544:                        return crypto_dispatch(crp);
                    545:                }
                    546:                FREE(tc, M_XDATA);
                    547:                espstat.esps_noxform++;
                    548:                DPRINTF(("esp_input_cb(): crypto error %d\n", crp->crp_etype));
                    549:                error = crp->crp_etype;
                    550:                goto baddone;
                    551:        }
                    552:
                    553:        /* If authentication was performed, check now. */
                    554:        if (esph != NULL) {
                    555:                /*
                    556:                 * If we have a tag, it means an IPsec-aware NIC did the verification
                    557:                 * for us.
                    558:                 */
                    559:                if (mtag == NULL) {
                    560:                        /* Copy the authenticator from the packet */
                    561:                        m_copydata(m, m->m_pkthdr.len - esph->authsize,
                    562:                            esph->authsize, aalg);
                    563:
                    564:                        ptr = (caddr_t) (tc + 1);
                    565:
                    566:                        /* Verify authenticator */
                    567:                        if (bcmp(ptr, aalg, esph->authsize)) {
                    568:                                FREE(tc, M_XDATA);
                    569:                                DPRINTF(("esp_input_cb(): authentication failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    570:                                espstat.esps_badauth++;
                    571:                                error = EACCES;
                    572:                                goto baddone;
                    573:                        }
                    574:                }
                    575:
                    576:                /* Remove trailing authenticator */
                    577:                m_adj(m, -(esph->authsize));
                    578:        }
                    579:        FREE(tc, M_XDATA);
                    580:
                    581:        /* Replay window checking, if appropriate */
                    582:        if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
                    583:                m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
                    584:                    (unsigned char *) &btsx);
                    585:                btsx = ntohl(btsx);
                    586:
                    587:                switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl),
                    588:                    tdb->tdb_wnd, &(tdb->tdb_bitmap), 1)) {
                    589:                case 0: /* All's well */
                    590: #if NPFSYNC > 0
                    591:                        pfsync_update_tdb(tdb,0);
                    592: #endif
                    593:                        break;
                    594:
                    595:                case 1:
                    596:                        DPRINTF(("esp_input_cb(): replay counter wrapped for SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    597:                        espstat.esps_wrap++;
                    598:                        error = EACCES;
                    599:                        goto baddone;
                    600:
                    601:                case 2:
                    602:                case 3:
                    603:                        DPRINTF(("esp_input_cb(): duplicate packet received in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    604:                        error = EACCES;
                    605:                        goto baddone;
                    606:
                    607:                default:
                    608:                        DPRINTF(("esp_input_cb(): bogus value from checkreplaywindow32() in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    609:                        espstat.esps_replay++;
                    610:                        error = EACCES;
                    611:                        goto baddone;
                    612:                }
                    613:        }
                    614:
                    615:        /* Release the crypto descriptors */
                    616:        crypto_freereq(crp);
                    617:
                    618:        /* Determine the ESP header length */
                    619:        if (tdb->tdb_flags & TDBF_NOREPLAY)
                    620:                hlen = sizeof(u_int32_t) + tdb->tdb_ivlen; /* "old" ESP */
                    621:        else
                    622:                hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; /* "new" ESP */
                    623:
                    624:        /* Find beginning of ESP header */
                    625:        m1 = m_getptr(m, skip, &roff);
                    626:        if (m1 == NULL) {
                    627:                espstat.esps_hdrops++;
                    628:                splx(s);
                    629:                DPRINTF(("esp_input_cb(): bad mbuf chain, SA %s/%08x\n",
                    630:                    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    631:                m_freem(m);
                    632:                return EINVAL;
                    633:        }
                    634:
                    635:        /* Remove the ESP header and IV from the mbuf. */
                    636:        if (roff == 0) {
                    637:                /* The ESP header was conveniently at the beginning of the mbuf */
                    638:                m_adj(m1, hlen);
                    639:                if (!(m1->m_flags & M_PKTHDR))
                    640:                        m->m_pkthdr.len -= hlen;
                    641:        } else if (roff + hlen >= m1->m_len) {
                    642:                /*
                    643:                 * Part or all of the ESP header is at the end of this mbuf, so
                    644:                 * first let's remove the remainder of the ESP header from the
                    645:                 * beginning of the remainder of the mbuf chain, if any.
                    646:                 */
                    647:                if (roff + hlen > m1->m_len) {
                    648:                        /* Adjust the next mbuf by the remainder */
                    649:                        m_adj(m1->m_next, roff + hlen - m1->m_len);
                    650:
                    651:                        /* The second mbuf is guaranteed not to have a pkthdr... */
                    652:                        m->m_pkthdr.len -= (roff + hlen - m1->m_len);
                    653:                }
                    654:
                    655:                /* Now, let's unlink the mbuf chain for a second...*/
                    656:                mo = m1->m_next;
                    657:                m1->m_next = NULL;
                    658:
                    659:                /* ...and trim the end of the first part of the chain...sick */
                    660:                m_adj(m1, -(m1->m_len - roff));
                    661:                if (!(m1->m_flags & M_PKTHDR))
                    662:                        m->m_pkthdr.len -= (m1->m_len - roff);
                    663:
                    664:                /* Finally, let's relink */
                    665:                m1->m_next = mo;
                    666:        } else {
                    667:                /*
                    668:                 * The ESP header lies in the "middle" of the mbuf...do an
                    669:                 * overlapping copy of the remainder of the mbuf over the ESP
                    670:                 * header.
                    671:                 */
                    672:                bcopy(mtod(m1, u_char *) + roff + hlen,
                    673:                    mtod(m1, u_char *) + roff, m1->m_len - (roff + hlen));
                    674:                m1->m_len -= hlen;
                    675:                m->m_pkthdr.len -= hlen;
                    676:        }
                    677:
                    678:        /* Save the last three bytes of decrypted data */
                    679:        m_copydata(m, m->m_pkthdr.len - 3, 3, lastthree);
                    680:
                    681:        /* Verify pad length */
                    682:        if (lastthree[1] + 2 > m->m_pkthdr.len - skip) {
                    683:                espstat.esps_badilen++;
                    684:                splx(s);
                    685:                DPRINTF(("esp_input_cb(): invalid padding length %d for packet in SA %s/%08x\n", lastthree[1], ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    686:                m_freem(m);
                    687:                return EINVAL;
                    688:        }
                    689:
                    690:        /* Verify correct decryption by checking the last padding bytes */
                    691:        if (!(tdb->tdb_flags & TDBF_RANDOMPADDING)) {
                    692:                if ((lastthree[1] != lastthree[0]) && (lastthree[1] != 0)) {
                    693:                        espstat.esps_badenc++;
                    694:                        splx(s);
                    695:                        DPRINTF(("esp_input(): decryption failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    696:                        m_freem(m);
                    697:                        return EINVAL;
                    698:                }
                    699:        }
                    700:
                    701:        /* Trim the mbuf chain to remove the trailing authenticator and padding */
                    702:        m_adj(m, -(lastthree[1] + 2));
                    703:
                    704:        /* Restore the Next Protocol field */
                    705:        m_copyback(m, protoff, sizeof(u_int8_t), lastthree + 2);
                    706:
                    707:        /* Back to generic IPsec input processing */
                    708:        error = ipsec_common_input_cb(m, tdb, skip, protoff, mtag);
                    709:        splx(s);
                    710:        return (error);
                    711:
                    712:  baddone:
                    713:        splx(s);
                    714:
                    715:        if (m != NULL)
                    716:                m_freem(m);
                    717:
                    718:        crypto_freereq(crp);
                    719:
                    720:        return (error);
                    721: }
                    722:
                    723: /*
                    724:  * ESP output routine, called by ipsp_process_packet().
                    725:  */
                    726: int
                    727: esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
                    728:     int protoff)
                    729: {
                    730:        struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
                    731:        struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
                    732:        int ilen, hlen, rlen, padding, blks, alen;
                    733:        struct mbuf *mi, *mo = (struct mbuf *) NULL;
                    734:        struct tdb_crypto *tc;
                    735:        unsigned char *pad;
                    736:        u_int8_t prot;
                    737:
                    738:        struct cryptodesc *crde = NULL, *crda = NULL;
                    739:        struct cryptop *crp;
                    740: #if NBPFILTER > 0
                    741:        struct ifnet *ifn = &(encif[0].sc_if);
                    742:
                    743:        ifn->if_opackets++;
                    744:        ifn->if_obytes += m->m_pkthdr.len;
                    745:
                    746:        if (ifn->if_bpf) {
                    747:                struct enchdr hdr;
                    748:
                    749:                bzero (&hdr, sizeof(hdr));
                    750:
                    751:                hdr.af = tdb->tdb_dst.sa.sa_family;
                    752:                hdr.spi = tdb->tdb_spi;
                    753:                if (espx)
                    754:                        hdr.flags |= M_CONF;
                    755:                if (esph)
                    756:                        hdr.flags |= M_AUTH;
                    757:
                    758:                bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, ENC_HDRLEN, m,
                    759:                    BPF_DIRECTION_OUT);
                    760:        }
                    761: #endif
                    762:
                    763:        if (tdb->tdb_flags & TDBF_NOREPLAY)
                    764:                hlen = sizeof(u_int32_t) + tdb->tdb_ivlen;
                    765:        else
                    766:                hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen;
                    767:
                    768:        rlen = m->m_pkthdr.len - skip; /* Raw payload length. */
                    769:        if (espx)
                    770:                blks = espx->blocksize;
                    771:        else
                    772:                blks = 4; /* If no encryption, we have to be 4-byte aligned. */
                    773:
                    774:        padding = ((blks - ((rlen + 2) % blks)) % blks) + 2;
                    775:
                    776:        if (esph)
                    777:                alen = AH_HMAC_HASHLEN;
                    778:        else
                    779:                alen = 0;
                    780:
                    781:        espstat.esps_output++;
                    782:
                    783:        switch (tdb->tdb_dst.sa.sa_family) {
                    784: #ifdef INET
                    785:        case AF_INET:
                    786:                /* Check for IP maximum packet size violations. */
                    787:                if (skip + hlen + rlen + padding + alen > IP_MAXPACKET) {
                    788:                        DPRINTF(("esp_output(): packet in SA %s/%08x got "
                    789:                            "too big\n", ipsp_address(tdb->tdb_dst),
                    790:                            ntohl(tdb->tdb_spi)));
                    791:                        m_freem(m);
                    792:                        espstat.esps_toobig++;
                    793:                        return EMSGSIZE;
                    794:                }
                    795:                break;
                    796: #endif /* INET */
                    797:
                    798: #ifdef INET6
                    799:        case AF_INET6:
                    800:                /* Check for IPv6 maximum packet size violations. */
                    801:                if (skip + hlen + rlen + padding + alen > IPV6_MAXPACKET) {
                    802:                        DPRINTF(("esp_output(): packet in SA %s/%08x got too "
                    803:                            "big\n", ipsp_address(tdb->tdb_dst),
                    804:                            ntohl(tdb->tdb_spi)));
                    805:                        m_freem(m);
                    806:                        espstat.esps_toobig++;
                    807:                        return EMSGSIZE;
                    808:                }
                    809:                break;
                    810: #endif /* INET6 */
                    811:
                    812:        default:
                    813:                DPRINTF(("esp_output(): unknown/unsupported protocol "
                    814:                    "family %d, SA %s/%08x\n", tdb->tdb_dst.sa.sa_family
                    815:                    , ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    816:                m_freem(m);
                    817:                espstat.esps_nopf++;
                    818:                return EPFNOSUPPORT;
                    819:        }
                    820:
                    821:        /* Update the counters. */
                    822:        tdb->tdb_cur_bytes += m->m_pkthdr.len - skip;
                    823:        espstat.esps_obytes += m->m_pkthdr.len - skip;
                    824:
                    825:        /* Hard byte expiration. */
                    826:        if (tdb->tdb_flags & TDBF_BYTES &&
                    827:            tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
                    828:                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
                    829:                tdb_delete(tdb);
                    830:                m_freem(m);
                    831:                return EINVAL;
                    832:        }
                    833:
                    834:        /* Soft byte expiration. */
                    835:        if (tdb->tdb_flags & TDBF_SOFT_BYTES &&
                    836:            tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) {
                    837:                pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
                    838:                tdb->tdb_flags &= ~TDBF_SOFT_BYTES;    /* Turn off checking. */
                    839:        }
                    840:
                    841:        /*
                    842:         * Loop through mbuf chain; if we find a readonly mbuf,
                    843:         * replace the rest of the chain.
                    844:         */
                    845:        mo = NULL;
                    846:        mi = m;
                    847:        while (mi != NULL && !M_READONLY(mi)) {
                    848:                mo = mi;
                    849:                mi = mi->m_next;
                    850:        }
                    851:
                    852:        if (mi != NULL) {
                    853:                /* Replace the rest of the mbuf chain. */
                    854:                struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
                    855:
                    856:                if (n == NULL) {
                    857:                        DPRINTF(("esp_output(): bad mbuf chain, SA %s/%08x\n",
                    858:                            ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    859:                        espstat.esps_hdrops++;
                    860:                        m_freem(m);
                    861:                        return ENOBUFS;
                    862:                }
                    863:
                    864:                if (mo != NULL)
                    865:                        mo->m_next = n;
                    866:                else
                    867:                        m = n;
                    868:
                    869:                m_freem(mi);
                    870:        }
                    871:
                    872:        /* Inject ESP header. */
                    873:        mo = m_inject(m, skip, hlen, M_DONTWAIT);
                    874:        if (mo == NULL) {
                    875:                DPRINTF(("esp_output(): failed to inject ESP header for "
                    876:                    "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
                    877:                    ntohl(tdb->tdb_spi)));
                    878:                m_freem(m);
                    879:                espstat.esps_hdrops++;
                    880:                return ENOBUFS;
                    881:        }
                    882:
                    883:        /* Initialize ESP header. */
                    884:        bcopy((caddr_t) &tdb->tdb_spi, mtod(mo, caddr_t), sizeof(u_int32_t));
                    885:        if (!(tdb->tdb_flags & TDBF_NOREPLAY)) {
                    886:                u_int32_t replay = htonl(tdb->tdb_rpl++);
                    887:                bcopy((caddr_t) &replay, mtod(mo, caddr_t) + sizeof(u_int32_t),
                    888:                    sizeof(u_int32_t));
                    889: #if NPFSYNC > 0
                    890:                pfsync_update_tdb(tdb,1);
                    891: #endif
                    892:        }
                    893:
                    894:        /*
                    895:         * Add padding -- better to do it ourselves than use the crypto engine,
                    896:         * although if/when we support compression, we'd have to do that.
                    897:         */
                    898:        pad = (u_char *) m_pad(m, padding + alen);
                    899:        if (pad == NULL) {
                    900:                DPRINTF(("esp_output(): m_pad() failed for SA %s/%08x\n",
                    901:                    ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
                    902:                return ENOBUFS;
                    903:        }
                    904:
                    905:        /* Self-describing or random padding ? */
                    906:        if (!(tdb->tdb_flags & TDBF_RANDOMPADDING))
                    907:                for (ilen = 0; ilen < padding - 2; ilen++)
                    908:                        pad[ilen] = ilen + 1;
                    909:        else
                    910:                arc4random_bytes((void *) pad, padding - 2);
                    911:
                    912:        /* Fix padding length and Next Protocol in padding itself. */
                    913:        pad[padding - 2] = padding - 2;
                    914:        m_copydata(m, protoff, sizeof(u_int8_t), pad + padding - 1);
                    915:
                    916:        /* Fix Next Protocol in IPv4/IPv6 header. */
                    917:        prot = IPPROTO_ESP;
                    918:        m_copyback(m, protoff, sizeof(u_int8_t), &prot);
                    919:
                    920:        /* Get crypto descriptors. */
                    921:        crp = crypto_getreq(esph && espx ? 2 : 1);
                    922:        if (crp == NULL) {
                    923:                m_freem(m);
                    924:                DPRINTF(("esp_output(): failed to acquire crypto "
                    925:                    "descriptors\n"));
                    926:                espstat.esps_crypto++;
                    927:                return ENOBUFS;
                    928:        }
                    929:
                    930:        if (espx) {
                    931:                crde = crp->crp_desc;
                    932:                crda = crde->crd_next;
                    933:
                    934:                /* Encryption descriptor. */
                    935:                crde->crd_skip = skip + hlen;
                    936:                crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
                    937:                crde->crd_flags = CRD_F_ENCRYPT;
                    938:                crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
                    939:
                    940:                if (tdb->tdb_flags & TDBF_HALFIV) {
                    941:                        /* Copy half-iv in the packet. */
                    942:                        m_copyback(m, crde->crd_inject, tdb->tdb_ivlen,
                    943:                            tdb->tdb_iv);
                    944:
                    945:                        /* Cook half-iv. */
                    946:                        bcopy(tdb->tdb_iv, crde->crd_iv, tdb->tdb_ivlen);
                    947:                        for (ilen = 0; ilen < tdb->tdb_ivlen; ilen++)
                    948:                                crde->crd_iv[tdb->tdb_ivlen + ilen] =
                    949:                                    ~crde->crd_iv[ilen];
                    950:
                    951:                        crde->crd_flags |=
                    952:                            CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT;
                    953:                }
                    954:
                    955:                /* Encryption operation. */
                    956:                crde->crd_alg = espx->type;
                    957:                crde->crd_key = tdb->tdb_emxkey;
                    958:                crde->crd_klen = tdb->tdb_emxkeylen * 8;
                    959:                /* XXX Rounds ? */
                    960:        } else
                    961:                crda = crp->crp_desc;
                    962:
                    963:        /* IPsec-specific opaque crypto info. */
                    964:        MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
                    965:            M_XDATA, M_NOWAIT);
                    966:        if (tc == NULL) {
                    967:                m_freem(m);
                    968:                crypto_freereq(crp);
                    969:                DPRINTF(("esp_output(): failed to allocate tdb_crypto\n"));
                    970:                espstat.esps_crypto++;
                    971:                return ENOBUFS;
                    972:        }
                    973:
                    974:        bzero(tc, sizeof(struct tdb_crypto));
                    975:        tc->tc_spi = tdb->tdb_spi;
                    976:        tc->tc_proto = tdb->tdb_sproto;
                    977:        bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
                    978:
                    979:        /* Crypto operation descriptor. */
                    980:        crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
                    981:        crp->crp_flags = CRYPTO_F_IMBUF;
                    982:        crp->crp_buf = (caddr_t) m;
                    983:        crp->crp_callback = (int (*) (struct cryptop *)) esp_output_cb;
                    984:        crp->crp_opaque = (caddr_t) tc;
                    985:        crp->crp_sid = tdb->tdb_cryptoid;
                    986:
                    987:        if (esph) {
                    988:                /* Authentication descriptor. */
                    989:                crda->crd_skip = skip;
                    990:                crda->crd_len = m->m_pkthdr.len - (skip + alen);
                    991:                crda->crd_inject = m->m_pkthdr.len - alen;
                    992:
                    993:                /* Authentication operation. */
                    994:                crda->crd_alg = esph->type;
                    995:                crda->crd_key = tdb->tdb_amxkey;
                    996:                crda->crd_klen = tdb->tdb_amxkeylen * 8;
                    997:        }
                    998:
                    999:        if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
                   1000:                return crypto_dispatch(crp);
                   1001:        else
                   1002:                return esp_output_cb(crp);
                   1003: }
                   1004:
                   1005: /*
                   1006:  * ESP output callback, called directly by the crypto driver.
                   1007:  */
                   1008: int
                   1009: esp_output_cb(void *op)
                   1010: {
                   1011:        struct cryptop *crp = (struct cryptop *) op;
                   1012:        struct tdb_crypto *tc;
                   1013:        struct tdb *tdb;
                   1014:        struct mbuf *m;
                   1015:        int error, s;
                   1016:
                   1017:        tc = (struct tdb_crypto *) crp->crp_opaque;
                   1018:
                   1019:        m = (struct mbuf *) crp->crp_buf;
                   1020:        if (m == NULL) {
                   1021:                /* Shouldn't happen... */
                   1022:                FREE(tc, M_XDATA);
                   1023:                crypto_freereq(crp);
                   1024:                espstat.esps_crypto++;
                   1025:                DPRINTF(("esp_output_cb(): bogus returned buffer from "
                   1026:                    "crypto\n"));
                   1027:                return (EINVAL);
                   1028:        }
                   1029:
                   1030:
                   1031:        s = spltdb();
                   1032:
                   1033:        tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
                   1034:        if (tdb == NULL) {
                   1035:                FREE(tc, M_XDATA);
                   1036:                espstat.esps_notdb++;
                   1037:                DPRINTF(("esp_output_cb(): TDB is expired while in crypto\n"));
                   1038:                error = EPERM;
                   1039:                goto baddone;
                   1040:        }
                   1041:
                   1042:        /* Check for crypto errors. */
                   1043:        if (crp->crp_etype) {
                   1044:                if (crp->crp_etype == EAGAIN) {
                   1045:                        /* Reset the session ID */
                   1046:                        if (tdb->tdb_cryptoid != 0)
                   1047:                                tdb->tdb_cryptoid = crp->crp_sid;
                   1048:                        splx(s);
                   1049:                        return crypto_dispatch(crp);
                   1050:                }
                   1051:                FREE(tc, M_XDATA);
                   1052:                espstat.esps_noxform++;
                   1053:                DPRINTF(("esp_output_cb(): crypto error %d\n",
                   1054:                    crp->crp_etype));
                   1055:                error = crp->crp_etype;
                   1056:                goto baddone;
                   1057:        }
                   1058:        FREE(tc, M_XDATA);
                   1059:
                   1060:        /* Release crypto descriptors. */
                   1061:        crypto_freereq(crp);
                   1062:
                   1063:        /*
                   1064:         * If we're doing half-iv, keep a copy of the last few bytes of the
                   1065:         * encrypted part, for use as the next IV. Note that HALF-IV is only
                   1066:         * supposed to be used without authentication (the old ESP specs).
                   1067:         */
                   1068:        if (tdb->tdb_flags & TDBF_HALFIV)
                   1069:                m_copydata(m, m->m_pkthdr.len - tdb->tdb_ivlen, tdb->tdb_ivlen,
                   1070:                    tdb->tdb_iv);
                   1071:
                   1072:        /* Call the IPsec input callback. */
                   1073:        error = ipsp_process_done(m, tdb);
                   1074:        splx(s);
                   1075:        return error;
                   1076:
                   1077:  baddone:
                   1078:        splx(s);
                   1079:
                   1080:        if (m != NULL)
                   1081:                m_freem(m);
                   1082:
                   1083:        crypto_freereq(crp);
                   1084:
                   1085:        return error;
                   1086: }
                   1087:
                   1088: /*
                   1089:  * return 0 on success
                   1090:  * return 1 for counter == 0
                   1091:  * return 2 for very old packet
                   1092:  * return 3 for packet within current window but already received
                   1093:  */
                   1094: int
                   1095: checkreplaywindow32(u_int32_t seq, u_int32_t initial, u_int32_t *lastseq,
                   1096:     u_int32_t window, u_int32_t *bitmap, int commit)
                   1097: {
                   1098:        u_int32_t diff, llseq, lbitmap;
                   1099:
                   1100:        /* Just do the checking, without "committing" any changes. */
                   1101:        if (commit == 0) {
                   1102:                llseq = *lastseq;
                   1103:                lbitmap = *bitmap;
                   1104:
                   1105:                lastseq = &llseq;
                   1106:                bitmap = &lbitmap;
                   1107:        }
                   1108:
                   1109:        seq -= initial;
                   1110:
                   1111:        if (seq == 0)
                   1112:                return 1;
                   1113:
                   1114:        if (seq > *lastseq - initial) {
                   1115:                diff = seq - (*lastseq - initial);
                   1116:                if (diff < window)
                   1117:                        *bitmap = ((*bitmap) << diff) | 1;
                   1118:                else
                   1119:                        *bitmap = 1;
                   1120:                *lastseq = seq + initial;
                   1121:                return 0;
                   1122:        }
                   1123:
                   1124:        diff = *lastseq - initial - seq;
                   1125:        if (diff >= window) {
                   1126:                espstat.esps_wrap++;
                   1127:                return 2;
                   1128:        }
                   1129:
                   1130:        if ((*bitmap) & (((u_int32_t) 1) << diff)) {
                   1131:                espstat.esps_replay++;
                   1132:                return 3;
                   1133:        }
                   1134:
                   1135:        *bitmap |= (((u_int32_t) 1) << diff);
                   1136:        return 0;
                   1137: }
                   1138:
                   1139: /*
                   1140:  * m_pad(m, n) pads <m> with <n> bytes at the end. The packet header
                   1141:  * length is updated, and a pointer to the first byte of the padding
                   1142:  * (which is guaranteed to be all in one mbuf) is returned.
                   1143:  */
                   1144:
                   1145: caddr_t
                   1146: m_pad(struct mbuf *m, int n)
                   1147: {
                   1148:        struct mbuf *m0, *m1;
                   1149:        int len, pad;
                   1150:        caddr_t retval;
                   1151:
                   1152:        if (n <= 0) {  /* No stupid arguments. */
                   1153:                DPRINTF(("m_pad(): pad length invalid (%d)\n", n));
                   1154:                m_freem(m);
                   1155:                return NULL;
                   1156:        }
                   1157:
                   1158:        len = m->m_pkthdr.len;
                   1159:        pad = n;
                   1160:        m0 = m;
                   1161:
                   1162:        while (m0->m_len < len) {
                   1163:                len -= m0->m_len;
                   1164:                m0 = m0->m_next;
                   1165:        }
                   1166:
                   1167:        if (m0->m_len != len) {
                   1168:                DPRINTF(("m_pad(): length mismatch (should be %d instead of "
                   1169:                    "%d)\n", m->m_pkthdr.len,
                   1170:                    m->m_pkthdr.len + m0->m_len - len));
                   1171:
                   1172:                m_freem(m);
                   1173:                return NULL;
                   1174:        }
                   1175:
                   1176:        /* Check for zero-length trailing mbufs, and find the last one. */
                   1177:        for (m1 = m0; m1->m_next; m1 = m1->m_next) {
                   1178:                if (m1->m_next->m_len != 0) {
                   1179:                        DPRINTF(("m_pad(): length mismatch (should be %d "
                   1180:                            "instead of %d)\n", m->m_pkthdr.len,
                   1181:                            m->m_pkthdr.len + m1->m_next->m_len));
                   1182:
                   1183:                        m_freem(m);
                   1184:                        return NULL;
                   1185:                }
                   1186:
                   1187:                m0 = m1->m_next;
                   1188:        }
                   1189:
                   1190:        if ((m0->m_flags & M_EXT) ||
                   1191:            m0->m_data + m0->m_len + pad >= &(m0->m_dat[MLEN])) {
                   1192:                /* Add an mbuf to the chain. */
                   1193:                MGET(m1, M_DONTWAIT, MT_DATA);
                   1194:                if (m1 == 0) {
                   1195:                        m_freem(m0);
                   1196:                        DPRINTF(("m_pad(): cannot append\n"));
                   1197:                        return NULL;
                   1198:                }
                   1199:
                   1200:                m0->m_next = m1;
                   1201:                m0 = m1;
                   1202:                m0->m_len = 0;
                   1203:        }
                   1204:
                   1205:        retval = m0->m_data + m0->m_len;
                   1206:        m0->m_len += pad;
                   1207:        m->m_pkthdr.len += pad;
                   1208:
                   1209:        return retval;
                   1210: }

CVSweb