summaryrefslogtreecommitdiff
path: root/include/crypto
diff options
context:
space:
mode:
authorCorentin Labbe <clabbe@baylibre.com>2018-09-19 10:10:54 +0000
committerHerbert Xu <herbert@gondor.apana.org.au>2018-09-28 12:46:25 +0800
commitcac5818c25d0423bda73e2b6997404ed0a7ed9e3 (patch)
tree3a443fa0e9a8e96799e2802552cd1f6435213569 /include/crypto
parenta9cbfe4c784436368790f0c59674f99ba97ae21e (diff)
downloadlwn-cac5818c25d0423bda73e2b6997404ed0a7ed9e3.tar.gz
lwn-cac5818c25d0423bda73e2b6997404ed0a7ed9e3.zip
crypto: user - Implement a generic crypto statistics
This patch implement a generic way to get statistics about all crypto usages. Signed-off-by: Corentin Labbe <clabbe@baylibre.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'include/crypto')
-rw-r--r--include/crypto/acompress.h38
-rw-r--r--include/crypto/aead.h51
-rw-r--r--include/crypto/akcipher.h76
-rw-r--r--include/crypto/hash.h32
-rw-r--r--include/crypto/internal/cryptouser.h8
-rw-r--r--include/crypto/kpp.h51
-rw-r--r--include/crypto/rng.h29
-rw-r--r--include/crypto/skcipher.h44
8 files changed, 303 insertions, 26 deletions
diff --git a/include/crypto/acompress.h b/include/crypto/acompress.h
index e328b52425a8..22e6f412c595 100644
--- a/include/crypto/acompress.h
+++ b/include/crypto/acompress.h
@@ -234,6 +234,34 @@ static inline void acomp_request_set_params(struct acomp_req *req,
req->flags |= CRYPTO_ACOMP_ALLOC_OUTPUT;
}
+static inline void crypto_stat_compress(struct acomp_req *req, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&tfm->base.__crt_alg->compress_err_cnt);
+ } else {
+ atomic_inc(&tfm->base.__crt_alg->compress_cnt);
+ atomic64_add(req->slen, &tfm->base.__crt_alg->compress_tlen);
+ }
+#endif
+}
+
+static inline void crypto_stat_decompress(struct acomp_req *req, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&tfm->base.__crt_alg->compress_err_cnt);
+ } else {
+ atomic_inc(&tfm->base.__crt_alg->decompress_cnt);
+ atomic64_add(req->slen, &tfm->base.__crt_alg->decompress_tlen);
+ }
+#endif
+}
+
/**
* crypto_acomp_compress() -- Invoke asynchronous compress operation
*
@@ -246,8 +274,11 @@ static inline void acomp_request_set_params(struct acomp_req *req,
static inline int crypto_acomp_compress(struct acomp_req *req)
{
struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+ int ret;
- return tfm->compress(req);
+ ret = tfm->compress(req);
+ crypto_stat_compress(req, ret);
+ return ret;
}
/**
@@ -262,8 +293,11 @@ static inline int crypto_acomp_compress(struct acomp_req *req)
static inline int crypto_acomp_decompress(struct acomp_req *req)
{
struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+ int ret;
- return tfm->decompress(req);
+ ret = tfm->decompress(req);
+ crypto_stat_decompress(req, ret);
+ return ret;
}
#endif
diff --git a/include/crypto/aead.h b/include/crypto/aead.h
index 1e26f790b03f..0d765d7bfb82 100644
--- a/include/crypto/aead.h
+++ b/include/crypto/aead.h
@@ -306,6 +306,34 @@ static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req)
return __crypto_aead_cast(req->base.tfm);
}
+static inline void crypto_stat_aead_encrypt(struct aead_request *req, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&tfm->base.__crt_alg->aead_err_cnt);
+ } else {
+ atomic_inc(&tfm->base.__crt_alg->encrypt_cnt);
+ atomic64_add(req->cryptlen, &tfm->base.__crt_alg->encrypt_tlen);
+ }
+#endif
+}
+
+static inline void crypto_stat_aead_decrypt(struct aead_request *req, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&tfm->base.__crt_alg->aead_err_cnt);
+ } else {
+ atomic_inc(&tfm->base.__crt_alg->decrypt_cnt);
+ atomic64_add(req->cryptlen, &tfm->base.__crt_alg->decrypt_tlen);
+ }
+#endif
+}
+
/**
* crypto_aead_encrypt() - encrypt plaintext
* @req: reference to the aead_request handle that holds all information
@@ -328,11 +356,14 @@ static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req)
static inline int crypto_aead_encrypt(struct aead_request *req)
{
struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ int ret;
if (crypto_aead_get_flags(aead) & CRYPTO_TFM_NEED_KEY)
- return -ENOKEY;
-
- return crypto_aead_alg(aead)->encrypt(req);
+ ret = -ENOKEY;
+ else
+ ret = crypto_aead_alg(aead)->encrypt(req);
+ crypto_stat_aead_encrypt(req, ret);
+ return ret;
}
/**
@@ -360,14 +391,16 @@ static inline int crypto_aead_encrypt(struct aead_request *req)
static inline int crypto_aead_decrypt(struct aead_request *req)
{
struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ int ret;
if (crypto_aead_get_flags(aead) & CRYPTO_TFM_NEED_KEY)
- return -ENOKEY;
-
- if (req->cryptlen < crypto_aead_authsize(aead))
- return -EINVAL;
-
- return crypto_aead_alg(aead)->decrypt(req);
+ ret = -ENOKEY;
+ else if (req->cryptlen < crypto_aead_authsize(aead))
+ ret = -EINVAL;
+ else
+ ret = crypto_aead_alg(aead)->decrypt(req);
+ crypto_stat_aead_decrypt(req, ret);
+ return ret;
}
/**
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index b5e11de4d497..afac71119396 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -271,6 +271,62 @@ static inline unsigned int crypto_akcipher_maxsize(struct crypto_akcipher *tfm)
return alg->max_size(tfm);
}
+static inline void crypto_stat_akcipher_encrypt(struct akcipher_request *req,
+ int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&tfm->base.__crt_alg->akcipher_err_cnt);
+ } else {
+ atomic_inc(&tfm->base.__crt_alg->encrypt_cnt);
+ atomic64_add(req->src_len, &tfm->base.__crt_alg->encrypt_tlen);
+ }
+#endif
+}
+
+static inline void crypto_stat_akcipher_decrypt(struct akcipher_request *req,
+ int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&tfm->base.__crt_alg->akcipher_err_cnt);
+ } else {
+ atomic_inc(&tfm->base.__crt_alg->decrypt_cnt);
+ atomic64_add(req->src_len, &tfm->base.__crt_alg->decrypt_tlen);
+ }
+#endif
+}
+
+static inline void crypto_stat_akcipher_sign(struct akcipher_request *req,
+ int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY)
+ atomic_inc(&tfm->base.__crt_alg->akcipher_err_cnt);
+ else
+ atomic_inc(&tfm->base.__crt_alg->sign_cnt);
+#endif
+}
+
+static inline void crypto_stat_akcipher_verify(struct akcipher_request *req,
+ int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY)
+ atomic_inc(&tfm->base.__crt_alg->akcipher_err_cnt);
+ else
+ atomic_inc(&tfm->base.__crt_alg->verify_cnt);
+#endif
+}
+
/**
* crypto_akcipher_encrypt() - Invoke public key encrypt operation
*
@@ -285,8 +341,11 @@ static inline int crypto_akcipher_encrypt(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+ int ret;
- return alg->encrypt(req);
+ ret = alg->encrypt(req);
+ crypto_stat_akcipher_encrypt(req, ret);
+ return ret;
}
/**
@@ -303,8 +362,11 @@ static inline int crypto_akcipher_decrypt(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+ int ret;
- return alg->decrypt(req);
+ ret = alg->decrypt(req);
+ crypto_stat_akcipher_decrypt(req, ret);
+ return ret;
}
/**
@@ -321,8 +383,11 @@ static inline int crypto_akcipher_sign(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+ int ret;
- return alg->sign(req);
+ ret = alg->sign(req);
+ crypto_stat_akcipher_sign(req, ret);
+ return ret;
}
/**
@@ -339,8 +404,11 @@ static inline int crypto_akcipher_verify(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+ int ret;
- return alg->verify(req);
+ ret = alg->verify(req);
+ crypto_stat_akcipher_verify(req, ret);
+ return ret;
}
/**
diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index 21587011ab0f..bc7796600338 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -412,6 +412,32 @@ static inline void *ahash_request_ctx(struct ahash_request *req)
int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen);
+static inline void crypto_stat_ahash_update(struct ahash_request *req, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY)
+ atomic_inc(&tfm->base.__crt_alg->hash_err_cnt);
+ else
+ atomic64_add(req->nbytes, &tfm->base.__crt_alg->hash_tlen);
+#endif
+}
+
+static inline void crypto_stat_ahash_final(struct ahash_request *req, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&tfm->base.__crt_alg->hash_err_cnt);
+ } else {
+ atomic_inc(&tfm->base.__crt_alg->hash_cnt);
+ atomic64_add(req->nbytes, &tfm->base.__crt_alg->hash_tlen);
+ }
+#endif
+}
+
/**
* crypto_ahash_finup() - update and finalize message digest
* @req: reference to the ahash_request handle that holds all information
@@ -526,7 +552,11 @@ static inline int crypto_ahash_init(struct ahash_request *req)
*/
static inline int crypto_ahash_update(struct ahash_request *req)
{
- return crypto_ahash_reqtfm(req)->update(req);
+ int ret;
+
+ ret = crypto_ahash_reqtfm(req)->update(req);
+ crypto_stat_ahash_update(req, ret);
+ return ret;
}
/**
diff --git a/include/crypto/internal/cryptouser.h b/include/crypto/internal/cryptouser.h
new file mode 100644
index 000000000000..8db299c25566
--- /dev/null
+++ b/include/crypto/internal/cryptouser.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <net/netlink.h>
+
+struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact);
+
+int crypto_dump_reportstat(struct sk_buff *skb, struct netlink_callback *cb);
+int crypto_reportstat(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, struct nlattr **attrs);
+int crypto_dump_reportstat_done(struct netlink_callback *cb);
diff --git a/include/crypto/kpp.h b/include/crypto/kpp.h
index 1bde0a6514fa..f517ba6d3a27 100644
--- a/include/crypto/kpp.h
+++ b/include/crypto/kpp.h
@@ -268,6 +268,42 @@ struct kpp_secret {
unsigned short len;
};
+static inline void crypto_stat_kpp_set_secret(struct crypto_kpp *tfm, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ if (ret)
+ atomic_inc(&tfm->base.__crt_alg->kpp_err_cnt);
+ else
+ atomic_inc(&tfm->base.__crt_alg->setsecret_cnt);
+#endif
+}
+
+static inline void crypto_stat_kpp_generate_public_key(struct kpp_request *req,
+ int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+
+ if (ret)
+ atomic_inc(&tfm->base.__crt_alg->kpp_err_cnt);
+ else
+ atomic_inc(&tfm->base.__crt_alg->generate_public_key_cnt);
+#endif
+}
+
+static inline void crypto_stat_kpp_compute_shared_secret(struct kpp_request *req,
+ int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+
+ if (ret)
+ atomic_inc(&tfm->base.__crt_alg->kpp_err_cnt);
+ else
+ atomic_inc(&tfm->base.__crt_alg->compute_shared_secret_cnt);
+#endif
+}
+
/**
* crypto_kpp_set_secret() - Invoke kpp operation
*
@@ -287,8 +323,11 @@ static inline int crypto_kpp_set_secret(struct crypto_kpp *tfm,
const void *buffer, unsigned int len)
{
struct kpp_alg *alg = crypto_kpp_alg(tfm);
+ int ret;
- return alg->set_secret(tfm, buffer, len);
+ ret = alg->set_secret(tfm, buffer, len);
+ crypto_stat_kpp_set_secret(tfm, ret);
+ return ret;
}
/**
@@ -308,8 +347,11 @@ static inline int crypto_kpp_generate_public_key(struct kpp_request *req)
{
struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
struct kpp_alg *alg = crypto_kpp_alg(tfm);
+ int ret;
- return alg->generate_public_key(req);
+ ret = alg->generate_public_key(req);
+ crypto_stat_kpp_generate_public_key(req, ret);
+ return ret;
}
/**
@@ -326,8 +368,11 @@ static inline int crypto_kpp_compute_shared_secret(struct kpp_request *req)
{
struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
struct kpp_alg *alg = crypto_kpp_alg(tfm);
+ int ret;
- return alg->compute_shared_secret(req);
+ ret = alg->compute_shared_secret(req);
+ crypto_stat_kpp_compute_shared_secret(req, ret);
+ return ret;
}
/**
diff --git a/include/crypto/rng.h b/include/crypto/rng.h
index b95ede354a66..6d258f5b68f1 100644
--- a/include/crypto/rng.h
+++ b/include/crypto/rng.h
@@ -122,6 +122,29 @@ static inline void crypto_free_rng(struct crypto_rng *tfm)
crypto_destroy_tfm(tfm, crypto_rng_tfm(tfm));
}
+static inline void crypto_stat_rng_seed(struct crypto_rng *tfm, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY)
+ atomic_inc(&tfm->base.__crt_alg->rng_err_cnt);
+ else
+ atomic_inc(&tfm->base.__crt_alg->seed_cnt);
+#endif
+}
+
+static inline void crypto_stat_rng_generate(struct crypto_rng *tfm,
+ unsigned int dlen, int ret)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&tfm->base.__crt_alg->rng_err_cnt);
+ } else {
+ atomic_inc(&tfm->base.__crt_alg->generate_cnt);
+ atomic64_add(dlen, &tfm->base.__crt_alg->generate_tlen);
+ }
+#endif
+}
+
/**
* crypto_rng_generate() - get random number
* @tfm: cipher handle
@@ -140,7 +163,11 @@ static inline int crypto_rng_generate(struct crypto_rng *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int dlen)
{
- return crypto_rng_alg(tfm)->generate(tfm, src, slen, dst, dlen);
+ int ret;
+
+ ret = crypto_rng_alg(tfm)->generate(tfm, src, slen, dst, dlen);
+ crypto_stat_rng_generate(tfm, dlen, ret);
+ return ret;
}
/**
diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h
index 45ae894fda32..925f547cdcfa 100644
--- a/include/crypto/skcipher.h
+++ b/include/crypto/skcipher.h
@@ -486,6 +486,32 @@ static inline struct crypto_sync_skcipher *crypto_sync_skcipher_reqtfm(
return container_of(tfm, struct crypto_sync_skcipher, base);
}
+static inline void crypto_stat_skcipher_encrypt(struct skcipher_request *req,
+ int ret, struct crypto_alg *alg)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&alg->cipher_err_cnt);
+ } else {
+ atomic_inc(&alg->encrypt_cnt);
+ atomic64_add(req->cryptlen, &alg->encrypt_tlen);
+ }
+#endif
+}
+
+static inline void crypto_stat_skcipher_decrypt(struct skcipher_request *req,
+ int ret, struct crypto_alg *alg)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
+ atomic_inc(&alg->cipher_err_cnt);
+ } else {
+ atomic_inc(&alg->decrypt_cnt);
+ atomic64_add(req->cryptlen, &alg->decrypt_tlen);
+ }
+#endif
+}
+
/**
* crypto_skcipher_encrypt() - encrypt plaintext
* @req: reference to the skcipher_request handle that holds all information
@@ -500,11 +526,14 @@ static inline struct crypto_sync_skcipher *crypto_sync_skcipher_reqtfm(
static inline int crypto_skcipher_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ int ret;
if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
- return -ENOKEY;
-
- return tfm->encrypt(req);
+ ret = -ENOKEY;
+ else
+ ret = tfm->encrypt(req);
+ crypto_stat_skcipher_encrypt(req, ret, tfm->base.__crt_alg);
+ return ret;
}
/**
@@ -521,11 +550,14 @@ static inline int crypto_skcipher_encrypt(struct skcipher_request *req)
static inline int crypto_skcipher_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ int ret;
if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
- return -ENOKEY;
-
- return tfm->decrypt(req);
+ ret = -ENOKEY;
+ else
+ ret = tfm->decrypt(req);
+ crypto_stat_skcipher_decrypt(req, ret, tfm->base.__crt_alg);
+ return ret;
}
/**