summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-11-13 06:34:43 +0100
committerMiloslav Trmač <mitr@redhat.com>2010-11-30 14:35:42 +0100
commit5eccbc32899a5e083700fc0ee4574a4a3f86d6ff (patch)
tree4949289bb7b5926e7053fdf0d27f829577b0e9ec
parent1bc0a1995676135832764fe7447d46437d44cbf5 (diff)
downloadkernel-crypto-audit.tar.gz
kernel-crypto-audit.tar.xz
kernel-crypto-audit.zip
Audit type-specific crypto operationsaudit
-rw-r--r--crypto/af_alg.c14
-rw-r--r--crypto/algif_hash.c27
-rw-r--r--crypto/algif_skcipher.c20
-rw-r--r--include/crypto/if_alg.h6
4 files changed, 61 insertions, 6 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index fc1b0f70ce5..450d51abe84 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 3a61e9dbaa7..7e3ffd16e0a 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 0776fe157b2..1d8fb210449 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -286,6 +286,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;
+
while (size) {
struct scatterlist *sg;
unsigned long len = size;
@@ -376,8 +381,14 @@ 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;
+
+ 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;
@@ -427,10 +438,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 092c599e031..6650ae5761f 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;