Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/cxgbe/crypto/t4_crypto.c
Show First 20 Lines • Show All 1,130 Lines • ▼ Show 20 Lines | if (crp->crp_aad_length + AES_BLOCK_LEN > MAX_AAD_LEN) | ||||
return (EMSGSIZE); | return (EMSGSIZE); | ||||
hash_size_in_response = s->gmac.hash_len; | hash_size_in_response = s->gmac.hash_len; | ||||
if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) | if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) | ||||
op_type = CHCR_ENCRYPT_OP; | op_type = CHCR_ENCRYPT_OP; | ||||
else | else | ||||
op_type = CHCR_DECRYPT_OP; | op_type = CHCR_DECRYPT_OP; | ||||
/* | |||||
* The IV handling for GCM in OCF is a bit more complicated in | |||||
* that IPSec provides a full 16-byte IV (including the | |||||
* counter), whereas the /dev/crypto interface sometimes | |||||
* provides a full 16-byte IV (if no IV is provided in the | |||||
* ioctl) and sometimes a 12-byte IV (if the IV was explicit). | |||||
* | |||||
* When provided a 12-byte IV, assume the IV is really 16 bytes | |||||
* with a counter in the last 4 bytes initialized to 1. | |||||
* | |||||
* While iv_len is checked below, the value is currently | |||||
* always set to 12 when creating a GCM session in this driver | |||||
* due to limitations in OCF (there is no way to know what the | |||||
* IV length of a given request will be). This means that the | |||||
* driver always assumes as 12-byte IV for now. | |||||
*/ | |||||
if (s->blkcipher.iv_len == 12) | |||||
iv_len = AES_BLOCK_LEN; | iv_len = AES_BLOCK_LEN; | ||||
else | |||||
iv_len = s->blkcipher.iv_len; | |||||
/* | /* | ||||
* GCM requests should always provide an explicit IV. | * GCM requests should always provide an explicit IV. | ||||
*/ | */ | ||||
if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) | if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | ccr_gcm(struct ccr_softc *sc, struct ccr_session *s, struct cryptop *crp) | ||||
wr = alloc_wrqe(wr_len, s->port->txq); | wr = alloc_wrqe(wr_len, s->port->txq); | ||||
if (wr == NULL) { | if (wr == NULL) { | ||||
counter_u64_add(sc->stats_wr_nomem, 1); | counter_u64_add(sc->stats_wr_nomem, 1); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
crwr = wrtod(wr); | crwr = wrtod(wr); | ||||
memset(crwr, 0, wr_len); | memset(crwr, 0, wr_len); | ||||
memcpy(iv, crp->crp_iv, s->blkcipher.iv_len); | crypto_read_iv(crp, iv); | ||||
if (s->blkcipher.iv_len == 12) | |||||
*(uint32_t *)&iv[12] = htobe32(1); | *(uint32_t *)&iv[12] = htobe32(1); | ||||
ccr_populate_wreq(sc, s, crwr, kctx_len, wr_len, imm_len, sgl_len, 0, | ccr_populate_wreq(sc, s, crwr, kctx_len, wr_len, imm_len, sgl_len, 0, | ||||
crp); | crp); | ||||
crwr->sec_cpl.op_ivinsrtofst = htobe32( | crwr->sec_cpl.op_ivinsrtofst = htobe32( | ||||
V_CPL_TX_SEC_PDU_OPCODE(CPL_TX_SEC_PDU) | | V_CPL_TX_SEC_PDU_OPCODE(CPL_TX_SEC_PDU) | | ||||
V_CPL_TX_SEC_PDU_RXCHID(s->port->rx_channel_id) | | V_CPL_TX_SEC_PDU_RXCHID(s->port->rx_channel_id) | | ||||
V_CPL_TX_SEC_PDU_ACKFOLLOWS(0) | V_CPL_TX_SEC_PDU_ULPTXLPBK(1) | | V_CPL_TX_SEC_PDU_ACKFOLLOWS(0) | V_CPL_TX_SEC_PDU_ULPTXLPBK(1) | | ||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | if (kschedule == NULL) { | ||||
error = ENOMEM; | error = ENOMEM; | ||||
goto out; | goto out; | ||||
} | } | ||||
error = exf->setkey(kschedule, s->blkcipher.enckey, | error = exf->setkey(kschedule, s->blkcipher.enckey, | ||||
s->blkcipher.key_len); | s->blkcipher.key_len); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
/* | |||||
* This assumes a 12-byte IV from the crp. See longer comment | |||||
* above in ccr_gcm() for more details. | |||||
*/ | |||||
if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) { | if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
memcpy(iv, crp->crp_iv, 12); | crypto_read_iv(crp, iv); | ||||
*(uint32_t *)&iv[12] = htobe32(1); | *(uint32_t *)&iv[12] = htobe32(1); | ||||
axf->Reinit(auth_ctx, iv, sizeof(iv)); | axf->Reinit(auth_ctx, iv, sizeof(iv)); | ||||
/* MAC the AAD. */ | /* MAC the AAD. */ | ||||
if (crp->crp_aad != NULL) { | if (crp->crp_aad != NULL) { | ||||
len = rounddown(crp->crp_aad_length, sizeof(block)); | len = rounddown(crp->crp_aad_length, sizeof(block)); | ||||
if (len != 0) | if (len != 0) | ||||
▲ Show 20 Lines • Show All 297 Lines • ▼ Show 20 Lines | ccr_ccm(struct ccr_softc *sc, struct ccr_session *s, struct cryptop *crp) | ||||
memset(crwr, 0, wr_len); | memset(crwr, 0, wr_len); | ||||
/* | /* | ||||
* Read the nonce from the request. Use the nonce to generate | * Read the nonce from the request. Use the nonce to generate | ||||
* the full IV with the counter set to 0. | * the full IV with the counter set to 0. | ||||
*/ | */ | ||||
memset(iv, 0, iv_len); | memset(iv, 0, iv_len); | ||||
iv[0] = (15 - AES_CCM_IV_LEN) - 1; | iv[0] = (15 - AES_CCM_IV_LEN) - 1; | ||||
memcpy(iv + 1, crp->crp_iv, AES_CCM_IV_LEN); | crypto_read_iv(crp, iv + 1); | ||||
ccr_populate_wreq(sc, s, crwr, kctx_len, wr_len, imm_len, sgl_len, 0, | ccr_populate_wreq(sc, s, crwr, kctx_len, wr_len, imm_len, sgl_len, 0, | ||||
crp); | crp); | ||||
crwr->sec_cpl.op_ivinsrtofst = htobe32( | crwr->sec_cpl.op_ivinsrtofst = htobe32( | ||||
V_CPL_TX_SEC_PDU_OPCODE(CPL_TX_SEC_PDU) | | V_CPL_TX_SEC_PDU_OPCODE(CPL_TX_SEC_PDU) | | ||||
V_CPL_TX_SEC_PDU_RXCHID(s->port->rx_channel_id) | | V_CPL_TX_SEC_PDU_RXCHID(s->port->rx_channel_id) | | ||||
V_CPL_TX_SEC_PDU_ACKFOLLOWS(0) | V_CPL_TX_SEC_PDU_ULPTXLPBK(1) | | V_CPL_TX_SEC_PDU_ACKFOLLOWS(0) | V_CPL_TX_SEC_PDU_ULPTXLPBK(1) | | ||||
▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | error = exf->setkey(kschedule, s->blkcipher.enckey, | ||||
s->blkcipher.key_len); | s->blkcipher.key_len); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) { | if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
memcpy(iv, crp->crp_iv, AES_CCM_IV_LEN); | crypto_read_iv(crp, iv); | ||||
auth_ctx->aes_cbc_mac_ctx.authDataLength = crp->crp_aad_length; | auth_ctx->aes_cbc_mac_ctx.authDataLength = crp->crp_aad_length; | ||||
auth_ctx->aes_cbc_mac_ctx.cryptDataLength = crp->crp_payload_length; | auth_ctx->aes_cbc_mac_ctx.cryptDataLength = crp->crp_payload_length; | ||||
axf->Reinit(auth_ctx, iv, sizeof(iv)); | axf->Reinit(auth_ctx, iv, sizeof(iv)); | ||||
/* MAC the AAD. */ | /* MAC the AAD. */ | ||||
if (crp->crp_aad != NULL) | if (crp->crp_aad != NULL) | ||||
error = axf->Update(auth_ctx, crp->crp_aad, | error = axf->Update(auth_ctx, crp->crp_aad, | ||||
▲ Show 20 Lines • Show All 1,028 Lines • Show Last 20 Lines |