LCOV - code coverage report
Current view: top level - crypto - rng.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 0 70 0.0 %
Date: 2020-09-30 20:25:40 Functions: 0 12 0.0 %
Branches: 0 24 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  * Cryptographic API.
       4                 :            :  *
       5                 :            :  * RNG operations.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
       8                 :            :  * Copyright (c) 2015 Herbert Xu <herbert@gondor.apana.org.au>
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <linux/atomic.h>
      12                 :            : #include <crypto/internal/rng.h>
      13                 :            : #include <linux/err.h>
      14                 :            : #include <linux/module.h>
      15                 :            : #include <linux/mutex.h>
      16                 :            : #include <linux/random.h>
      17                 :            : #include <linux/seq_file.h>
      18                 :            : #include <linux/slab.h>
      19                 :            : #include <linux/string.h>
      20                 :            : #include <linux/cryptouser.h>
      21                 :            : #include <linux/compiler.h>
      22                 :            : #include <net/netlink.h>
      23                 :            : 
      24                 :            : #include "internal.h"
      25                 :            : 
      26                 :            : static DEFINE_MUTEX(crypto_default_rng_lock);
      27                 :            : struct crypto_rng *crypto_default_rng;
      28                 :            : EXPORT_SYMBOL_GPL(crypto_default_rng);
      29                 :            : static int crypto_default_rng_refcnt;
      30                 :            : 
      31                 :          0 : int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
      32                 :            : {
      33                 :          0 :         struct crypto_alg *alg = tfm->base.__crt_alg;
      34                 :            :         u8 *buf = NULL;
      35                 :            :         int err;
      36                 :            : 
      37                 :            :         crypto_stats_get(alg);
      38         [ #  # ]:          0 :         if (!seed && slen) {
      39                 :            :                 buf = kmalloc(slen, GFP_KERNEL);
      40         [ #  # ]:          0 :                 if (!buf) {
      41                 :          0 :                         crypto_alg_put(alg);
      42                 :          0 :                         return -ENOMEM;
      43                 :            :                 }
      44                 :            : 
      45                 :          0 :                 err = get_random_bytes_wait(buf, slen);
      46         [ #  # ]:          0 :                 if (err) {
      47                 :          0 :                         crypto_alg_put(alg);
      48                 :          0 :                         goto out;
      49                 :            :                 }
      50                 :            :                 seed = buf;
      51                 :            :         }
      52                 :            : 
      53                 :          0 :         err = crypto_rng_alg(tfm)->seed(tfm, seed, slen);
      54                 :            :         crypto_stats_rng_seed(alg, err);
      55                 :            : out:
      56                 :          0 :         kzfree(buf);
      57                 :          0 :         return err;
      58                 :            : }
      59                 :            : EXPORT_SYMBOL_GPL(crypto_rng_reset);
      60                 :            : 
      61                 :          0 : static int crypto_rng_init_tfm(struct crypto_tfm *tfm)
      62                 :            : {
      63                 :          0 :         return 0;
      64                 :            : }
      65                 :            : 
      66                 :            : static unsigned int seedsize(struct crypto_alg *alg)
      67                 :            : {
      68                 :            :         struct rng_alg *ralg = container_of(alg, struct rng_alg, base);
      69                 :            : 
      70                 :          0 :         return ralg->seedsize;
      71                 :            : }
      72                 :            : 
      73                 :            : #ifdef CONFIG_NET
      74                 :          0 : static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
      75                 :            : {
      76                 :            :         struct crypto_report_rng rrng;
      77                 :            : 
      78                 :          0 :         memset(&rrng, 0, sizeof(rrng));
      79                 :            : 
      80                 :          0 :         strscpy(rrng.type, "rng", sizeof(rrng.type));
      81                 :            : 
      82                 :          0 :         rrng.seedsize = seedsize(alg);
      83                 :            : 
      84                 :          0 :         return nla_put(skb, CRYPTOCFGA_REPORT_RNG, sizeof(rrng), &rrng);
      85                 :            : }
      86                 :            : #else
      87                 :            : static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
      88                 :            : {
      89                 :            :         return -ENOSYS;
      90                 :            : }
      91                 :            : #endif
      92                 :            : 
      93                 :            : static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
      94                 :            :         __maybe_unused;
      95                 :          0 : static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
      96                 :            : {
      97                 :          0 :         seq_printf(m, "type         : rng\n");
      98                 :          0 :         seq_printf(m, "seedsize     : %u\n", seedsize(alg));
      99                 :          0 : }
     100                 :            : 
     101                 :            : static const struct crypto_type crypto_rng_type = {
     102                 :            :         .extsize = crypto_alg_extsize,
     103                 :            :         .init_tfm = crypto_rng_init_tfm,
     104                 :            : #ifdef CONFIG_PROC_FS
     105                 :            :         .show = crypto_rng_show,
     106                 :            : #endif
     107                 :            :         .report = crypto_rng_report,
     108                 :            :         .maskclear = ~CRYPTO_ALG_TYPE_MASK,
     109                 :            :         .maskset = CRYPTO_ALG_TYPE_MASK,
     110                 :            :         .type = CRYPTO_ALG_TYPE_RNG,
     111                 :            :         .tfmsize = offsetof(struct crypto_rng, base),
     112                 :            : };
     113                 :            : 
     114                 :          0 : struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask)
     115                 :            : {
     116                 :          0 :         return crypto_alloc_tfm(alg_name, &crypto_rng_type, type, mask);
     117                 :            : }
     118                 :            : EXPORT_SYMBOL_GPL(crypto_alloc_rng);
     119                 :            : 
     120                 :          0 : int crypto_get_default_rng(void)
     121                 :            : {
     122                 :            :         struct crypto_rng *rng;
     123                 :            :         int err;
     124                 :            : 
     125                 :          0 :         mutex_lock(&crypto_default_rng_lock);
     126         [ #  # ]:          0 :         if (!crypto_default_rng) {
     127                 :            :                 rng = crypto_alloc_rng("stdrng", 0, 0);
     128                 :            :                 err = PTR_ERR(rng);
     129         [ #  # ]:          0 :                 if (IS_ERR(rng))
     130                 :            :                         goto unlock;
     131                 :            : 
     132                 :          0 :                 err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
     133         [ #  # ]:          0 :                 if (err) {
     134                 :            :                         crypto_free_rng(rng);
     135                 :            :                         goto unlock;
     136                 :            :                 }
     137                 :            : 
     138                 :          0 :                 crypto_default_rng = rng;
     139                 :            :         }
     140                 :            : 
     141                 :          0 :         crypto_default_rng_refcnt++;
     142                 :            :         err = 0;
     143                 :            : 
     144                 :            : unlock:
     145                 :          0 :         mutex_unlock(&crypto_default_rng_lock);
     146                 :            : 
     147                 :          0 :         return err;
     148                 :            : }
     149                 :            : EXPORT_SYMBOL_GPL(crypto_get_default_rng);
     150                 :            : 
     151                 :          0 : void crypto_put_default_rng(void)
     152                 :            : {
     153                 :          0 :         mutex_lock(&crypto_default_rng_lock);
     154                 :          0 :         crypto_default_rng_refcnt--;
     155                 :          0 :         mutex_unlock(&crypto_default_rng_lock);
     156                 :          0 : }
     157                 :            : EXPORT_SYMBOL_GPL(crypto_put_default_rng);
     158                 :            : 
     159                 :            : #if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE)
     160                 :          0 : int crypto_del_default_rng(void)
     161                 :            : {
     162                 :            :         int err = -EBUSY;
     163                 :            : 
     164                 :          0 :         mutex_lock(&crypto_default_rng_lock);
     165         [ #  # ]:          0 :         if (crypto_default_rng_refcnt)
     166                 :            :                 goto out;
     167                 :            : 
     168                 :          0 :         crypto_free_rng(crypto_default_rng);
     169                 :          0 :         crypto_default_rng = NULL;
     170                 :            : 
     171                 :            :         err = 0;
     172                 :            : 
     173                 :            : out:
     174                 :          0 :         mutex_unlock(&crypto_default_rng_lock);
     175                 :            : 
     176                 :          0 :         return err;
     177                 :            : }
     178                 :            : EXPORT_SYMBOL_GPL(crypto_del_default_rng);
     179                 :            : #endif
     180                 :            : 
     181                 :          0 : int crypto_register_rng(struct rng_alg *alg)
     182                 :            : {
     183                 :          0 :         struct crypto_alg *base = &alg->base;
     184                 :            : 
     185         [ #  # ]:          0 :         if (alg->seedsize > PAGE_SIZE / 8)
     186                 :            :                 return -EINVAL;
     187                 :            : 
     188                 :          0 :         base->cra_type = &crypto_rng_type;
     189                 :          0 :         base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
     190                 :          0 :         base->cra_flags |= CRYPTO_ALG_TYPE_RNG;
     191                 :            : 
     192                 :          0 :         return crypto_register_alg(base);
     193                 :            : }
     194                 :            : EXPORT_SYMBOL_GPL(crypto_register_rng);
     195                 :            : 
     196                 :          0 : void crypto_unregister_rng(struct rng_alg *alg)
     197                 :            : {
     198                 :          0 :         crypto_unregister_alg(&alg->base);
     199                 :          0 : }
     200                 :            : EXPORT_SYMBOL_GPL(crypto_unregister_rng);
     201                 :            : 
     202                 :          0 : int crypto_register_rngs(struct rng_alg *algs, int count)
     203                 :            : {
     204                 :            :         int i, ret;
     205                 :            : 
     206         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     207                 :          0 :                 ret = crypto_register_rng(algs + i);
     208         [ #  # ]:          0 :                 if (ret)
     209                 :            :                         goto err;
     210                 :            :         }
     211                 :            : 
     212                 :            :         return 0;
     213                 :            : 
     214                 :            : err:
     215         [ #  # ]:          0 :         for (--i; i >= 0; --i)
     216                 :          0 :                 crypto_unregister_rng(algs + i);
     217                 :            : 
     218                 :          0 :         return ret;
     219                 :            : }
     220                 :            : EXPORT_SYMBOL_GPL(crypto_register_rngs);
     221                 :            : 
     222                 :          0 : void crypto_unregister_rngs(struct rng_alg *algs, int count)
     223                 :            : {
     224                 :            :         int i;
     225                 :            : 
     226         [ #  # ]:          0 :         for (i = count - 1; i >= 0; --i)
     227                 :          0 :                 crypto_unregister_rng(algs + i);
     228                 :          0 : }
     229                 :            : EXPORT_SYMBOL_GPL(crypto_unregister_rngs);
     230                 :            : 
     231                 :            : MODULE_LICENSE("GPL");
     232                 :            : MODULE_DESCRIPTION("Random Number Generator");

Generated by: LCOV version 1.14