mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:38:03 +00:00
SUNRPC: Use a static buffer for the checksum initialization vector
Allocating and zeroing a buffer during every call to krb5_etm_checksum() is inefficient. Instead, set aside a static buffer that is the maximum crypto block size, and use a portion (or all) of that. Reported-by: Markus Elfring <Markus.Elfring@web.de> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
3cfcfc102a
commit
561141dd49
@ -921,6 +921,8 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len,
|
|||||||
* Caller provides the truncation length of the output token (h) in
|
* Caller provides the truncation length of the output token (h) in
|
||||||
* cksumout.len.
|
* cksumout.len.
|
||||||
*
|
*
|
||||||
|
* Note that for RPCSEC, the "initial cipher state" is always all zeroes.
|
||||||
|
*
|
||||||
* Return values:
|
* Return values:
|
||||||
* %GSS_S_COMPLETE: Digest computed, @cksumout filled in
|
* %GSS_S_COMPLETE: Digest computed, @cksumout filled in
|
||||||
* %GSS_S_FAILURE: Call failed
|
* %GSS_S_FAILURE: Call failed
|
||||||
@ -931,22 +933,19 @@ u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher,
|
|||||||
int body_offset, struct xdr_netobj *cksumout)
|
int body_offset, struct xdr_netobj *cksumout)
|
||||||
{
|
{
|
||||||
unsigned int ivsize = crypto_sync_skcipher_ivsize(cipher);
|
unsigned int ivsize = crypto_sync_skcipher_ivsize(cipher);
|
||||||
|
static const u8 iv[GSS_KRB5_MAX_BLOCKSIZE];
|
||||||
struct ahash_request *req;
|
struct ahash_request *req;
|
||||||
struct scatterlist sg[1];
|
struct scatterlist sg[1];
|
||||||
u8 *iv, *checksumdata;
|
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
|
u8 *checksumdata;
|
||||||
|
|
||||||
checksumdata = kmalloc(crypto_ahash_digestsize(tfm), GFP_KERNEL);
|
checksumdata = kmalloc(crypto_ahash_digestsize(tfm), GFP_KERNEL);
|
||||||
if (!checksumdata)
|
if (!checksumdata)
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
/* For RPCSEC, the "initial cipher state" is always all zeroes. */
|
|
||||||
iv = kzalloc(ivsize, GFP_KERNEL);
|
|
||||||
if (!iv)
|
|
||||||
goto out_free_mem;
|
|
||||||
|
|
||||||
req = ahash_request_alloc(tfm, GFP_KERNEL);
|
req = ahash_request_alloc(tfm, GFP_KERNEL);
|
||||||
if (!req)
|
if (!req)
|
||||||
goto out_free_mem;
|
goto out_free_cksumdata;
|
||||||
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
|
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
|
||||||
err = crypto_ahash_init(req);
|
err = crypto_ahash_init(req);
|
||||||
if (err)
|
if (err)
|
||||||
@ -970,8 +969,7 @@ u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher,
|
|||||||
|
|
||||||
out_free_ahash:
|
out_free_ahash:
|
||||||
ahash_request_free(req);
|
ahash_request_free(req);
|
||||||
out_free_mem:
|
out_free_cksumdata:
|
||||||
kfree(iv);
|
|
||||||
kfree_sensitive(checksumdata);
|
kfree_sensitive(checksumdata);
|
||||||
return err ? GSS_S_FAILURE : GSS_S_COMPLETE;
|
return err ? GSS_S_FAILURE : GSS_S_COMPLETE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user