Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/cryptosoft.c
Show First 20 Lines • Show All 329 Lines • ▼ Show 20 Lines | swcr_authcompute(struct swcr_session *ses, struct cryptop *crp) | ||||
if (crp->crp_auth_key != NULL) { | if (crp->crp_auth_key != NULL) { | ||||
csp = crypto_get_params(crp->crp_session); | csp = crypto_get_params(crp->crp_session); | ||||
swcr_authprepare(axf, sw, crp->crp_auth_key, | swcr_authprepare(axf, sw, crp->crp_auth_key, | ||||
csp->csp_auth_klen); | csp->csp_auth_klen); | ||||
} | } | ||||
bcopy(sw->sw_ictx, &ctx, axf->ctxsize); | bcopy(sw->sw_ictx, &ctx, axf->ctxsize); | ||||
if (crp->crp_aad != NULL) | |||||
err = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); | |||||
else | |||||
err = crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length, | err = crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length, | ||||
axf->Update, &ctx); | axf->Update, &ctx); | ||||
if (err) | if (err) | ||||
return err; | return err; | ||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp) && | if (CRYPTO_HAS_OUTPUT_BUFFER(crp) && | ||||
CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) | CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) | ||||
err = crypto_apply_buf(&crp->crp_obuf, | err = crypto_apply_buf(&crp->crp_obuf, | ||||
crp->crp_payload_output_start, crp->crp_payload_length, | crp->crp_payload_output_start, crp->crp_payload_length, | ||||
axf->Update, &ctx); | axf->Update, &ctx); | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | swcr_gcm(struct swcr_session *ses, struct cryptop *crp) | ||||
swa = &ses->swcr_auth; | swa = &ses->swcr_auth; | ||||
axf = swa->sw_axf; | axf = swa->sw_axf; | ||||
bcopy(swa->sw_ictx, &ctx, axf->ctxsize); | bcopy(swa->sw_ictx, &ctx, axf->ctxsize); | ||||
blksz = GMAC_BLOCK_LEN; | blksz = GMAC_BLOCK_LEN; | ||||
KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch", | KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch", | ||||
__func__)); | __func__)); | ||||
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 */ | /* Initialize the IV */ | ||||
ivlen = AES_GCM_IV_LEN; | ivlen = AES_GCM_IV_LEN; | ||||
bcopy(crp->crp_iv, iv, ivlen); | bcopy(crp->crp_iv, iv, ivlen); | ||||
/* Supply MAC with IV */ | /* Supply MAC with IV */ | ||||
axf->Reinit(&ctx, iv, ivlen); | axf->Reinit(&ctx, iv, ivlen); | ||||
/* Supply MAC with AAD */ | /* Supply MAC with AAD */ | ||||
if (crp->crp_aad != NULL) { | |||||
len = rounddown(crp->crp_aad_length, blksz); | |||||
if (len != 0) | |||||
axf->Update(&ctx, crp->crp_aad, len); | |||||
if (crp->crp_aad_length != len) { | |||||
memset(blk, 0, blksz); | |||||
memcpy(blk, (char *)crp->crp_aad + len, | |||||
crp->crp_aad_length - len); | |||||
axf->Update(&ctx, blk, blksz); | |||||
} | |||||
} else { | |||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_aad_start); | crypto_cursor_advance(&cc_in, crp->crp_aad_start); | ||||
for (resid = crp->crp_aad_length; resid >= blksz; resid -= len) { | for (resid = crp->crp_aad_length; resid >= blksz; | ||||
resid -= len) { | |||||
len = crypto_cursor_seglen(&cc_in); | len = crypto_cursor_seglen(&cc_in); | ||||
if (len >= blksz) { | if (len >= blksz) { | ||||
inblk = crypto_cursor_segbase(&cc_in); | inblk = crypto_cursor_segbase(&cc_in); | ||||
len = rounddown(MIN(len, resid), blksz); | len = rounddown(MIN(len, resid), blksz); | ||||
crypto_cursor_advance(&cc_in, len); | crypto_cursor_advance(&cc_in, len); | ||||
} else { | } else { | ||||
len = blksz; | len = blksz; | ||||
crypto_cursor_copydata(&cc_in, len, blk); | crypto_cursor_copydata(&cc_in, len, blk); | ||||
inblk = blk; | inblk = blk; | ||||
} | } | ||||
axf->Update(&ctx, inblk, len); | axf->Update(&ctx, inblk, len); | ||||
} | } | ||||
if (resid > 0) { | if (resid > 0) { | ||||
memset(blk, 0, blksz); | memset(blk, 0, blksz); | ||||
crypto_cursor_copydata(&cc_in, resid, blk); | crypto_cursor_copydata(&cc_in, resid, blk); | ||||
axf->Update(&ctx, blk, blksz); | axf->Update(&ctx, blk, blksz); | ||||
} | } | ||||
} | |||||
exf->reinit(swe->sw_kschedule, iv); | exf->reinit(swe->sw_kschedule, iv); | ||||
/* 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); | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { | ||||
crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2); | crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2); | ||||
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 */ | ||||
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) { | ||||
if (crypto_cursor_seglen(&cc_in) < blksz) { | if (crypto_cursor_seglen(&cc_in) < blksz) { | ||||
crypto_cursor_copydata(&cc_in, blksz, blk); | crypto_cursor_copydata(&cc_in, blksz, blk); | ||||
inblk = blk; | inblk = blk; | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp) | ||||
/* | /* | ||||
* 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_payload_length; | ctx.aes_cbc_mac_ctx.authDataLength = crp->crp_payload_length; | ||||
ctx.aes_cbc_mac_ctx.cryptDataLength = 0; | ctx.aes_cbc_mac_ctx.cryptDataLength = 0; | ||||
axf->Reinit(&ctx, iv, ivlen); | axf->Reinit(&ctx, iv, ivlen); | ||||
if (crp->crp_aad != NULL) | |||||
error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); | |||||
else | |||||
error = crypto_apply(crp, crp->crp_payload_start, | error = crypto_apply(crp, crp->crp_payload_start, | ||||
crp->crp_payload_length, axf->Update, &ctx); | crp->crp_payload_length, axf->Update, &ctx); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
/* Finalize MAC */ | /* Finalize MAC */ | ||||
axf->Final(tag, &ctx); | axf->Final(tag, &ctx); | ||||
if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { | if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { | ||||
u_char tag2[AES_CBC_MAC_HASH_LEN]; | u_char tag2[AES_CBC_MAC_HASH_LEN]; | ||||
Show All 31 Lines | swcr_ccm(struct swcr_session *ses, struct cryptop *crp) | ||||
swa = &ses->swcr_auth; | swa = &ses->swcr_auth; | ||||
axf = swa->sw_axf; | axf = swa->sw_axf; | ||||
bcopy(swa->sw_ictx, &ctx, axf->ctxsize); | bcopy(swa->sw_ictx, &ctx, axf->ctxsize); | ||||
blksz = AES_BLOCK_LEN; | blksz = AES_BLOCK_LEN; | ||||
KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch", | KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch", | ||||
__func__)); | __func__)); | ||||
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 */ | /* Initialize the IV */ | ||||
ivlen = AES_CCM_IV_LEN; | ivlen = AES_CCM_IV_LEN; | ||||
bcopy(crp->crp_iv, iv, ivlen); | 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, iv, ivlen); | ||||
/* Supply MAC with AAD */ | /* Supply MAC with AAD */ | ||||
error = crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length, | if (crp->crp_aad != NULL) | ||||
axf->Update, &ctx); | error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); | ||||
else | |||||
error = crypto_apply(crp, crp->crp_aad_start, | |||||
crp->crp_aad_length, axf->Update, &ctx); | |||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
exf->reinit(swe->sw_kschedule, iv); | exf->reinit(swe->sw_kschedule, iv); | ||||
/* 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); | ||||
▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (csp->csp_auth_mlen == 0) | if (csp->csp_auth_mlen == 0) | ||||
swa->sw_mlen = axf->hashsize; | swa->sw_mlen = axf->hashsize; | ||||
else | else | ||||
swa->sw_mlen = csp->csp_auth_mlen; | swa->sw_mlen = csp->csp_auth_mlen; | ||||
swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); | swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); | ||||
if (swa->sw_ictx == NULL) | if (swa->sw_ictx == NULL) | ||||
return (ENOBUFS); | return (ENOBUFS); | ||||
switch (csp->csp_auth_alg) { | switch (csp->csp_auth_alg) { | ||||
case CRYPTO_SHA1_HMAC: | case CRYPTO_SHA1_HMAC: | ||||
case CRYPTO_SHA2_224_HMAC: | case CRYPTO_SHA2_224_HMAC: | ||||
case CRYPTO_SHA2_256_HMAC: | case CRYPTO_SHA2_256_HMAC: | ||||
case CRYPTO_SHA2_384_HMAC: | case CRYPTO_SHA2_384_HMAC: | ||||
case CRYPTO_SHA2_512_HMAC: | case CRYPTO_SHA2_512_HMAC: | ||||
case CRYPTO_NULL_HMAC: | case CRYPTO_NULL_HMAC: | ||||
case CRYPTO_RIPEMD160_HMAC: | case CRYPTO_RIPEMD160_HMAC: | ||||
▲ Show 20 Lines • Show All 206 Lines • ▼ Show 20 Lines | if (csp->csp_cipher_alg != CRYPTO_NULL_CBC && | ||||
return (false); | return (false); | ||||
return (true); | return (true); | ||||
} | } | ||||
static int | static int | ||||
swcr_probesession(device_t dev, const struct crypto_session_params *csp) | swcr_probesession(device_t dev, const struct crypto_session_params *csp) | ||||
{ | { | ||||
if ((csp->csp_flags & ~(CSP_F_SEPARATE_OUTPUT)) != 0) | if ((csp->csp_flags & ~(CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD)) != | ||||
0) | |||||
return (EINVAL); | return (EINVAL); | ||||
switch (csp->csp_mode) { | switch (csp->csp_mode) { | ||||
case CSP_MODE_COMPRESS: | case CSP_MODE_COMPRESS: | ||||
switch (csp->csp_cipher_alg) { | switch (csp->csp_cipher_alg) { | ||||
case CRYPTO_DEFLATE_COMP: | case CRYPTO_DEFLATE_COMP: | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
▲ Show 20 Lines • Show All 271 Lines • Show Last 20 Lines |