Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/cxgbe/crypto/t4_crypto.c
Show First 20 Lines • Show All 1,385 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
ccr_gcm_soft(struct ccr_session *s, struct cryptop *crp) | ccr_gcm_soft(struct ccr_session *s, struct cryptop *crp) | ||||
{ | { | ||||
const struct auth_hash *axf; | const struct auth_hash *axf; | ||||
const struct enc_xform *exf; | const struct enc_xform *exf; | ||||
void *auth_ctx, *kschedule; | void *auth_ctx, *kschedule; | ||||
char block[GMAC_BLOCK_LEN]; | char block[GMAC_BLOCK_LEN]; | ||||
char digest[GMAC_DIGEST_LEN]; | char digest[GMAC_DIGEST_LEN]; | ||||
char iv[AES_BLOCK_LEN]; | |||||
int error, i, len; | int error, i, len; | ||||
auth_ctx = NULL; | auth_ctx = NULL; | ||||
kschedule = NULL; | kschedule = NULL; | ||||
/* Initialize the MAC. */ | /* Initialize the MAC. */ | ||||
switch (s->blkcipher.key_len) { | switch (s->blkcipher.key_len) { | ||||
case 16: | case 16: | ||||
Show All 28 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; | ||||
} | } | ||||
crypto_read_iv(crp, iv); | |||||
*(uint32_t *)&iv[12] = htobe32(1); | |||||
axf->Reinit(auth_ctx, iv, sizeof(iv)); | axf->Reinit(auth_ctx, crp->crp_iv, AES_GCM_IV_LEN); | ||||
/* 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) | ||||
axf->Update(auth_ctx, crp->crp_aad, len); | axf->Update(auth_ctx, crp->crp_aad, len); | ||||
if (crp->crp_aad_length != len) { | if (crp->crp_aad_length != len) { | ||||
memset(block, 0, sizeof(block)); | memset(block, 0, sizeof(block)); | ||||
memcpy(block, (char *)crp->crp_aad + len, | memcpy(block, (char *)crp->crp_aad + len, | ||||
crp->crp_aad_length - len); | crp->crp_aad_length - len); | ||||
axf->Update(auth_ctx, block, sizeof(block)); | axf->Update(auth_ctx, block, sizeof(block)); | ||||
} | } | ||||
} else { | } else { | ||||
for (i = 0; i < crp->crp_aad_length; i += sizeof(block)) { | for (i = 0; i < crp->crp_aad_length; i += sizeof(block)) { | ||||
len = imin(crp->crp_aad_length - i, sizeof(block)); | len = imin(crp->crp_aad_length - i, sizeof(block)); | ||||
crypto_copydata(crp, crp->crp_aad_start + i, len, | crypto_copydata(crp, crp->crp_aad_start + i, len, | ||||
block); | block); | ||||
bzero(block + len, sizeof(block) - len); | bzero(block + len, sizeof(block) - len); | ||||
axf->Update(auth_ctx, block, sizeof(block)); | axf->Update(auth_ctx, block, sizeof(block)); | ||||
} | } | ||||
} | } | ||||
exf->reinit(kschedule, iv, sizeof(iv)); | exf->reinit(kschedule, crp->crp_iv, AES_GCM_IV_LEN); | ||||
/* Do encryption with MAC */ | /* Do encryption with MAC */ | ||||
for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) { | for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) { | ||||
len = imin(crp->crp_payload_length - i, sizeof(block)); | len = imin(crp->crp_payload_length - i, sizeof(block)); | ||||
crypto_copydata(crp, crp->crp_payload_start + i, len, block); | crypto_copydata(crp, crp->crp_payload_start + i, len, block); | ||||
bzero(block + len, sizeof(block) - len); | bzero(block + len, sizeof(block) - len); | ||||
if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { | if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { | ||||
exf->encrypt(kschedule, block, block); | exf->encrypt(kschedule, block, block); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if (timingsafe_bcmp(digest, digest2, sizeof(digest)) == 0) { | ||||
error = EBADMSG; | error = EBADMSG; | ||||
explicit_bzero(digest2, sizeof(digest2)); | explicit_bzero(digest2, sizeof(digest2)); | ||||
} | } | ||||
out: | out: | ||||
zfree(kschedule, M_CCR); | zfree(kschedule, M_CCR); | ||||
zfree(auth_ctx, M_CCR); | zfree(auth_ctx, M_CCR); | ||||
explicit_bzero(block, sizeof(block)); | explicit_bzero(block, sizeof(block)); | ||||
explicit_bzero(iv, sizeof(iv)); | |||||
explicit_bzero(digest, sizeof(digest)); | explicit_bzero(digest, sizeof(digest)); | ||||
crp->crp_etype = error; | crp->crp_etype = error; | ||||
crypto_done(crp); | crypto_done(crp); | ||||
} | } | ||||
static void | static void | ||||
generate_ccm_b0(struct cryptop *crp, u_int hash_size_in_response, | generate_ccm_b0(struct cryptop *crp, u_int hash_size_in_response, | ||||
const char *iv, char *b0) | const char *iv, char *b0) | ||||
▲ Show 20 Lines • Show All 339 Lines • ▼ Show 20 Lines | |||||
ccr_ccm_soft(struct ccr_session *s, struct cryptop *crp) | ccr_ccm_soft(struct ccr_session *s, struct cryptop *crp) | ||||
{ | { | ||||
const struct auth_hash *axf; | const struct auth_hash *axf; | ||||
const struct enc_xform *exf; | const struct enc_xform *exf; | ||||
union authctx *auth_ctx; | union authctx *auth_ctx; | ||||
void *kschedule; | void *kschedule; | ||||
char block[CCM_CBC_BLOCK_LEN]; | char block[CCM_CBC_BLOCK_LEN]; | ||||
char digest[AES_CBC_MAC_HASH_LEN]; | char digest[AES_CBC_MAC_HASH_LEN]; | ||||
char iv[AES_CCM_IV_LEN]; | |||||
int error, i, len; | int error, i, len; | ||||
auth_ctx = NULL; | auth_ctx = NULL; | ||||
kschedule = NULL; | kschedule = NULL; | ||||
/* Initialize the MAC. */ | /* Initialize the MAC. */ | ||||
switch (s->blkcipher.key_len) { | switch (s->blkcipher.key_len) { | ||||
case 16: | case 16: | ||||
Show All 28 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; | ||||
} | } | ||||
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, crp->crp_iv, AES_CCM_IV_LEN); | ||||
/* 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, | ||||
crp->crp_aad_length); | crp->crp_aad_length); | ||||
else | else | ||||
error = crypto_apply(crp, crp->crp_aad_start, | error = crypto_apply(crp, crp->crp_aad_start, | ||||
crp->crp_aad_length, axf->Update, auth_ctx); | crp->crp_aad_length, axf->Update, auth_ctx); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
exf->reinit(kschedule, iv, sizeof(iv)); | exf->reinit(kschedule, crp->crp_iv, AES_CCM_IV_LEN); | ||||
/* Do encryption/decryption with MAC */ | /* Do encryption/decryption with MAC */ | ||||
for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) { | for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) { | ||||
len = imin(crp->crp_payload_length - i, sizeof(block)); | len = imin(crp->crp_payload_length - i, sizeof(block)); | ||||
crypto_copydata(crp, crp->crp_payload_start + i, len, block); | crypto_copydata(crp, crp->crp_payload_start + i, len, block); | ||||
bzero(block + len, sizeof(block) - len); | bzero(block + len, sizeof(block) - len); | ||||
if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { | if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { | ||||
axf->Update(auth_ctx, block, len); | axf->Update(auth_ctx, block, len); | ||||
Show All 18 Lines | if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { | ||||
char digest2[AES_CBC_MAC_HASH_LEN]; | char digest2[AES_CBC_MAC_HASH_LEN]; | ||||
crypto_copydata(crp, crp->crp_digest_start, sizeof(digest2), | crypto_copydata(crp, crp->crp_digest_start, sizeof(digest2), | ||||
digest2); | digest2); | ||||
if (timingsafe_bcmp(digest, digest2, sizeof(digest)) == 0) { | if (timingsafe_bcmp(digest, digest2, sizeof(digest)) == 0) { | ||||
error = 0; | error = 0; | ||||
/* Tag matches, decrypt data. */ | /* Tag matches, decrypt data. */ | ||||
exf->reinit(kschedule, iv, sizeof(iv)); | exf->reinit(kschedule, crp->crp_iv, AES_CCM_IV_LEN); | ||||
for (i = 0; i < crp->crp_payload_length; | for (i = 0; i < crp->crp_payload_length; | ||||
i += sizeof(block)) { | i += sizeof(block)) { | ||||
len = imin(crp->crp_payload_length - i, | len = imin(crp->crp_payload_length - i, | ||||
sizeof(block)); | sizeof(block)); | ||||
crypto_copydata(crp, crp->crp_payload_start + i, | crypto_copydata(crp, crp->crp_payload_start + i, | ||||
len, block); | len, block); | ||||
bzero(block + len, sizeof(block) - len); | bzero(block + len, sizeof(block) - len); | ||||
exf->decrypt(kschedule, block, block); | exf->decrypt(kschedule, block, block); | ||||
crypto_copyback(crp, crp->crp_payload_start + i, | crypto_copyback(crp, crp->crp_payload_start + i, | ||||
len, block); | len, block); | ||||
} | } | ||||
} else | } else | ||||
error = EBADMSG; | error = EBADMSG; | ||||
explicit_bzero(digest2, sizeof(digest2)); | explicit_bzero(digest2, sizeof(digest2)); | ||||
} | } | ||||
out: | out: | ||||
zfree(kschedule, M_CCR); | zfree(kschedule, M_CCR); | ||||
zfree(auth_ctx, M_CCR); | zfree(auth_ctx, M_CCR); | ||||
explicit_bzero(block, sizeof(block)); | explicit_bzero(block, sizeof(block)); | ||||
explicit_bzero(iv, sizeof(iv)); | |||||
explicit_bzero(digest, sizeof(digest)); | explicit_bzero(digest, sizeof(digest)); | ||||
crp->crp_etype = error; | crp->crp_etype = error; | ||||
crypto_done(crp); | crypto_done(crp); | ||||
} | } | ||||
static void | static void | ||||
ccr_identify(driver_t *driver, device_t parent) | ccr_identify(driver_t *driver, device_t parent) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 956 Lines • Show Last 20 Lines |