[PATCH 5/5] Audit type-specific crypto operations

Miloslav Trmač mitr at redhat.com
Wed Nov 24 17:05:55 UTC 2010


Signed-off-by: Miloslav Trmač <mitr at redhat.com>
---
 crypto/af_alg.c         |   14 ++++++++++++++
 crypto/algif_hash.c     |   27 +++++++++++++++++++++++----
 crypto/algif_skcipher.c |   20 ++++++++++++++++++--
 include/crypto/if_alg.h |    6 ++++++
 4 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index fc1b0f7..450d51a 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -542,6 +542,20 @@ void af_alg_complete(struct crypto_async_request *req, int err)
 }
 EXPORT_SYMBOL_GPL(af_alg_complete);
 
+#ifdef CONFIG_AUDIT
+int af_alg_audit_crypto_op(struct sock *sk, const char *operation, int ctx2)
+{
+	struct alg_sock *ask = alg_sk(sk);
+	struct alg_sock *parent_ask = alg_sk(ask->parent);
+	const char *alg_name;
+
+	alg_name = parent_ask->type->alg_name(parent_ask->private);
+	return audit_log_crypto_op(AUDIT_CRYPTO_OP_CTX_OP, parent_ask->id,
+				   ask->id, ctx2, alg_name, operation);
+}
+EXPORT_SYMBOL_GPL(af_alg_audit_crypto_op);
+#endif
+
 static int __init af_alg_init(void)
 {
 	int err = proto_register(&alg_proto, 0);
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index 3a61e9d..7e3ffd1 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -46,6 +46,10 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock,
 	long copied = 0;
 	int err;
 
+	err = af_alg_audit_crypto_op(sk, "hash-input", -1);
+	if (err)
+		return err;
+
 	if (limit > sk->sk_sndbuf)
 		limit = sk->sk_sndbuf;
 
@@ -112,6 +116,10 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
 	struct hash_ctx *ctx = ask->private;
 	int err;
 
+	err = af_alg_audit_crypto_op(sk, "hash-input", -1);
+	if (err)
+		return err;
+
 	lock_sock(sk);
 	sg_init_table(ctx->sgl.sg, 1);
 	sg_set_page(ctx->sgl.sg, page, size, offset);
@@ -154,6 +162,10 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
 	unsigned ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req));
 	int err;
 
+	err = af_alg_audit_crypto_op(sk, "hash-output", -1);
+	if (err)
+		return err;
+
 	if (len > ds)
 		len = ds;
 	else if (len < ds)
@@ -202,12 +214,19 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags)
 	ctx2 = ask2->private;
 	ctx2->more = 1;
 
+	err = af_alg_audit_crypto_op(sk, "hash-clone", ask2->id);
+	if (err)
+		goto error_sk2;
+
 	err = crypto_ahash_import(&ctx2->req, state);
-	if (err) {
-		sock_orphan(sk2);
-		sock_put(sk2);
-	}
+	if (err)
+		goto error_sk2;
+
+	return err;
 
+error_sk2:
+	sock_orphan(sk2);
+	sock_put(sk2);
 	return err;
 }
 
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index e14c8be..c5c37d6 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -283,6 +283,11 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock,
 			memcpy(ctx->iv, con.iv->iv, ivsize);
 	}
 
+	err = af_alg_audit_crypto_op(sk, ctx->enc ? "encrypt-input"
+				     : "decrypt-input", -1);
+	if (err)
+		goto unlock;
+
 	limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE);
 	limit -= ctx->used;
 
@@ -381,9 +386,15 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page,
 	struct alg_sock *ask = alg_sk(sk);
 	struct skcipher_ctx *ctx = ask->private;
 	struct skcipher_sg_list *sgl;
-	int err = -EINVAL;
+	int err;
 	int limit;
 
+	err = af_alg_audit_crypto_op(sk, ctx->enc ? "encrypt-input"
+				     : "decrypt-input", -1);
+	if (err)
+		return err;
+
+	err = -EINVAL;
 	lock_sock(sk);
 	if (!ctx->more && ctx->used)
 		goto unlock;
@@ -439,10 +450,15 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
 	struct scatterlist *sg;
 	unsigned long iovlen;
 	struct iovec *iov;
-	int err = -EAGAIN;
+	int err;
 	int used;
 	long copied = 0;
 
+	err = af_alg_audit_crypto_op(sk, ctx->enc ? "encrypt-output"
+				     : "decrypt-output", -1);
+	if (err)
+		return err;
+
 	lock_sock(sk);
 	for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
 	     iovlen--, iov++) {
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 092c599..6650ae5 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -80,6 +80,12 @@ int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con);
 int af_alg_wait_for_completion(int err, struct af_alg_completion *completion);
 void af_alg_complete(struct crypto_async_request *req, int err);
 
+#ifdef CONFIG_AUDIT
+int af_alg_audit_crypto_op(struct sock *sk, const char *operation, int ctx2);
+#else
+#define af_alg_audit_crypto_op(sk, operation, ctx2) (0)
+#endif
+
 static inline struct alg_sock *alg_sk(struct sock *sk)
 {
 	return (struct alg_sock *)sk;
-- 
1.7.3.2




More information about the Linux-audit mailing list