Change return types of hash update functions in SHA-NI
r359374 introduced crypto_apply function which takes as argument a function pointer that is expected to return an int, however aesni hash update functions return void. Because of that the function pointer passed was simply cast with its return value changed. This resulted in undefined behavior, in particular when mbuf is used, (ipsec) m_apply checks return value of function pointer passed to it and in our case bogusly fails after calculating hash of the first mbuf in chain. Fix it by changing signatures of sha update routines in aesni and dropping the casts. Submitted by: Kornel Duleba Reviewed by: jhb, cem Obtained from: Semihalf Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D25030
This commit is contained in:
parent
4ac6682cab
commit
ccbaa67d8b
@ -386,8 +386,8 @@ DRIVER_MODULE(aesni, nexus, aesni_driver, aesni_devclass, 0, 0);
|
||||
MODULE_VERSION(aesni, 1);
|
||||
MODULE_DEPEND(aesni, crypto, 1, 1, 1);
|
||||
|
||||
static void
|
||||
intel_sha1_update(void *vctx, const void *vdata, u_int datalen)
|
||||
static int
|
||||
intel_sha1_update(void *vctx, void *vdata, u_int datalen)
|
||||
{
|
||||
struct sha1_ctxt *ctx = vctx;
|
||||
const char *data = vdata;
|
||||
@ -419,6 +419,8 @@ intel_sha1_update(void *vctx, const void *vdata, u_int datalen)
|
||||
intel_sha1_step(ctx->h.b32, (void *)ctx->m.b8, 1);
|
||||
off += copysiz;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -433,8 +435,8 @@ SHA1_Finalize_fn(void *digest, void *ctx)
|
||||
sha1_result(ctx, digest);
|
||||
}
|
||||
|
||||
static void
|
||||
intel_sha256_update(void *vctx, const void *vdata, u_int len)
|
||||
static int
|
||||
intel_sha256_update(void *vctx, void *vdata, u_int len)
|
||||
{
|
||||
SHA256_CTX *ctx = vctx;
|
||||
uint64_t bitlen;
|
||||
@ -454,7 +456,7 @@ intel_sha256_update(void *vctx, const void *vdata, u_int len)
|
||||
/* Handle the case where we don't need to perform any transforms */
|
||||
if (len < 64 - r) {
|
||||
memcpy(&ctx->buf[r], src, len);
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Finish the current block */
|
||||
@ -473,6 +475,8 @@ intel_sha256_update(void *vctx, const void *vdata, u_int len)
|
||||
|
||||
/* Copy left over data into buffer */
|
||||
memcpy(ctx->buf, src, len);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -844,20 +848,16 @@ aesni_cipher_mac(struct aesni_session *ses, struct cryptop *crp,
|
||||
ses->hash_update(&sctx, hmac_key, sizeof(hmac_key));
|
||||
|
||||
crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length,
|
||||
__DECONST(int (*)(void *, void *, u_int), ses->hash_update),
|
||||
&sctx);
|
||||
ses->hash_update, &sctx);
|
||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp) &&
|
||||
CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
|
||||
crypto_apply_buf(&crp->crp_obuf,
|
||||
crp->crp_payload_output_start,
|
||||
crp->crp_payload_length,
|
||||
__DECONST(int (*)(void *, void *, u_int),
|
||||
ses->hash_update), &sctx);
|
||||
ses->hash_update, &sctx);
|
||||
else
|
||||
crypto_apply(crp, crp->crp_payload_start,
|
||||
crp->crp_payload_length,
|
||||
__DECONST(int (*)(void *, void *, u_int),
|
||||
ses->hash_update), &sctx);
|
||||
crp->crp_payload_length, ses->hash_update, &sctx);
|
||||
ses->hash_finalize(res, &sctx);
|
||||
|
||||
/* Outer hash: (K ^ OPAD) || inner hash */
|
||||
@ -873,20 +873,17 @@ aesni_cipher_mac(struct aesni_session *ses, struct cryptop *crp,
|
||||
ses->hash_init(&sctx);
|
||||
|
||||
crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length,
|
||||
__DECONST(int (*)(void *, void *, u_int), ses->hash_update),
|
||||
&sctx);
|
||||
ses->hash_update, &sctx);
|
||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp) &&
|
||||
CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
|
||||
crypto_apply_buf(&crp->crp_obuf,
|
||||
crp->crp_payload_output_start,
|
||||
crp->crp_payload_length,
|
||||
__DECONST(int (*)(void *, void *, u_int),
|
||||
ses->hash_update), &sctx);
|
||||
ses->hash_update, &sctx);
|
||||
else
|
||||
crypto_apply(crp, crp->crp_payload_start,
|
||||
crp->crp_payload_length,
|
||||
__DECONST(int (*)(void *, void *, u_int),
|
||||
ses->hash_update), &sctx);
|
||||
ses->hash_update, &sctx);
|
||||
|
||||
ses->hash_finalize(res, &sctx);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ struct aesni_session {
|
||||
int mlen;
|
||||
int hash_len;
|
||||
void (*hash_init)(void *);
|
||||
void (*hash_update)(void *, const void *, unsigned);
|
||||
int (*hash_update)(void *, void *, unsigned);
|
||||
void (*hash_finalize)(void *, void *);
|
||||
bool hmac;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user