Index: sys/opencrypto/cryptosoft.c =================================================================== --- sys/opencrypto/cryptosoft.c +++ sys/opencrypto/cryptosoft.c @@ -392,6 +392,9 @@ if (err) return err; + if (crp->crp_flags & CRYPTO_F_ESN) + axf->Update(&ctx, crp->crp_esn, 4); + switch (axf->type) { case CRYPTO_SHA1: case CRYPTO_SHA2_224: @@ -505,7 +508,8 @@ struct auth_hash *axf; struct enc_xform *exf; uint32_t *blkp; - int blksz, i, ivlen, len, r; + int aadlen, blksz, i, ivlen, len, r, iskip, oskip; + iskip = oskip = 0; swa = &ses->swcr_auth; axf = swa->sw_axf; @@ -527,11 +531,24 @@ axf->Reinit(&ctx, iv, ivlen); /* Supply MAC with AAD */ - for (i = 0; i < crp->crp_aad_length; i += blksz) { - len = MIN(crp->crp_aad_length - i, blksz); - crypto_copydata(crp, crp->crp_aad_start + i, len, blk); - bzero(blk + len, blksz - len); + + aadlen = crp->crp_aad_length; + if (crp->crp_flags & CRYPTO_F_ESN) { + aadlen += 4; + /* SPI */ + crypto_copydata(crp, crp->crp_aad_start, 4, blk); + iskip = 4; + /* ESN */ + bcopy(crp->crp_esn, blk + 4, 4); + oskip = iskip + 4; + } + + for (i = iskip; i < crp->crp_aad_length; i += blksz) { + len = MIN(crp->crp_aad_length - i, blksz - oskip); + crypto_copydata(crp, crp->crp_aad_start + i, len, blk + oskip); + bzero(blk + len + oskip, blksz - len - oskip); axf->Update(&ctx, blk, blksz); + oskip = 0; /* reset initial output offset */ } exf->reinit(swe->sw_kschedule, iv); @@ -555,7 +572,7 @@ /* length block */ bzero(blk, blksz); blkp = (uint32_t *)blk + 1; - *blkp = htobe32(crp->crp_aad_length * 8); + *blkp = htobe32(aadlen * 8); blkp = (uint32_t *)blk + 3; *blkp = htobe32(crp->crp_payload_length * 8); axf->Update(&ctx, blk, blksz); @@ -658,7 +675,9 @@ struct swcr_encdec *swe; struct auth_hash *axf; struct enc_xform *exf; - int blksz, i, ivlen, len, r; + int aadlen, blksz, i, ivlen, len, r, iskip, oskip; + + iskip = oskip = 0; swa = &ses->swcr_auth; axf = swa->sw_axf; @@ -676,22 +695,35 @@ ivlen = AES_CCM_IV_LEN; bcopy(crp->crp_iv, iv, ivlen); + aadlen = crp->crp_aad_length; + if (crp->crp_flags & CRYPTO_F_ESN) + aadlen += 4; /* * AES CCM-CBC-MAC needs to know the length of both the auth * data and payload data before doing the auth computation. */ - ctx.aes_cbc_mac_ctx.authDataLength = crp->crp_aad_length; + ctx.aes_cbc_mac_ctx.authDataLength = aadlen; ctx.aes_cbc_mac_ctx.cryptDataLength = crp->crp_payload_length; /* Supply MAC with IV */ axf->Reinit(&ctx, iv, ivlen); /* Supply MAC with AAD */ - for (i = 0; i < crp->crp_aad_length; i += blksz) { - len = MIN(crp->crp_aad_length - i, blksz); - crypto_copydata(crp, crp->crp_aad_start + i, len, blk); - bzero(blk + len, blksz - len); + if (crp->crp_flags & CRYPTO_F_ESN) { + /* SPI */ + crypto_copydata(crp, crp->crp_aad_start, 4, blk); + iskip = 4; + /* ESN */ + bcopy(crp->crp_esn, blk + 4, 4); + oskip = iskip + 4; + } + + for (i = iskip; i < crp->crp_aad_length; i += blksz) { + len = MIN(crp->crp_aad_length - i, blksz - oskip); + crypto_copydata(crp, crp->crp_aad_start + i, len, blk + oskip); + bzero(blk + len + oskip, blksz - len - oskip); axf->Update(&ctx, blk, blksz); + oskip = 0; /* reset initial output offset */ } exf->reinit(swe->sw_kschedule, iv);