Commit 561141dd authored by Chuck Lever's avatar Chuck Lever
Browse files

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: default avatarMarkus Elfring <Markus.Elfring@web.de>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 3cfcfc10
Loading
Loading
Loading
Loading
+6 −8
Original line number Diff line number Diff line
@@ -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
 * cksumout.len.
 *
 * Note that for RPCSEC, the "initial cipher state" is always all zeroes.
 *
 * Return values:
 *   %GSS_S_COMPLETE: Digest computed, @cksumout filled in
 *   %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)
{
	unsigned int ivsize = crypto_sync_skcipher_ivsize(cipher);
	static const u8 iv[GSS_KRB5_MAX_BLOCKSIZE];
	struct ahash_request *req;
	struct scatterlist sg[1];
	u8 *iv, *checksumdata;
	int err = -ENOMEM;
	u8 *checksumdata;

	checksumdata = kmalloc(crypto_ahash_digestsize(tfm), GFP_KERNEL);
	if (!checksumdata)
		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);
	if (!req)
		goto out_free_mem;
		goto out_free_cksumdata;
	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
	err = crypto_ahash_init(req);
	if (err)
@@ -970,8 +969,7 @@ u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher,

out_free_ahash:
	ahash_request_free(req);
out_free_mem:
	kfree(iv);
out_free_cksumdata:
	kfree_sensitive(checksumdata);
	return err ? GSS_S_FAILURE : GSS_S_COMPLETE;
}