Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/cryptosoft.c
Show First 20 Lines • Show All 457 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
swcr_gcm(struct swcr_session *ses, struct cryptop *crp) | swcr_gcm(struct swcr_session *ses, struct cryptop *crp) | ||||
{ | { | ||||
uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; | uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; | ||||
u_char *blk = (u_char *)blkbuf; | u_char *blk = (u_char *)blkbuf; | ||||
u_char tag[GMAC_DIGEST_LEN]; | u_char tag[GMAC_DIGEST_LEN]; | ||||
u_char iv[AES_BLOCK_LEN]; | |||||
struct crypto_buffer_cursor cc_in, cc_out; | struct crypto_buffer_cursor cc_in, cc_out; | ||||
const u_char *inblk; | const u_char *inblk; | ||||
u_char *outblk; | u_char *outblk; | ||||
union authctx ctx; | union authctx ctx; | ||||
struct swcr_auth *swa; | struct swcr_auth *swa; | ||||
struct swcr_encdec *swe; | struct swcr_encdec *swe; | ||||
const struct auth_hash *axf; | const struct auth_hash *axf; | ||||
const struct enc_xform *exf; | const struct enc_xform *exf; | ||||
Show All 12 Lines | swcr_gcm(struct swcr_session *ses, struct cryptop *crp) | ||||
swe = &ses->swcr_encdec; | swe = &ses->swcr_encdec; | ||||
exf = swe->sw_exf; | exf = swe->sw_exf; | ||||
KASSERT(axf->blocksize == exf->native_blocksize, | KASSERT(axf->blocksize == exf->native_blocksize, | ||||
("%s: blocksize mismatch", __func__)); | ("%s: blocksize mismatch", __func__)); | ||||
if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) | if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* Initialize the IV */ | |||||
ivlen = AES_GCM_IV_LEN; | ivlen = AES_GCM_IV_LEN; | ||||
bcopy(crp->crp_iv, iv, ivlen); | |||||
/* Supply MAC with IV */ | /* Supply MAC with IV */ | ||||
axf->Reinit(&ctx, iv, ivlen); | axf->Reinit(&ctx, crp->crp_iv, ivlen); | ||||
/* Supply MAC with AAD */ | /* Supply MAC with AAD */ | ||||
if (crp->crp_aad != NULL) { | if (crp->crp_aad != NULL) { | ||||
len = rounddown(crp->crp_aad_length, blksz); | len = rounddown(crp->crp_aad_length, blksz); | ||||
if (len != 0) | if (len != 0) | ||||
axf->Update(&ctx, crp->crp_aad, len); | axf->Update(&ctx, crp->crp_aad, len); | ||||
if (crp->crp_aad_length != len) { | if (crp->crp_aad_length != len) { | ||||
memset(blk, 0, blksz); | memset(blk, 0, blksz); | ||||
Show All 22 Lines | if (resid > 0) { | ||||
crypto_cursor_copydata(&cc_in, resid, blk); | crypto_cursor_copydata(&cc_in, resid, blk); | ||||
axf->Update(&ctx, blk, blksz); | axf->Update(&ctx, blk, blksz); | ||||
} | } | ||||
} | } | ||||
if (crp->crp_cipher_key != NULL) | if (crp->crp_cipher_key != NULL) | ||||
exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | ||||
crypto_get_params(crp->crp_session)->csp_cipher_klen); | crypto_get_params(crp->crp_session)->csp_cipher_klen); | ||||
exf->reinit(swe->sw_kschedule, iv, ivlen); | exf->reinit(swe->sw_kschedule, crp->crp_iv, ivlen); | ||||
/* Do encryption with MAC */ | /* Do encryption with MAC */ | ||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start); | crypto_cursor_advance(&cc_in, crp->crp_payload_start); | ||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | ||||
crypto_cursor_init(&cc_out, &crp->crp_obuf); | crypto_cursor_init(&cc_out, &crp->crp_obuf); | ||||
crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | ||||
} else | } else | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | swcr_gcm(struct swcr_session *ses, struct cryptop *crp) | ||||
} else { | } else { | ||||
/* Inject the authentication data */ | /* Inject the authentication data */ | ||||
crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); | crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); | ||||
} | } | ||||
out: | out: | ||||
explicit_bzero(blkbuf, sizeof(blkbuf)); | explicit_bzero(blkbuf, sizeof(blkbuf)); | ||||
explicit_bzero(tag, sizeof(tag)); | explicit_bzero(tag, sizeof(tag)); | ||||
explicit_bzero(iv, sizeof(iv)); | |||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp) | swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp) | ||||
{ | { | ||||
u_char tag[AES_CBC_MAC_HASH_LEN]; | u_char tag[AES_CBC_MAC_HASH_LEN]; | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
swcr_ccm(struct swcr_session *ses, struct cryptop *crp) | swcr_ccm(struct swcr_session *ses, struct cryptop *crp) | ||||
{ | { | ||||
uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; | uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; | ||||
u_char *blk = (u_char *)blkbuf; | u_char *blk = (u_char *)blkbuf; | ||||
u_char tag[AES_CBC_MAC_HASH_LEN]; | u_char tag[AES_CBC_MAC_HASH_LEN]; | ||||
u_char iv[AES_BLOCK_LEN]; | |||||
struct crypto_buffer_cursor cc_in, cc_out; | struct crypto_buffer_cursor cc_in, cc_out; | ||||
const u_char *inblk; | const u_char *inblk; | ||||
u_char *outblk; | u_char *outblk; | ||||
union authctx ctx; | union authctx ctx; | ||||
struct swcr_auth *swa; | struct swcr_auth *swa; | ||||
struct swcr_encdec *swe; | struct swcr_encdec *swe; | ||||
const struct auth_hash *axf; | const struct auth_hash *axf; | ||||
const struct enc_xform *exf; | const struct enc_xform *exf; | ||||
Show All 11 Lines | swcr_ccm(struct swcr_session *ses, struct cryptop *crp) | ||||
swe = &ses->swcr_encdec; | swe = &ses->swcr_encdec; | ||||
exf = swe->sw_exf; | exf = swe->sw_exf; | ||||
KASSERT(axf->blocksize == exf->native_blocksize, | KASSERT(axf->blocksize == exf->native_blocksize, | ||||
("%s: blocksize mismatch", __func__)); | ("%s: blocksize mismatch", __func__)); | ||||
if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) | if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* Initialize the IV */ | |||||
ivlen = AES_CCM_IV_LEN; | ivlen = AES_CCM_IV_LEN; | ||||
bcopy(crp->crp_iv, iv, ivlen); | |||||
/* | /* | ||||
* AES CCM-CBC-MAC needs to know the length of both the auth | * AES CCM-CBC-MAC needs to know the length of both the auth | ||||
* data and payload data before doing the auth computation. | * 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 = crp->crp_aad_length; | ||||
ctx.aes_cbc_mac_ctx.cryptDataLength = crp->crp_payload_length; | ctx.aes_cbc_mac_ctx.cryptDataLength = crp->crp_payload_length; | ||||
/* Supply MAC with IV */ | /* Supply MAC with IV */ | ||||
axf->Reinit(&ctx, iv, ivlen); | axf->Reinit(&ctx, crp->crp_iv, ivlen); | ||||
/* Supply MAC with AAD */ | /* Supply MAC with AAD */ | ||||
if (crp->crp_aad != NULL) | if (crp->crp_aad != NULL) | ||||
error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); | error = axf->Update(&ctx, crp->crp_aad, 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, &ctx); | crp->crp_aad_length, axf->Update, &ctx); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
if (crp->crp_cipher_key != NULL) | if (crp->crp_cipher_key != NULL) | ||||
exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | ||||
crypto_get_params(crp->crp_session)->csp_cipher_klen); | crypto_get_params(crp->crp_session)->csp_cipher_klen); | ||||
exf->reinit(swe->sw_kschedule, iv, ivlen); | exf->reinit(swe->sw_kschedule, crp->crp_iv, ivlen); | ||||
/* Do encryption/decryption with MAC */ | /* Do encryption/decryption with MAC */ | ||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start); | crypto_cursor_advance(&cc_in, crp->crp_payload_start); | ||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | ||||
crypto_cursor_init(&cc_out, &crp->crp_obuf); | crypto_cursor_init(&cc_out, &crp->crp_obuf); | ||||
crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | ||||
} else | } else | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { | ||||
r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); | r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); | ||||
explicit_bzero(tag2, sizeof(tag2)); | explicit_bzero(tag2, sizeof(tag2)); | ||||
if (r != 0) { | if (r != 0) { | ||||
error = EBADMSG; | error = EBADMSG; | ||||
goto out; | goto out; | ||||
} | } | ||||
/* tag matches, decrypt data */ | /* tag matches, decrypt data */ | ||||
exf->reinit(swe->sw_kschedule, iv, ivlen); | exf->reinit(swe->sw_kschedule, crp->crp_iv, ivlen); | ||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start); | crypto_cursor_advance(&cc_in, crp->crp_payload_start); | ||||
for (resid = crp->crp_payload_length; resid > blksz; | for (resid = crp->crp_payload_length; resid > blksz; | ||||
resid -= blksz) { | resid -= blksz) { | ||||
inblk = crypto_cursor_segment(&cc_in, &len); | inblk = crypto_cursor_segment(&cc_in, &len); | ||||
if (len < blksz) { | if (len < blksz) { | ||||
crypto_cursor_copydata(&cc_in, blksz, blk); | crypto_cursor_copydata(&cc_in, blksz, blk); | ||||
inblk = blk; | inblk = blk; | ||||
Show All 16 Lines | swcr_ccm(struct swcr_session *ses, struct cryptop *crp) | ||||
} else { | } else { | ||||
/* Inject the authentication data */ | /* Inject the authentication data */ | ||||
crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); | crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); | ||||
} | } | ||||
out: | out: | ||||
explicit_bzero(blkbuf, sizeof(blkbuf)); | explicit_bzero(blkbuf, sizeof(blkbuf)); | ||||
explicit_bzero(tag, sizeof(tag)); | explicit_bzero(tag, sizeof(tag)); | ||||
explicit_bzero(iv, sizeof(iv)); | |||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
swcr_chacha20_poly1305(struct swcr_session *ses, struct cryptop *crp) | swcr_chacha20_poly1305(struct swcr_session *ses, struct cryptop *crp) | ||||
{ | { | ||||
const struct crypto_session_params *csp; | const struct crypto_session_params *csp; | ||||
uint64_t blkbuf[howmany(CHACHA20_NATIVE_BLOCK_LEN, sizeof(uint64_t))]; | uint64_t blkbuf[howmany(CHACHA20_NATIVE_BLOCK_LEN, sizeof(uint64_t))]; | ||||
▲ Show 20 Lines • Show All 836 Lines • Show Last 20 Lines |