summaryrefslogtreecommitdiffstats
path: root/include/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2024-03-13 09:49:37 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2024-03-13 09:49:37 +0800
commit6a8dbd71a70620c42d4fa82509204ba18231f28d (patch)
tree4cf38267140e30c8bd1ae3ec9d02f29b28037020 /include/crypto
parent77292bb8ca69c808741aadbd29207605296e24af (diff)
downloadlinux-6a8dbd71a70620c42d4fa82509204ba18231f28d.tar.gz
linux-6a8dbd71a70620c42d4fa82509204ba18231f28d.tar.bz2
linux-6a8dbd71a70620c42d4fa82509204ba18231f28d.zip
Revert "crypto: remove CONFIG_CRYPTO_STATS"
This reverts commit 2beb81fbf0c01a62515a1bcef326168494ee2bd0. While removing CONFIG_CRYPTO_STATS is a worthy goal, this also removed unrelated infrastructure such as crypto_comp_alg_common. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'include/crypto')
-rw-r--r--include/crypto/acompress.h90
-rw-r--r--include/crypto/aead.h21
-rw-r--r--include/crypto/akcipher.h78
-rw-r--r--include/crypto/algapi.h3
-rw-r--r--include/crypto/hash.h22
-rw-r--r--include/crypto/internal/acompress.h7
-rw-r--r--include/crypto/internal/cryptouser.h16
-rw-r--r--include/crypto/internal/scompress.h8
-rw-r--r--include/crypto/kpp.h58
-rw-r--r--include/crypto/rng.h51
-rw-r--r--include/crypto/skcipher.h25
11 files changed, 367 insertions, 12 deletions
diff --git a/include/crypto/acompress.h b/include/crypto/acompress.h
index d042c90e0907..574cffc90730 100644
--- a/include/crypto/acompress.h
+++ b/include/crypto/acompress.h
@@ -56,6 +56,35 @@ struct crypto_acomp {
struct crypto_tfm base;
};
+/*
+ * struct crypto_istat_compress - statistics for compress algorithm
+ * @compress_cnt: number of compress requests
+ * @compress_tlen: total data size handled by compress requests
+ * @decompress_cnt: number of decompress requests
+ * @decompress_tlen: total data size handled by decompress requests
+ * @err_cnt: number of error for compress requests
+ */
+struct crypto_istat_compress {
+ atomic64_t compress_cnt;
+ atomic64_t compress_tlen;
+ atomic64_t decompress_cnt;
+ atomic64_t decompress_tlen;
+ atomic64_t err_cnt;
+};
+
+#ifdef CONFIG_CRYPTO_STATS
+#define COMP_ALG_COMMON_STATS struct crypto_istat_compress stat;
+#else
+#define COMP_ALG_COMMON_STATS
+#endif
+
+#define COMP_ALG_COMMON { \
+ COMP_ALG_COMMON_STATS \
+ \
+ struct crypto_alg base; \
+}
+struct comp_alg_common COMP_ALG_COMMON;
+
/**
* DOC: Asynchronous Compression API
*
@@ -103,11 +132,23 @@ static inline struct crypto_tfm *crypto_acomp_tfm(struct crypto_acomp *tfm)
return &tfm->base;
}
+static inline struct comp_alg_common *__crypto_comp_alg_common(
+ struct crypto_alg *alg)
+{
+ return container_of(alg, struct comp_alg_common, base);
+}
+
static inline struct crypto_acomp *__crypto_acomp_tfm(struct crypto_tfm *tfm)
{
return container_of(tfm, struct crypto_acomp, base);
}
+static inline struct comp_alg_common *crypto_comp_alg_common(
+ struct crypto_acomp *tfm)
+{
+ return __crypto_comp_alg_common(crypto_acomp_tfm(tfm)->__crt_alg);
+}
+
static inline unsigned int crypto_acomp_reqsize(struct crypto_acomp *tfm)
{
return tfm->reqsize;
@@ -214,6 +255,27 @@ static inline void acomp_request_set_params(struct acomp_req *req,
req->flags |= CRYPTO_ACOMP_ALLOC_OUTPUT;
}
+static inline struct crypto_istat_compress *comp_get_stat(
+ struct comp_alg_common *alg)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ return &alg->stat;
+#else
+ return NULL;
+#endif
+}
+
+static inline int crypto_comp_errstat(struct comp_alg_common *alg, int err)
+{
+ if (!IS_ENABLED(CONFIG_CRYPTO_STATS))
+ return err;
+
+ if (err && err != -EINPROGRESS && err != -EBUSY)
+ atomic64_inc(&comp_get_stat(alg)->err_cnt);
+
+ return err;
+}
+
/**
* crypto_acomp_compress() -- Invoke asynchronous compress operation
*
@@ -225,7 +287,19 @@ static inline void acomp_request_set_params(struct acomp_req *req,
*/
static inline int crypto_acomp_compress(struct acomp_req *req)
{
- return crypto_acomp_reqtfm(req)->compress(req);
+ struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+ struct comp_alg_common *alg;
+
+ alg = crypto_comp_alg_common(tfm);
+
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
+ struct crypto_istat_compress *istat = comp_get_stat(alg);
+
+ atomic64_inc(&istat->compress_cnt);
+ atomic64_add(req->slen, &istat->compress_tlen);
+ }
+
+ return crypto_comp_errstat(alg, tfm->compress(req));
}
/**
@@ -239,7 +313,19 @@ static inline int crypto_acomp_compress(struct acomp_req *req)
*/
static inline int crypto_acomp_decompress(struct acomp_req *req)
{
- return crypto_acomp_reqtfm(req)->decompress(req);
+ struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+ struct comp_alg_common *alg;
+
+ alg = crypto_comp_alg_common(tfm);
+
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
+ struct crypto_istat_compress *istat = comp_get_stat(alg);
+
+ atomic64_inc(&istat->decompress_cnt);
+ atomic64_add(req->slen, &istat->decompress_tlen);
+ }
+
+ return crypto_comp_errstat(alg, tfm->decompress(req));
}
#endif
diff --git a/include/crypto/aead.h b/include/crypto/aead.h
index 0e8a41638678..51382befbe37 100644
--- a/include/crypto/aead.h
+++ b/include/crypto/aead.h
@@ -101,6 +101,22 @@ struct aead_request {
void *__ctx[] CRYPTO_MINALIGN_ATTR;
};
+/*
+ * struct crypto_istat_aead - statistics for AEAD algorithm
+ * @encrypt_cnt: number of encrypt requests
+ * @encrypt_tlen: total data size handled by encrypt requests
+ * @decrypt_cnt: number of decrypt requests
+ * @decrypt_tlen: total data size handled by decrypt requests
+ * @err_cnt: number of error for AEAD requests
+ */
+struct crypto_istat_aead {
+ atomic64_t encrypt_cnt;
+ atomic64_t encrypt_tlen;
+ atomic64_t decrypt_cnt;
+ atomic64_t decrypt_tlen;
+ atomic64_t err_cnt;
+};
+
/**
* struct aead_alg - AEAD cipher definition
* @maxauthsize: Set the maximum authentication tag size supported by the
@@ -119,6 +135,7 @@ struct aead_request {
* @setkey: see struct skcipher_alg
* @encrypt: see struct skcipher_alg
* @decrypt: see struct skcipher_alg
+ * @stat: statistics for AEAD algorithm
* @ivsize: see struct skcipher_alg
* @chunksize: see struct skcipher_alg
* @init: Initialize the cryptographic transformation object. This function
@@ -145,6 +162,10 @@ struct aead_alg {
int (*init)(struct crypto_aead *tfm);
void (*exit)(struct crypto_aead *tfm);
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_istat_aead stat;
+#endif
+
unsigned int ivsize;
unsigned int maxauthsize;
unsigned int chunksize;
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index 18a10cad07aa..31c111bebb68 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -54,6 +54,26 @@ struct crypto_akcipher {
struct crypto_tfm base;
};
+/*
+ * struct crypto_istat_akcipher - statistics for akcipher algorithm
+ * @encrypt_cnt: number of encrypt requests
+ * @encrypt_tlen: total data size handled by encrypt requests
+ * @decrypt_cnt: number of decrypt requests
+ * @decrypt_tlen: total data size handled by decrypt requests
+ * @verify_cnt: number of verify operation
+ * @sign_cnt: number of sign requests
+ * @err_cnt: number of error for akcipher requests
+ */
+struct crypto_istat_akcipher {
+ atomic64_t encrypt_cnt;
+ atomic64_t encrypt_tlen;
+ atomic64_t decrypt_cnt;
+ atomic64_t decrypt_tlen;
+ atomic64_t verify_cnt;
+ atomic64_t sign_cnt;
+ atomic64_t err_cnt;
+};
+
/**
* struct akcipher_alg - generic public key algorithm
*
@@ -90,6 +110,7 @@ struct crypto_akcipher {
* @exit: Deinitialize the cryptographic transformation object. This is a
* counterpart to @init, used to remove various changes set in
* @init.
+ * @stat: Statistics for akcipher algorithm
*
* @base: Common crypto API algorithm data structure
*/
@@ -106,6 +127,10 @@ struct akcipher_alg {
int (*init)(struct crypto_akcipher *tfm);
void (*exit)(struct crypto_akcipher *tfm);
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_istat_akcipher stat;
+#endif
+
struct crypto_alg base;
};
@@ -277,6 +302,27 @@ static inline unsigned int crypto_akcipher_maxsize(struct crypto_akcipher *tfm)
return alg->max_size(tfm);
}
+static inline struct crypto_istat_akcipher *akcipher_get_stat(
+ struct akcipher_alg *alg)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ return &alg->stat;
+#else
+ return NULL;
+#endif
+}
+
+static inline int crypto_akcipher_errstat(struct akcipher_alg *alg, int err)
+{
+ if (!IS_ENABLED(CONFIG_CRYPTO_STATS))
+ return err;
+
+ if (err && err != -EINPROGRESS && err != -EBUSY)
+ atomic64_inc(&akcipher_get_stat(alg)->err_cnt);
+
+ return err;
+}
+
/**
* crypto_akcipher_encrypt() - Invoke public key encrypt operation
*
@@ -290,8 +336,16 @@ static inline unsigned int crypto_akcipher_maxsize(struct crypto_akcipher *tfm)
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);
- return crypto_akcipher_alg(tfm)->encrypt(req);
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
+ struct crypto_istat_akcipher *istat = akcipher_get_stat(alg);
+
+ atomic64_inc(&istat->encrypt_cnt);
+ atomic64_add(req->src_len, &istat->encrypt_tlen);
+ }
+
+ return crypto_akcipher_errstat(alg, alg->encrypt(req));
}
/**
@@ -307,8 +361,16 @@ static inline int crypto_akcipher_encrypt(struct akcipher_request *req)
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);
- return crypto_akcipher_alg(tfm)->decrypt(req);
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
+ struct crypto_istat_akcipher *istat = akcipher_get_stat(alg);
+
+ atomic64_inc(&istat->decrypt_cnt);
+ atomic64_add(req->src_len, &istat->decrypt_tlen);
+ }
+
+ return crypto_akcipher_errstat(alg, alg->decrypt(req));
}
/**
@@ -360,8 +422,12 @@ int crypto_akcipher_sync_decrypt(struct crypto_akcipher *tfm,
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);
- return crypto_akcipher_alg(tfm)->sign(req);
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS))
+ atomic64_inc(&akcipher_get_stat(alg)->sign_cnt);
+
+ return crypto_akcipher_errstat(alg, alg->sign(req));
}
/**
@@ -381,8 +447,12 @@ static inline int crypto_akcipher_sign(struct akcipher_request *req)
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);
+
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS))
+ atomic64_inc(&akcipher_get_stat(alg)->verify_cnt);
- return crypto_akcipher_alg(tfm)->verify(req);
+ return crypto_akcipher_errstat(alg, alg->verify(req));
}
/**
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 156de41ca760..7a4a71af653f 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -61,6 +61,9 @@ struct crypto_type {
void (*show)(struct seq_file *m, struct crypto_alg *alg);
int (*report)(struct sk_buff *skb, struct crypto_alg *alg);
void (*free)(struct crypto_instance *inst);
+#ifdef CONFIG_CRYPTO_STATS
+ int (*report_stat)(struct sk_buff *skb, struct crypto_alg *alg);
+#endif
unsigned int type;
unsigned int maskclear;
diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index 0014bdd81ab7..5d61f576cfc8 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -24,7 +24,26 @@ struct crypto_ahash;
*/
/*
+ * struct crypto_istat_hash - statistics for has algorithm
+ * @hash_cnt: number of hash requests
+ * @hash_tlen: total data size hashed
+ * @err_cnt: number of error for hash requests
+ */
+struct crypto_istat_hash {
+ atomic64_t hash_cnt;
+ atomic64_t hash_tlen;
+ atomic64_t err_cnt;
+};
+
+#ifdef CONFIG_CRYPTO_STATS
+#define HASH_ALG_COMMON_STAT struct crypto_istat_hash stat;
+#else
+#define HASH_ALG_COMMON_STAT
+#endif
+
+/*
* struct hash_alg_common - define properties of message digest
+ * @stat: Statistics for hash algorithm.
* @digestsize: Size of the result of the transformation. A buffer of this size
* must be available to the @final and @finup calls, so they can
* store the resulting hash into it. For various predefined sizes,
@@ -41,6 +60,8 @@ struct crypto_ahash;
* information.
*/
#define HASH_ALG_COMMON { \
+ HASH_ALG_COMMON_STAT \
+ \
unsigned int digestsize; \
unsigned int statesize; \
\
@@ -222,6 +243,7 @@ struct shash_alg {
};
};
#undef HASH_ALG_COMMON
+#undef HASH_ALG_COMMON_STAT
struct crypto_ahash {
bool using_shash; /* Underlying algorithm is shash, not ahash */
diff --git a/include/crypto/internal/acompress.h b/include/crypto/internal/acompress.h
index 475e60a9f9ea..4ac46bafba9d 100644
--- a/include/crypto/internal/acompress.h
+++ b/include/crypto/internal/acompress.h
@@ -31,7 +31,9 @@
* @init.
*
* @reqsize: Context size for (de)compression requests
+ * @stat: Statistics for compress algorithm
* @base: Common crypto API algorithm data structure
+ * @calg: Cmonn algorithm data structure shared with scomp
*/
struct acomp_alg {
int (*compress)(struct acomp_req *req);
@@ -42,7 +44,10 @@ struct acomp_alg {
unsigned int reqsize;
- struct crypto_alg base;
+ union {
+ struct COMP_ALG_COMMON;
+ struct comp_alg_common calg;
+ };
};
/*
diff --git a/include/crypto/internal/cryptouser.h b/include/crypto/internal/cryptouser.h
new file mode 100644
index 000000000000..fd54074332f5
--- /dev/null
+++ b/include/crypto/internal/cryptouser.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
+
+struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact);
+
+#ifdef CONFIG_CRYPTO_STATS
+int crypto_reportstat(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, struct nlattr **attrs);
+#else
+static inline int crypto_reportstat(struct sk_buff *in_skb,
+ struct nlmsghdr *in_nlh,
+ struct nlattr **attrs)
+{
+ return -ENOTSUPP;
+}
+#endif
diff --git a/include/crypto/internal/scompress.h b/include/crypto/internal/scompress.h
index 5a75f2db18ce..858fe3965ae3 100644
--- a/include/crypto/internal/scompress.h
+++ b/include/crypto/internal/scompress.h
@@ -27,7 +27,9 @@ struct crypto_scomp {
* @free_ctx: Function frees context allocated with alloc_ctx
* @compress: Function performs a compress operation
* @decompress: Function performs a de-compress operation
+ * @stat: Statistics for compress algorithm
* @base: Common crypto API algorithm data structure
+ * @calg: Cmonn algorithm data structure shared with acomp
*/
struct scomp_alg {
void *(*alloc_ctx)(struct crypto_scomp *tfm);
@@ -38,7 +40,11 @@ struct scomp_alg {
int (*decompress)(struct crypto_scomp *tfm, const u8 *src,
unsigned int slen, u8 *dst, unsigned int *dlen,
void *ctx);
- struct crypto_alg base;
+
+ union {
+ struct COMP_ALG_COMMON;
+ struct comp_alg_common calg;
+ };
};
static inline struct scomp_alg *__crypto_scomp_alg(struct crypto_alg *alg)
diff --git a/include/crypto/kpp.h b/include/crypto/kpp.h
index 2d9c4de57b69..1988e24a0d1d 100644
--- a/include/crypto/kpp.h
+++ b/include/crypto/kpp.h
@@ -51,6 +51,20 @@ struct crypto_kpp {
struct crypto_tfm base;
};
+/*
+ * struct crypto_istat_kpp - statistics for KPP algorithm
+ * @setsecret_cnt: number of setsecrey operation
+ * @generate_public_key_cnt: number of generate_public_key operation
+ * @compute_shared_secret_cnt: number of compute_shared_secret operation
+ * @err_cnt: number of error for KPP requests
+ */
+struct crypto_istat_kpp {
+ atomic64_t setsecret_cnt;
+ atomic64_t generate_public_key_cnt;
+ atomic64_t compute_shared_secret_cnt;
+ atomic64_t err_cnt;
+};
+
/**
* struct kpp_alg - generic key-agreement protocol primitives
*
@@ -73,6 +87,7 @@ struct crypto_kpp {
* @exit: Undo everything @init did.
*
* @base: Common crypto API algorithm data structure
+ * @stat: Statistics for KPP algorithm
*/
struct kpp_alg {
int (*set_secret)(struct crypto_kpp *tfm, const void *buffer,
@@ -85,6 +100,10 @@ struct kpp_alg {
int (*init)(struct crypto_kpp *tfm);
void (*exit)(struct crypto_kpp *tfm);
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_istat_kpp stat;
+#endif
+
struct crypto_alg base;
};
@@ -272,6 +291,26 @@ struct kpp_secret {
unsigned short len;
};
+static inline struct crypto_istat_kpp *kpp_get_stat(struct kpp_alg *alg)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ return &alg->stat;
+#else
+ return NULL;
+#endif
+}
+
+static inline int crypto_kpp_errstat(struct kpp_alg *alg, int err)
+{
+ if (!IS_ENABLED(CONFIG_CRYPTO_STATS))
+ return err;
+
+ if (err && err != -EINPROGRESS && err != -EBUSY)
+ atomic64_inc(&kpp_get_stat(alg)->err_cnt);
+
+ return err;
+}
+
/**
* crypto_kpp_set_secret() - Invoke kpp operation
*
@@ -290,7 +329,12 @@ struct kpp_secret {
static inline int crypto_kpp_set_secret(struct crypto_kpp *tfm,
const void *buffer, unsigned int len)
{
- return crypto_kpp_alg(tfm)->set_secret(tfm, buffer, len);
+ struct kpp_alg *alg = crypto_kpp_alg(tfm);
+
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS))
+ atomic64_inc(&kpp_get_stat(alg)->setsecret_cnt);
+
+ return crypto_kpp_errstat(alg, alg->set_secret(tfm, buffer, len));
}
/**
@@ -309,8 +353,12 @@ static inline int crypto_kpp_set_secret(struct crypto_kpp *tfm,
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);
+
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS))
+ atomic64_inc(&kpp_get_stat(alg)->generate_public_key_cnt);
- return crypto_kpp_alg(tfm)->generate_public_key(req);
+ return crypto_kpp_errstat(alg, alg->generate_public_key(req));
}
/**
@@ -326,8 +374,12 @@ static inline int crypto_kpp_generate_public_key(struct kpp_request *req)
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);
+
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS))
+ atomic64_inc(&kpp_get_stat(alg)->compute_shared_secret_cnt);
- return crypto_kpp_alg(tfm)->compute_shared_secret(req);
+ return crypto_kpp_errstat(alg, alg->compute_shared_secret(req));
}
/**
diff --git a/include/crypto/rng.h b/include/crypto/rng.h
index 5ac4388f50e1..6abe5102e5fb 100644
--- a/include/crypto/rng.h
+++ b/include/crypto/rng.h
@@ -15,6 +15,20 @@
struct crypto_rng;
+/*
+ * struct crypto_istat_rng: statistics for RNG algorithm
+ * @generate_cnt: number of RNG generate requests
+ * @generate_tlen: total data size of generated data by the RNG
+ * @seed_cnt: number of times the RNG was seeded
+ * @err_cnt: number of error for RNG requests
+ */
+struct crypto_istat_rng {
+ atomic64_t generate_cnt;
+ atomic64_t generate_tlen;
+ atomic64_t seed_cnt;
+ atomic64_t err_cnt;
+};
+
/**
* struct rng_alg - random number generator definition
*
@@ -32,6 +46,7 @@ struct crypto_rng;
* size of the seed is defined with @seedsize .
* @set_ent: Set entropy that would otherwise be obtained from
* entropy source. Internal use only.
+ * @stat: Statistics for rng algorithm
* @seedsize: The seed size required for a random number generator
* initialization defined with this variable. Some
* random number generators does not require a seed
@@ -48,6 +63,10 @@ struct rng_alg {
void (*set_ent)(struct crypto_rng *tfm, const u8 *data,
unsigned int len);
+#ifdef CONFIG_CRYPTO_STATS
+ struct crypto_istat_rng stat;
+#endif
+
unsigned int seedsize;
struct crypto_alg base;
@@ -125,6 +144,26 @@ static inline void crypto_free_rng(struct crypto_rng *tfm)
crypto_destroy_tfm(tfm, crypto_rng_tfm(tfm));
}
+static inline struct crypto_istat_rng *rng_get_stat(struct rng_alg *alg)
+{
+#ifdef CONFIG_CRYPTO_STATS
+ return &alg->stat;
+#else
+ return NULL;
+#endif
+}
+
+static inline int crypto_rng_errstat(struct rng_alg *alg, int err)
+{
+ if (!IS_ENABLED(CONFIG_CRYPTO_STATS))
+ return err;
+
+ if (err && err != -EINPROGRESS && err != -EBUSY)
+ atomic64_inc(&rng_get_stat(alg)->err_cnt);
+
+ return err;
+}
+
/**
* crypto_rng_generate() - get random number
* @tfm: cipher handle
@@ -143,7 +182,17 @@ 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);
+ struct rng_alg *alg = crypto_rng_alg(tfm);
+
+ if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
+ struct crypto_istat_rng *istat = rng_get_stat(alg);
+
+ atomic64_inc(&istat->generate_cnt);
+ atomic64_add(dlen, &istat->generate_tlen);
+ }
+
+ return crypto_rng_errstat(alg,
+ alg->generate(tfm, src, slen, dst, dlen));
}
/**
diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h
index 74d47e23374e..c8857d7bdb37 100644
--- a/include/crypto/skcipher.h
+++ b/include/crypto/skcipher.h
@@ -65,6 +65,28 @@ struct crypto_lskcipher {
};
/*
+ * struct crypto_istat_cipher - statistics for cipher algorithm
+ * @encrypt_cnt: number of encrypt requests
+ * @encrypt_tlen: total data size handled by encrypt requests
+ * @decrypt_cnt: number of decrypt requests
+ * @decrypt_tlen: total data size handled by decrypt requests
+ * @err_cnt: number of error for cipher requests
+ */
+struct crypto_istat_cipher {
+ atomic64_t encrypt_cnt;
+ atomic64_t encrypt_tlen;
+ atomic64_t decrypt_cnt;
+ atomic64_t decrypt_tlen;
+ atomic64_t err_cnt;
+};
+
+#ifdef CONFIG_CRYPTO_STATS
+#define SKCIPHER_ALG_COMMON_STAT struct crypto_istat_cipher stat;
+#else
+#define SKCIPHER_ALG_COMMON_STAT
+#endif
+
+/*
* struct skcipher_alg_common - common properties of skcipher_alg
* @min_keysize: Minimum key size supported by the transformation. This is the
* smallest key length supported by this transformation algorithm.
@@ -81,6 +103,7 @@ struct crypto_lskcipher {
* @chunksize: Equal to the block size except for stream ciphers such as
* CTR where it is set to the underlying block size.
* @statesize: Size of the internal state for the algorithm.
+ * @stat: Statistics for cipher algorithm
* @base: Definition of a generic crypto algorithm.
*/
#define SKCIPHER_ALG_COMMON { \
@@ -90,6 +113,8 @@ struct crypto_lskcipher {
unsigned int chunksize; \
unsigned int statesize; \
\
+ SKCIPHER_ALG_COMMON_STAT \
+ \
struct crypto_alg base; \
}
struct skcipher_alg_common SKCIPHER_ALG_COMMON;