From 5eccbc32899a5e083700fc0ee4574a4a3f86d6ff Mon Sep 17 00:00:00 2001 From: Miloslav Trmač Date: Sat, 13 Nov 2010 06:34:43 +0100 Subject: Audit type-specific crypto operations --- 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 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; -- cgit