Commit 9f0b49f9 authored by Chuck Lever's avatar Chuck Lever
Browse files

SUNRPC: Obscure Kerberos encryption keys



The encryption subkeys are not used after the cipher transforms have
been allocated and keyed. There is no need to retain them in struct
krb5_ctx.

Tested-by: default avatarScott Mayhew <smayhew@redhat.com>
Reviewed-by: default avatarSimo Sorce <simo@redhat.com>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 7989a4f4
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -110,8 +110,6 @@ struct krb5_ctx {
	struct xdr_netobj	mech_used;
	u8			initiator_sign[GSS_KRB5_MAX_KEYLEN];
	u8			acceptor_sign[GSS_KRB5_MAX_KEYLEN];
	u8			initiator_seal[GSS_KRB5_MAX_KEYLEN];
	u8			acceptor_seal[GSS_KRB5_MAX_KEYLEN];
	u8			initiator_integ[GSS_KRB5_MAX_KEYLEN];
	u8			acceptor_integ[GSS_KRB5_MAX_KEYLEN];
};
+26 −17
Original line number Diff line number Diff line
@@ -350,42 +350,49 @@ context_derive_keys_des3(struct krb5_ctx *ctx, gfp_t gfp_mask)
static int
context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask)
{
	struct xdr_netobj c, keyin, keyout;
	u8 cdata[GSS_KRB5_K5CLENGTH];
	struct xdr_netobj c = {
		.len	= sizeof(cdata),
		.data	= cdata,
	};
	struct xdr_netobj keyin = {
		.len	= ctx->gk5e->keylength,
		.data	= ctx->Ksess,
	};
	struct xdr_netobj keyout;
	int ret = -EINVAL;
	void *subkey;
	u32 err;

	c.len = GSS_KRB5_K5CLENGTH;
	c.data = cdata;

	keyin.data = ctx->Ksess;
	keyin.len = ctx->gk5e->keylength;
	subkey = kmalloc(ctx->gk5e->keylength, gfp_mask);
	if (!subkey)
		return -ENOMEM;
	keyout.len = ctx->gk5e->keylength;
	keyout.data = subkey;

	/* initiator seal encryption */
	set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION);
	keyout.data = ctx->initiator_seal;
	err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
	if (err) {
		dprintk("%s: Error %d deriving initiator_seal key\n",
			__func__, err);
		goto out_err;
		goto out;
	}
	ctx->initiator_enc = context_v2_alloc_cipher(ctx,
						     ctx->gk5e->encrypt_name,
						     ctx->initiator_seal);
						     subkey);
	if (ctx->initiator_enc == NULL)
		goto out_err;
		goto out;
	if (ctx->gk5e->aux_cipher) {
		ctx->initiator_enc_aux =
			context_v2_alloc_cipher(ctx, ctx->gk5e->aux_cipher,
						ctx->initiator_seal);
						subkey);
		if (ctx->initiator_enc_aux == NULL)
			goto out_free;
	}

	/* acceptor seal encryption */
	set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION);
	keyout.data = ctx->acceptor_seal;
	err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
	if (err) {
		dprintk("%s: Error %d deriving acceptor_seal key\n",
@@ -394,13 +401,13 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask)
	}
	ctx->acceptor_enc = context_v2_alloc_cipher(ctx,
						    ctx->gk5e->encrypt_name,
						    ctx->acceptor_seal);
						    subkey);
	if (ctx->acceptor_enc == NULL)
		goto out_free;
	if (ctx->gk5e->aux_cipher) {
		ctx->acceptor_enc_aux =
			context_v2_alloc_cipher(ctx, ctx->gk5e->aux_cipher,
						ctx->acceptor_seal);
						subkey);
		if (ctx->acceptor_enc_aux == NULL)
			goto out_free;
	}
@@ -445,15 +452,17 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask)
		goto out_free;
	}

	return 0;
	ret = 0;
out:
	kfree_sensitive(subkey);
	return ret;

out_free:
	crypto_free_sync_skcipher(ctx->acceptor_enc_aux);
	crypto_free_sync_skcipher(ctx->acceptor_enc);
	crypto_free_sync_skcipher(ctx->initiator_enc_aux);
	crypto_free_sync_skcipher(ctx->initiator_enc);
out_err:
	return -EINVAL;
	goto out;
}

static int