[BACK]Return to cryptosoft.c CVS log [TXT][DIR] Up to [local] / sys / crypto

Annotation of sys/crypto/cryptosoft.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: cryptosoft.c,v 1.46 2006/12/29 13:04:37 pedro Exp $   */
                      2:
                      3: /*
                      4:  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
                      5:  *
                      6:  * This code was written by Angelos D. Keromytis in Athens, Greece, in
                      7:  * February 2000. Network Security Technologies Inc. (NSTI) kindly
                      8:  * supported the development of this code.
                      9:  *
                     10:  * Copyright (c) 2000, 2001 Angelos D. Keromytis
                     11:  *
                     12:  * Permission to use, copy, and modify this software with or without fee
                     13:  * is hereby granted, provided that this entire notice is included in
                     14:  * all source code copies of any software which is or includes a copy or
                     15:  * modification of this software.
                     16:  *
                     17:  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
                     18:  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
                     19:  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
                     20:  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
                     21:  * PURPOSE.
                     22:  */
                     23:
                     24: #include <sys/param.h>
                     25: #include <sys/systm.h>
                     26: #include <sys/malloc.h>
                     27: #include <sys/mbuf.h>
                     28: #include <sys/sysctl.h>
                     29: #include <sys/errno.h>
                     30: #include <dev/rndvar.h>
                     31: #include <crypto/md5.h>
                     32: #include <crypto/sha1.h>
                     33: #include <crypto/rmd160.h>
                     34: #include <crypto/cast.h>
                     35: #include <crypto/skipjack.h>
                     36: #include <crypto/blf.h>
                     37: #include <crypto/cryptodev.h>
                     38: #include <crypto/cryptosoft.h>
                     39: #include <crypto/xform.h>
                     40:
                     41: u_int8_t hmac_ipad_buffer[64] = {
                     42:        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                     43:        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                     44:        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                     45:        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                     46:        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                     47:        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                     48:        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                     49:        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
                     50: };
                     51:
                     52: u_int8_t hmac_opad_buffer[64] = {
                     53:        0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                     54:        0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                     55:        0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                     56:        0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                     57:        0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                     58:        0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                     59:        0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                     60:        0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
                     61: };
                     62:
                     63:
                     64: struct swcr_data **swcr_sessions = NULL;
                     65: u_int32_t swcr_sesnum = 0;
                     66: int32_t swcr_id = -1;
                     67:
                     68: #define COPYBACK(x, a, b, c, d) \
                     69:        (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \
                     70:        : cuio_copyback((struct uio *)a,b,c,d)
                     71: #define COPYDATA(x, a, b, c, d) \
                     72:        (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \
                     73:        : cuio_copydata((struct uio *)a,b,c,d)
                     74:
                     75: /*
                     76:  * Apply a symmetric encryption/decryption algorithm.
                     77:  */
                     78: int
                     79: swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
                     80:     int outtype)
                     81: {
                     82:        unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
                     83:        unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
                     84:        struct enc_xform *exf;
                     85:        int i, k, j, blks, ind, count, ivlen;
                     86:        struct mbuf *m = NULL;
                     87:        struct uio *uio = NULL;
                     88:
                     89:        exf = sw->sw_exf;
                     90:        blks = exf->blocksize;
                     91:        ivlen = exf->ivsize;
                     92:
                     93:        /* Check for non-padded data */
                     94:        if (crd->crd_len % blks)
                     95:                return EINVAL;
                     96:
                     97:        if (outtype == CRYPTO_BUF_MBUF)
                     98:                m = (struct mbuf *) buf;
                     99:        else
                    100:                uio = (struct uio *) buf;
                    101:
                    102:        /* Initialize the IV */
                    103:        if (crd->crd_flags & CRD_F_ENCRYPT) {
                    104:                /* IV explicitly provided ? */
                    105:                if (crd->crd_flags & CRD_F_IV_EXPLICIT)
                    106:                        bcopy(crd->crd_iv, iv, ivlen);
                    107:                else
                    108:                        arc4random_bytes(iv, ivlen);
                    109:
                    110:                /* Do we need to write the IV */
                    111:                if (!(crd->crd_flags & CRD_F_IV_PRESENT)) {
                    112:                        COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv);
                    113:                }
                    114:
                    115:        } else {        /* Decryption */
                    116:                        /* IV explicitly provided ? */
                    117:                if (crd->crd_flags & CRD_F_IV_EXPLICIT)
                    118:                        bcopy(crd->crd_iv, iv, ivlen);
                    119:                else {
                    120:                        /* Get IV off buf */
                    121:                        COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv);
                    122:                }
                    123:        }
                    124:
                    125:        ivp = iv;
                    126:
                    127:        if (exf->reinit)
                    128:                exf->reinit(sw->sw_kschedule, iv);
                    129:
                    130:        if (outtype == CRYPTO_BUF_MBUF) {
                    131:                /* Find beginning of data */
                    132:                m = m_getptr(m, crd->crd_skip, &k);
                    133:                if (m == NULL)
                    134:                        return EINVAL;
                    135:
                    136:                i = crd->crd_len;
                    137:
                    138:                while (i > 0) {
                    139:                        /*
                    140:                         * If there's insufficient data at the end of
                    141:                         * an mbuf, we have to do some copying.
                    142:                         */
                    143:                        if (m->m_len < k + blks && m->m_len != k) {
                    144:                                m_copydata(m, k, blks, blk);
                    145:
                    146:                                /* Actual encryption/decryption */
                    147:                                if (exf->reinit) {
                    148:                                        exf->encrypt(sw->sw_kschedule, blk);
                    149:                                } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                    150:                                        /* XOR with previous block */
                    151:                                        for (j = 0; j < blks; j++)
                    152:                                                blk[j] ^= ivp[j];
                    153:
                    154:                                        exf->encrypt(sw->sw_kschedule, blk);
                    155:
                    156:                                        /*
                    157:                                         * Keep encrypted block for XOR'ing
                    158:                                         * with next block
                    159:                                         */
                    160:                                        bcopy(blk, iv, blks);
                    161:                                        ivp = iv;
                    162:                                } else {        /* decrypt */
                    163:                                        /*
                    164:                                         * Keep encrypted block for XOR'ing
                    165:                                         * with next block
                    166:                                         */
                    167:                                        if (ivp == iv)
                    168:                                                bcopy(blk, piv, blks);
                    169:                                        else
                    170:                                                bcopy(blk, iv, blks);
                    171:
                    172:                                        exf->decrypt(sw->sw_kschedule, blk);
                    173:
                    174:                                        /* XOR with previous block */
                    175:                                        for (j = 0; j < blks; j++)
                    176:                                                blk[j] ^= ivp[j];
                    177:
                    178:                                        if (ivp == iv)
                    179:                                                bcopy(piv, iv, blks);
                    180:                                        else
                    181:                                                ivp = iv;
                    182:                                }
                    183:
                    184:                                /* Copy back decrypted block */
                    185:                                m_copyback(m, k, blks, blk);
                    186:
                    187:                                /* Advance pointer */
                    188:                                m = m_getptr(m, k + blks, &k);
                    189:                                if (m == NULL)
                    190:                                        return EINVAL;
                    191:
                    192:                                i -= blks;
                    193:
                    194:                                /* Could be done... */
                    195:                                if (i == 0)
                    196:                                        break;
                    197:                        }
                    198:
                    199:                        /* Skip possibly empty mbufs */
                    200:                        if (k == m->m_len) {
                    201:                                for (m = m->m_next; m && m->m_len == 0;
                    202:                                    m = m->m_next)
                    203:                                        ;
                    204:                                k = 0;
                    205:                        }
                    206:
                    207:                        /* Sanity check */
                    208:                        if (m == NULL)
                    209:                                return EINVAL;
                    210:
                    211:                        /*
                    212:                         * Warning: idat may point to garbage here, but
                    213:                         * we only use it in the while() loop, only if
                    214:                         * there are indeed enough data.
                    215:                         */
                    216:                        idat = mtod(m, unsigned char *) + k;
                    217:
                    218:                        while (m->m_len >= k + blks && i > 0) {
                    219:                                if (exf->reinit) {
                    220:                                        exf->encrypt(sw->sw_kschedule, idat);
                    221:                                } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                    222:                                        /* XOR with previous block/IV */
                    223:                                        for (j = 0; j < blks; j++)
                    224:                                                idat[j] ^= ivp[j];
                    225:
                    226:                                        exf->encrypt(sw->sw_kschedule, idat);
                    227:                                        ivp = idat;
                    228:                                } else {        /* decrypt */
                    229:                                        /*
                    230:                                         * Keep encrypted block to be used
                    231:                                         * in next block's processing.
                    232:                                         */
                    233:                                        if (ivp == iv)
                    234:                                                bcopy(idat, piv, blks);
                    235:                                        else
                    236:                                                bcopy(idat, iv, blks);
                    237:
                    238:                                        exf->decrypt(sw->sw_kschedule, idat);
                    239:
                    240:                                        /* XOR with previous block/IV */
                    241:                                        for (j = 0; j < blks; j++)
                    242:                                                idat[j] ^= ivp[j];
                    243:
                    244:                                        if (ivp == iv)
                    245:                                                bcopy(piv, iv, blks);
                    246:                                        else
                    247:                                                ivp = iv;
                    248:                                }
                    249:
                    250:                                idat += blks;
                    251:                                k += blks;
                    252:                                i -= blks;
                    253:                        }
                    254:                }
                    255:        } else {
                    256:                /* Find beginning of data */
                    257:                count = crd->crd_skip;
                    258:                ind = cuio_getptr(uio, count, &k);
                    259:                if (ind == -1)
                    260:                        return EINVAL;
                    261:
                    262:                i = crd->crd_len;
                    263:
                    264:                while (i > 0) {
                    265:                        /*
                    266:                         * If there's insufficient data at the end,
                    267:                         * we have to do some copying.
                    268:                         */
                    269:                        if (uio->uio_iov[ind].iov_len < k + blks &&
                    270:                            uio->uio_iov[ind].iov_len != k) {
                    271:                                cuio_copydata(uio, k, blks, blk);
                    272:
                    273:                                /* Actual encryption/decryption */
                    274:                                if (exf->reinit) {
                    275:                                        exf->encrypt(sw->sw_kschedule, blk);
                    276:                                } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                    277:                                        /* XOR with previous block */
                    278:                                        for (j = 0; j < blks; j++)
                    279:                                                blk[j] ^= ivp[j];
                    280:
                    281:                                        exf->encrypt(sw->sw_kschedule, blk);
                    282:
                    283:                                        /*
                    284:                                         * Keep encrypted block for XOR'ing
                    285:                                         * with next block
                    286:                                         */
                    287:                                        bcopy(blk, iv, blks);
                    288:                                        ivp = iv;
                    289:                                } else {        /* decrypt */
                    290:                                        /*
                    291:                                         * Keep encrypted block for XOR'ing
                    292:                                         * with next block
                    293:                                         */
                    294:                                        if (ivp == iv)
                    295:                                                bcopy(blk, piv, blks);
                    296:                                        else
                    297:                                                bcopy(blk, iv, blks);
                    298:
                    299:                                        exf->decrypt(sw->sw_kschedule, blk);
                    300:
                    301:                                        /* XOR with previous block */
                    302:                                        for (j = 0; j < blks; j++)
                    303:                                                blk[j] ^= ivp[j];
                    304:
                    305:                                        if (ivp == iv)
                    306:                                                bcopy(piv, iv, blks);
                    307:                                        else
                    308:                                                ivp = iv;
                    309:                                }
                    310:
                    311:                                /* Copy back decrypted block */
                    312:                                cuio_copyback(uio, k, blks, blk);
                    313:
                    314:                                count += blks;
                    315:
                    316:                                /* Advance pointer */
                    317:                                ind = cuio_getptr(uio, count, &k);
                    318:                                if (ind == -1)
                    319:                                        return (EINVAL);
                    320:
                    321:                                i -= blks;
                    322:
                    323:                                /* Could be done... */
                    324:                                if (i == 0)
                    325:                                        break;
                    326:                        }
                    327:
                    328:                        /*
                    329:                         * Warning: idat may point to garbage here, but
                    330:                         * we only use it in the while() loop, only if
                    331:                         * there are indeed enough data.
                    332:                         */
                    333:                        idat = (char *)uio->uio_iov[ind].iov_base + k;
                    334:
                    335:                        while (uio->uio_iov[ind].iov_len >= k + blks &&
                    336:                            i > 0) {
                    337:                                if (exf->reinit) {
                    338:                                        exf->encrypt(sw->sw_kschedule, idat);
                    339:                                } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                    340:                                        /* XOR with previous block/IV */
                    341:                                        for (j = 0; j < blks; j++)
                    342:                                                idat[j] ^= ivp[j];
                    343:
                    344:                                        exf->encrypt(sw->sw_kschedule, idat);
                    345:                                        ivp = idat;
                    346:                                } else {        /* decrypt */
                    347:                                        /*
                    348:                                         * Keep encrypted block to be used
                    349:                                         * in next block's processing.
                    350:                                         */
                    351:                                        if (ivp == iv)
                    352:                                                bcopy(idat, piv, blks);
                    353:                                        else
                    354:                                                bcopy(idat, iv, blks);
                    355:
                    356:                                        exf->decrypt(sw->sw_kschedule, idat);
                    357:
                    358:                                        /* XOR with previous block/IV */
                    359:                                        for (j = 0; j < blks; j++)
                    360:                                                idat[j] ^= ivp[j];
                    361:
                    362:                                        if (ivp == iv)
                    363:                                                bcopy(piv, iv, blks);
                    364:                                        else
                    365:                                                ivp = iv;
                    366:                                }
                    367:
                    368:                                idat += blks;
                    369:                                count += blks;
                    370:                                k += blks;
                    371:                                i -= blks;
                    372:                        }
                    373:                }
                    374:        }
                    375:
                    376:        return 0; /* Done with encryption/decryption */
                    377: }
                    378:
                    379: /*
                    380:  * Compute keyed-hash authenticator.
                    381:  */
                    382: int
                    383: swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
                    384:     struct swcr_data *sw, caddr_t buf, int outtype)
                    385: {
                    386:        unsigned char aalg[AALG_MAX_RESULT_LEN];
                    387:        struct auth_hash *axf;
                    388:        union authctx ctx;
                    389:        int err;
                    390:
                    391:        if (sw->sw_ictx == 0)
                    392:                return EINVAL;
                    393:
                    394:        axf = sw->sw_axf;
                    395:
                    396:        bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
                    397:
                    398:        if (outtype == CRYPTO_BUF_MBUF)
                    399:                err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len,
                    400:                    (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
                    401:                    (caddr_t) &ctx);
                    402:        else
                    403:                err = cuio_apply((struct uio *) buf, crd->crd_skip,
                    404:                    crd->crd_len,
                    405:                    (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
                    406:                    (caddr_t) &ctx);
                    407:
                    408:        if (err)
                    409:                return err;
                    410:
                    411:        switch (sw->sw_alg) {
                    412:        case CRYPTO_MD5_HMAC:
                    413:        case CRYPTO_SHA1_HMAC:
                    414:        case CRYPTO_RIPEMD160_HMAC:
                    415:        case CRYPTO_SHA2_256_HMAC:
                    416:        case CRYPTO_SHA2_384_HMAC:
                    417:        case CRYPTO_SHA2_512_HMAC:
                    418:                if (sw->sw_octx == NULL)
                    419:                        return EINVAL;
                    420:
                    421:                axf->Final(aalg, &ctx);
                    422:                bcopy(sw->sw_octx, &ctx, axf->ctxsize);
                    423:                axf->Update(&ctx, aalg, axf->hashsize);
                    424:                axf->Final(aalg, &ctx);
                    425:                break;
                    426:
                    427:        case CRYPTO_MD5_KPDK:
                    428:        case CRYPTO_SHA1_KPDK:
                    429:                if (sw->sw_octx == NULL)
                    430:                        return EINVAL;
                    431:
                    432:                axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
                    433:                axf->Final(aalg, &ctx);
                    434:                break;
                    435:
                    436:        case CRYPTO_MD5:
                    437:        case CRYPTO_SHA1:
                    438:                axf->Final(aalg, &ctx);
                    439:                break;
                    440:        }
                    441:
                    442:        /* Inject the authentication data */
                    443:        if (outtype == CRYPTO_BUF_MBUF)
                    444:                COPYBACK(outtype, buf, crd->crd_inject, axf->authsize, aalg);
                    445:        else
                    446:                bcopy(aalg, crp->crp_mac, axf->authsize);
                    447:
                    448:        return 0;
                    449: }
                    450:
                    451: /*
                    452:  * Apply a compression/decompression algorithm
                    453:  */
                    454: int
                    455: swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
                    456:     caddr_t buf, int outtype)
                    457: {
                    458:        u_int8_t *data, *out;
                    459:        struct comp_algo *cxf;
                    460:        int adj;
                    461:        u_int32_t result;
                    462:
                    463:        cxf = sw->sw_cxf;
                    464:
                    465:        /* We must handle the whole buffer of data in one time
                    466:         * then if there is not all the data in the mbuf, we must
                    467:         * copy in a buffer.
                    468:         */
                    469:
                    470:        MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA,  M_NOWAIT);
                    471:        if (data == NULL)
                    472:                return (EINVAL);
                    473:        COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data);
                    474:
                    475:        if (crd->crd_flags & CRD_F_COMP)
                    476:                result = cxf->compress(data, crd->crd_len, &out);
                    477:        else
                    478:                result = cxf->decompress(data, crd->crd_len, &out);
                    479:
                    480:        FREE(data, M_CRYPTO_DATA);
                    481:        if (result == 0)
                    482:                return EINVAL;
                    483:
                    484:        /* Copy back the (de)compressed data. m_copyback is
                    485:         * extending the mbuf as necessary.
                    486:         */
                    487:        sw->sw_size = result;
                    488:        /* Check the compressed size when doing compression */
                    489:        if (crd->crd_flags & CRD_F_COMP) {
                    490:                if (result > crd->crd_len) {
                    491:                        /* Compression was useless, we lost time */
                    492:                        FREE(out, M_CRYPTO_DATA);
                    493:                        return 0;
                    494:                }
                    495:        }
                    496:
                    497:        COPYBACK(outtype, buf, crd->crd_skip, result, out);
                    498:        if (result < crd->crd_len) {
                    499:                adj = result - crd->crd_len;
                    500:                if (outtype == CRYPTO_BUF_MBUF) {
                    501:                        adj = result - crd->crd_len;
                    502:                        m_adj((struct mbuf *)buf, adj);
                    503:                } else {
                    504:                        struct uio *uio = (struct uio *)buf;
                    505:                        int ind;
                    506:
                    507:                        adj = crd->crd_len - result;
                    508:                        ind = uio->uio_iovcnt - 1;
                    509:
                    510:                        while (adj > 0 && ind >= 0) {
                    511:                                if (adj < uio->uio_iov[ind].iov_len) {
                    512:                                        uio->uio_iov[ind].iov_len -= adj;
                    513:                                        break;
                    514:                                }
                    515:
                    516:                                adj -= uio->uio_iov[ind].iov_len;
                    517:                                uio->uio_iov[ind].iov_len = 0;
                    518:                                ind--;
                    519:                                uio->uio_iovcnt--;
                    520:                        }
                    521:                }
                    522:        }
                    523:        FREE(out, M_CRYPTO_DATA);
                    524:        return 0;
                    525: }
                    526:
                    527: /*
                    528:  * Generate a new software session.
                    529:  */
                    530: int
                    531: swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
                    532: {
                    533:        struct swcr_data **swd;
                    534:        struct auth_hash *axf;
                    535:        struct enc_xform *txf;
                    536:        struct comp_algo *cxf;
                    537:        u_int32_t i;
                    538:        int k;
                    539:
                    540:        if (sid == NULL || cri == NULL)
                    541:                return EINVAL;
                    542:
                    543:        if (swcr_sessions) {
                    544:                for (i = 1; i < swcr_sesnum; i++)
                    545:                        if (swcr_sessions[i] == NULL)
                    546:                                break;
                    547:        }
                    548:
                    549:        if (swcr_sessions == NULL || i == swcr_sesnum) {
                    550:                if (swcr_sessions == NULL) {
                    551:                        i = 1; /* We leave swcr_sessions[0] empty */
                    552:                        swcr_sesnum = CRYPTO_SW_SESSIONS;
                    553:                } else
                    554:                        swcr_sesnum *= 2;
                    555:
                    556:                swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
                    557:                    M_CRYPTO_DATA, M_NOWAIT);
                    558:                if (swd == NULL) {
                    559:                        /* Reset session number */
                    560:                        if (swcr_sesnum == CRYPTO_SW_SESSIONS)
                    561:                                swcr_sesnum = 0;
                    562:                        else
                    563:                                swcr_sesnum /= 2;
                    564:                        return ENOBUFS;
                    565:                }
                    566:
                    567:                bzero(swd, swcr_sesnum * sizeof(struct swcr_data *));
                    568:
                    569:                /* Copy existing sessions */
                    570:                if (swcr_sessions) {
                    571:                        bcopy(swcr_sessions, swd,
                    572:                            (swcr_sesnum / 2) * sizeof(struct swcr_data *));
                    573:                        free(swcr_sessions, M_CRYPTO_DATA);
                    574:                }
                    575:
                    576:                swcr_sessions = swd;
                    577:        }
                    578:
                    579:        swd = &swcr_sessions[i];
                    580:        *sid = i;
                    581:
                    582:        while (cri) {
                    583:                MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
                    584:                    M_CRYPTO_DATA, M_NOWAIT);
                    585:                if (*swd == NULL) {
                    586:                        swcr_freesession(i);
                    587:                        return ENOBUFS;
                    588:                }
                    589:                bzero(*swd, sizeof(struct swcr_data));
                    590:
                    591:                switch (cri->cri_alg) {
                    592:                case CRYPTO_DES_CBC:
                    593:                        txf = &enc_xform_des;
                    594:                        goto enccommon;
                    595:                case CRYPTO_3DES_CBC:
                    596:                        txf = &enc_xform_3des;
                    597:                        goto enccommon;
                    598:                case CRYPTO_BLF_CBC:
                    599:                        txf = &enc_xform_blf;
                    600:                        goto enccommon;
                    601:                case CRYPTO_CAST_CBC:
                    602:                        txf = &enc_xform_cast5;
                    603:                        goto enccommon;
                    604:                case CRYPTO_SKIPJACK_CBC:
                    605:                        txf = &enc_xform_skipjack;
                    606:                        goto enccommon;
                    607:                case CRYPTO_RIJNDAEL128_CBC:
                    608:                        txf = &enc_xform_rijndael128;
                    609:                        goto enccommon;
                    610:                case CRYPTO_AES_CTR:
                    611:                        txf = &enc_xform_aes_ctr;
                    612:                        goto enccommon;
                    613:                case CRYPTO_NULL:
                    614:                        txf = &enc_xform_null;
                    615:                        goto enccommon;
                    616:                enccommon:
                    617:                        if (txf->setkey(&((*swd)->sw_kschedule), cri->cri_key,
                    618:                            cri->cri_klen / 8) < 0) {
                    619:                                swcr_freesession(i);
                    620:                                return EINVAL;
                    621:                        }
                    622:                        (*swd)->sw_exf = txf;
                    623:                        break;
                    624:
                    625:                case CRYPTO_MD5_HMAC:
                    626:                        axf = &auth_hash_hmac_md5_96;
                    627:                        goto authcommon;
                    628:                case CRYPTO_SHA1_HMAC:
                    629:                        axf = &auth_hash_hmac_sha1_96;
                    630:                        goto authcommon;
                    631:                case CRYPTO_RIPEMD160_HMAC:
                    632:                        axf = &auth_hash_hmac_ripemd_160_96;
                    633:                        goto authcommon;
                    634:                case CRYPTO_SHA2_256_HMAC:
                    635:                        axf = &auth_hash_hmac_sha2_256_96;
                    636:                        goto authcommon;
                    637:                case CRYPTO_SHA2_384_HMAC:
                    638:                        axf = &auth_hash_hmac_sha2_384_96;
                    639:                        goto authcommon;
                    640:                case CRYPTO_SHA2_512_HMAC:
                    641:                        axf = &auth_hash_hmac_sha2_512_96;
                    642:                authcommon:
                    643:                        (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
                    644:                            M_NOWAIT);
                    645:                        if ((*swd)->sw_ictx == NULL) {
                    646:                                swcr_freesession(i);
                    647:                                return ENOBUFS;
                    648:                        }
                    649:
                    650:                        (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
                    651:                            M_NOWAIT);
                    652:                        if ((*swd)->sw_octx == NULL) {
                    653:                                swcr_freesession(i);
                    654:                                return ENOBUFS;
                    655:                        }
                    656:
                    657:                        for (k = 0; k < cri->cri_klen / 8; k++)
                    658:                                cri->cri_key[k] ^= HMAC_IPAD_VAL;
                    659:
                    660:                        axf->Init((*swd)->sw_ictx);
                    661:                        axf->Update((*swd)->sw_ictx, cri->cri_key,
                    662:                            cri->cri_klen / 8);
                    663:                        axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
                    664:                            HMAC_BLOCK_LEN - (cri->cri_klen / 8));
                    665:
                    666:                        for (k = 0; k < cri->cri_klen / 8; k++)
                    667:                                cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
                    668:
                    669:                        axf->Init((*swd)->sw_octx);
                    670:                        axf->Update((*swd)->sw_octx, cri->cri_key,
                    671:                            cri->cri_klen / 8);
                    672:                        axf->Update((*swd)->sw_octx, hmac_opad_buffer,
                    673:                            HMAC_BLOCK_LEN - (cri->cri_klen / 8));
                    674:
                    675:                        for (k = 0; k < cri->cri_klen / 8; k++)
                    676:                                cri->cri_key[k] ^= HMAC_OPAD_VAL;
                    677:                        (*swd)->sw_axf = axf;
                    678:                        break;
                    679:
                    680:                case CRYPTO_MD5_KPDK:
                    681:                        axf = &auth_hash_key_md5;
                    682:                        goto auth2common;
                    683:
                    684:                case CRYPTO_SHA1_KPDK:
                    685:                        axf = &auth_hash_key_sha1;
                    686:                auth2common:
                    687:                        (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
                    688:                            M_NOWAIT);
                    689:                        if ((*swd)->sw_ictx == NULL) {
                    690:                                swcr_freesession(i);
                    691:                                return ENOBUFS;
                    692:                        }
                    693:
                    694:                        /* Store the key so we can "append" it to the payload */
                    695:                        (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA,
                    696:                            M_NOWAIT);
                    697:                        if ((*swd)->sw_octx == NULL) {
                    698:                                swcr_freesession(i);
                    699:                                return ENOBUFS;
                    700:                        }
                    701:
                    702:                        (*swd)->sw_klen = cri->cri_klen / 8;
                    703:                        bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8);
                    704:                        axf->Init((*swd)->sw_ictx);
                    705:                        axf->Update((*swd)->sw_ictx, cri->cri_key,
                    706:                            cri->cri_klen / 8);
                    707:                        axf->Final(NULL, (*swd)->sw_ictx);
                    708:                        (*swd)->sw_axf = axf;
                    709:                        break;
                    710:
                    711:                case CRYPTO_MD5:
                    712:                        axf = &auth_hash_md5;
                    713:                        goto auth3common;
                    714:
                    715:                case CRYPTO_SHA1:
                    716:                        axf = &auth_hash_sha1;
                    717:                auth3common:
                    718:                        (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
                    719:                            M_NOWAIT);
                    720:                        if ((*swd)->sw_ictx == NULL) {
                    721:                                swcr_freesession(i);
                    722:                                return ENOBUFS;
                    723:                        }
                    724:
                    725:                        axf->Init((*swd)->sw_ictx);
                    726:                        (*swd)->sw_axf = axf;
                    727:                        break;
                    728:
                    729:                case CRYPTO_DEFLATE_COMP:
                    730:                        cxf = &comp_algo_deflate;
                    731:                        (*swd)->sw_cxf = cxf;
                    732:                        break;
                    733:                default:
                    734:                        swcr_freesession(i);
                    735:                        return EINVAL;
                    736:                }
                    737:
                    738:                (*swd)->sw_alg = cri->cri_alg;
                    739:                cri = cri->cri_next;
                    740:                swd = &((*swd)->sw_next);
                    741:        }
                    742:        return 0;
                    743: }
                    744:
                    745: /*
                    746:  * Free a session.
                    747:  */
                    748: int
                    749: swcr_freesession(u_int64_t tid)
                    750: {
                    751:        struct swcr_data *swd;
                    752:        struct enc_xform *txf;
                    753:        struct auth_hash *axf;
                    754:        u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
                    755:
                    756:        if (sid > swcr_sesnum || swcr_sessions == NULL ||
                    757:            swcr_sessions[sid] == NULL)
                    758:                return EINVAL;
                    759:
                    760:        /* Silently accept and return */
                    761:        if (sid == 0)
                    762:                return 0;
                    763:
                    764:        while ((swd = swcr_sessions[sid]) != NULL) {
                    765:                swcr_sessions[sid] = swd->sw_next;
                    766:
                    767:                switch (swd->sw_alg) {
                    768:                case CRYPTO_DES_CBC:
                    769:                case CRYPTO_3DES_CBC:
                    770:                case CRYPTO_BLF_CBC:
                    771:                case CRYPTO_CAST_CBC:
                    772:                case CRYPTO_SKIPJACK_CBC:
                    773:                case CRYPTO_RIJNDAEL128_CBC:
                    774:                case CRYPTO_AES_CTR:
                    775:                case CRYPTO_NULL:
                    776:                        txf = swd->sw_exf;
                    777:
                    778:                        if (swd->sw_kschedule)
                    779:                                txf->zerokey(&(swd->sw_kschedule));
                    780:                        break;
                    781:
                    782:                case CRYPTO_MD5_HMAC:
                    783:                case CRYPTO_SHA1_HMAC:
                    784:                case CRYPTO_RIPEMD160_HMAC:
                    785:                case CRYPTO_SHA2_256_HMAC:
                    786:                case CRYPTO_SHA2_384_HMAC:
                    787:                case CRYPTO_SHA2_512_HMAC:
                    788:                        axf = swd->sw_axf;
                    789:
                    790:                        if (swd->sw_ictx) {
                    791:                                bzero(swd->sw_ictx, axf->ctxsize);
                    792:                                free(swd->sw_ictx, M_CRYPTO_DATA);
                    793:                        }
                    794:                        if (swd->sw_octx) {
                    795:                                bzero(swd->sw_octx, axf->ctxsize);
                    796:                                free(swd->sw_octx, M_CRYPTO_DATA);
                    797:                        }
                    798:                        break;
                    799:
                    800:                case CRYPTO_MD5_KPDK:
                    801:                case CRYPTO_SHA1_KPDK:
                    802:                        axf = swd->sw_axf;
                    803:
                    804:                        if (swd->sw_ictx) {
                    805:                                bzero(swd->sw_ictx, axf->ctxsize);
                    806:                                free(swd->sw_ictx, M_CRYPTO_DATA);
                    807:                        }
                    808:                        if (swd->sw_octx) {
                    809:                                bzero(swd->sw_octx, swd->sw_klen);
                    810:                                free(swd->sw_octx, M_CRYPTO_DATA);
                    811:                        }
                    812:                        break;
                    813:
                    814:                case CRYPTO_MD5:
                    815:                case CRYPTO_SHA1:
                    816:                        axf = swd->sw_axf;
                    817:
                    818:                        if (swd->sw_ictx)
                    819:                                free(swd->sw_ictx, M_CRYPTO_DATA);
                    820:                        break;
                    821:                }
                    822:
                    823:                FREE(swd, M_CRYPTO_DATA);
                    824:        }
                    825:        return 0;
                    826: }
                    827:
                    828: /*
                    829:  * Process a software request.
                    830:  */
                    831: int
                    832: swcr_process(struct cryptop *crp)
                    833: {
                    834:        struct cryptodesc *crd;
                    835:        struct swcr_data *sw;
                    836:        u_int32_t lid;
                    837:        int type;
                    838:
                    839:        /* Sanity check */
                    840:        if (crp == NULL)
                    841:                return EINVAL;
                    842:
                    843:        if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
                    844:                crp->crp_etype = EINVAL;
                    845:                goto done;
                    846:        }
                    847:
                    848:        lid = crp->crp_sid & 0xffffffff;
                    849:        if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
                    850:                crp->crp_etype = ENOENT;
                    851:                goto done;
                    852:        }
                    853:
                    854:        if (crp->crp_flags & CRYPTO_F_IMBUF)
                    855:                type = CRYPTO_BUF_MBUF;
                    856:        else
                    857:                type = CRYPTO_BUF_IOV;
                    858:
                    859:        /* Go through crypto descriptors, processing as we go */
                    860:        for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
                    861:                /*
                    862:                 * Find the crypto context.
                    863:                 *
                    864:                 * XXX Note that the logic here prevents us from having
                    865:                 * XXX the same algorithm multiple times in a session
                    866:                 * XXX (or rather, we can but it won't give us the right
                    867:                 * XXX results). To do that, we'd need some way of differentiating
                    868:                 * XXX between the various instances of an algorithm (so we can
                    869:                 * XXX locate the correct crypto context).
                    870:                 */
                    871:                for (sw = swcr_sessions[lid];
                    872:                    sw && sw->sw_alg != crd->crd_alg;
                    873:                    sw = sw->sw_next)
                    874:                        ;
                    875:
                    876:                /* No such context ? */
                    877:                if (sw == NULL) {
                    878:                        crp->crp_etype = EINVAL;
                    879:                        goto done;
                    880:                }
                    881:
                    882:                switch (sw->sw_alg) {
                    883:                case CRYPTO_NULL:
                    884:                        break;
                    885:                case CRYPTO_DES_CBC:
                    886:                case CRYPTO_3DES_CBC:
                    887:                case CRYPTO_BLF_CBC:
                    888:                case CRYPTO_CAST_CBC:
                    889:                case CRYPTO_SKIPJACK_CBC:
                    890:                case CRYPTO_RIJNDAEL128_CBC:
                    891:                case CRYPTO_AES_CTR:
                    892:                        if ((crp->crp_etype = swcr_encdec(crd, sw,
                    893:                            crp->crp_buf, type)) != 0)
                    894:                                goto done;
                    895:                        break;
                    896:                case CRYPTO_MD5_HMAC:
                    897:                case CRYPTO_SHA1_HMAC:
                    898:                case CRYPTO_RIPEMD160_HMAC:
                    899:                case CRYPTO_SHA2_256_HMAC:
                    900:                case CRYPTO_SHA2_384_HMAC:
                    901:                case CRYPTO_SHA2_512_HMAC:
                    902:                case CRYPTO_MD5_KPDK:
                    903:                case CRYPTO_SHA1_KPDK:
                    904:                case CRYPTO_MD5:
                    905:                case CRYPTO_SHA1:
                    906:                        if ((crp->crp_etype = swcr_authcompute(crp, crd, sw,
                    907:                            crp->crp_buf, type)) != 0)
                    908:                                goto done;
                    909:                        break;
                    910:
                    911:                case CRYPTO_DEFLATE_COMP:
                    912:                        if ((crp->crp_etype = swcr_compdec(crd, sw,
                    913:                            crp->crp_buf, type)) != 0)
                    914:                                goto done;
                    915:                        else
                    916:                                crp->crp_olen = (int)sw->sw_size;
                    917:                        break;
                    918:
                    919:                default:
                    920:                        /* Unknown/unsupported algorithm */
                    921:                        crp->crp_etype = EINVAL;
                    922:                        goto done;
                    923:                }
                    924:        }
                    925:
                    926: done:
                    927:        crypto_done(crp);
                    928:        return 0;
                    929: }
                    930:
                    931: /*
                    932:  * Initialize the driver, called from the kernel main().
                    933:  */
                    934: void
                    935: swcr_init(void)
                    936: {
                    937:        int algs[CRYPTO_ALGORITHM_MAX + 1];
                    938:        int flags = CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_ENCRYPT_MAC |
                    939:            CRYPTOCAP_F_MAC_ENCRYPT;
                    940:
                    941:        swcr_id = crypto_get_driverid(flags);
                    942:        if (swcr_id < 0) {
                    943:                /* This should never happen */
                    944:                panic("Software crypto device cannot initialize!");
                    945:        }
                    946:
                    947:        bzero(algs, sizeof(algs));
                    948:
                    949:        algs[CRYPTO_DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    950:        algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    951:        algs[CRYPTO_BLF_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    952:        algs[CRYPTO_CAST_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    953:        algs[CRYPTO_SKIPJACK_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    954:        algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    955:        algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    956:        algs[CRYPTO_RIPEMD160_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    957:        algs[CRYPTO_MD5_KPDK] = CRYPTO_ALG_FLAG_SUPPORTED;
                    958:        algs[CRYPTO_SHA1_KPDK] = CRYPTO_ALG_FLAG_SUPPORTED;
                    959:        algs[CRYPTO_MD5] = CRYPTO_ALG_FLAG_SUPPORTED;
                    960:        algs[CRYPTO_SHA1] = CRYPTO_ALG_FLAG_SUPPORTED;
                    961:        algs[CRYPTO_RIJNDAEL128_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    962:        algs[CRYPTO_AES_CTR] = CRYPTO_ALG_FLAG_SUPPORTED;
                    963:        algs[CRYPTO_DEFLATE_COMP] = CRYPTO_ALG_FLAG_SUPPORTED;
                    964:        algs[CRYPTO_NULL] = CRYPTO_ALG_FLAG_SUPPORTED;
                    965:        algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    966:        algs[CRYPTO_SHA2_384_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    967:        algs[CRYPTO_SHA2_512_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    968:
                    969:        crypto_register(swcr_id, algs, swcr_newsession,
                    970:            swcr_freesession, swcr_process);
                    971: }

CVSweb