162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Scatterlist Cryptographic API.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Procfs information.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
862306a36Sopenharmony_ci * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/atomic.h>
1262306a36Sopenharmony_ci#include <linux/init.h>
1362306a36Sopenharmony_ci#include <linux/crypto.h>
1462306a36Sopenharmony_ci#include <linux/fips.h>
1562306a36Sopenharmony_ci#include <linux/module.h>	/* for module_name() */
1662306a36Sopenharmony_ci#include <linux/rwsem.h>
1762306a36Sopenharmony_ci#include <linux/proc_fs.h>
1862306a36Sopenharmony_ci#include <linux/seq_file.h>
1962306a36Sopenharmony_ci#include "internal.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic void *c_start(struct seq_file *m, loff_t *pos)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	down_read(&crypto_alg_sem);
2462306a36Sopenharmony_ci	return seq_list_start(&crypto_alg_list, *pos);
2562306a36Sopenharmony_ci}
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic void *c_next(struct seq_file *m, void *p, loff_t *pos)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	return seq_list_next(p, &crypto_alg_list, pos);
3062306a36Sopenharmony_ci}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistatic void c_stop(struct seq_file *m, void *p)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	up_read(&crypto_alg_sem);
3562306a36Sopenharmony_ci}
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistatic int c_show(struct seq_file *m, void *p)
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci	struct crypto_alg *alg = list_entry(p, struct crypto_alg, cra_list);
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	seq_printf(m, "name         : %s\n", alg->cra_name);
4262306a36Sopenharmony_ci	seq_printf(m, "driver       : %s\n", alg->cra_driver_name);
4362306a36Sopenharmony_ci	seq_printf(m, "module       : %s\n", module_name(alg->cra_module));
4462306a36Sopenharmony_ci	seq_printf(m, "priority     : %d\n", alg->cra_priority);
4562306a36Sopenharmony_ci	seq_printf(m, "refcnt       : %u\n", refcount_read(&alg->cra_refcnt));
4662306a36Sopenharmony_ci	seq_printf(m, "selftest     : %s\n",
4762306a36Sopenharmony_ci		   (alg->cra_flags & CRYPTO_ALG_TESTED) ?
4862306a36Sopenharmony_ci		   "passed" : "unknown");
4962306a36Sopenharmony_ci	seq_printf(m, "internal     : %s\n",
5062306a36Sopenharmony_ci		   (alg->cra_flags & CRYPTO_ALG_INTERNAL) ?
5162306a36Sopenharmony_ci		   "yes" : "no");
5262306a36Sopenharmony_ci	if (fips_enabled) {
5362306a36Sopenharmony_ci		seq_printf(m, "fips         : %s\n",
5462306a36Sopenharmony_ci			   (alg->cra_flags & CRYPTO_ALG_FIPS_INTERNAL) ?
5562306a36Sopenharmony_ci			   "no" : "yes");
5662306a36Sopenharmony_ci	}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
5962306a36Sopenharmony_ci		seq_printf(m, "type         : larval\n");
6062306a36Sopenharmony_ci		seq_printf(m, "flags        : 0x%x\n", alg->cra_flags);
6162306a36Sopenharmony_ci		goto out;
6262306a36Sopenharmony_ci	}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	if (alg->cra_type && alg->cra_type->show) {
6562306a36Sopenharmony_ci		alg->cra_type->show(m, alg);
6662306a36Sopenharmony_ci		goto out;
6762306a36Sopenharmony_ci	}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
7062306a36Sopenharmony_ci	case CRYPTO_ALG_TYPE_CIPHER:
7162306a36Sopenharmony_ci		seq_printf(m, "type         : cipher\n");
7262306a36Sopenharmony_ci		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
7362306a36Sopenharmony_ci		seq_printf(m, "min keysize  : %u\n",
7462306a36Sopenharmony_ci					alg->cra_cipher.cia_min_keysize);
7562306a36Sopenharmony_ci		seq_printf(m, "max keysize  : %u\n",
7662306a36Sopenharmony_ci					alg->cra_cipher.cia_max_keysize);
7762306a36Sopenharmony_ci		break;
7862306a36Sopenharmony_ci	case CRYPTO_ALG_TYPE_COMPRESS:
7962306a36Sopenharmony_ci		seq_printf(m, "type         : compression\n");
8062306a36Sopenharmony_ci		break;
8162306a36Sopenharmony_ci	default:
8262306a36Sopenharmony_ci		seq_printf(m, "type         : unknown\n");
8362306a36Sopenharmony_ci		break;
8462306a36Sopenharmony_ci	}
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ciout:
8762306a36Sopenharmony_ci	seq_putc(m, '\n');
8862306a36Sopenharmony_ci	return 0;
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_cistatic const struct seq_operations crypto_seq_ops = {
9262306a36Sopenharmony_ci	.start		= c_start,
9362306a36Sopenharmony_ci	.next		= c_next,
9462306a36Sopenharmony_ci	.stop		= c_stop,
9562306a36Sopenharmony_ci	.show		= c_show
9662306a36Sopenharmony_ci};
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_civoid __init crypto_init_proc(void)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	proc_create_seq("crypto", 0, NULL, &crypto_seq_ops);
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_civoid __exit crypto_exit_proc(void)
10462306a36Sopenharmony_ci{
10562306a36Sopenharmony_ci	remove_proc_entry("crypto", NULL);
10662306a36Sopenharmony_ci}
107