cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sun4i-ss-prng.c (1637B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2#include "sun4i-ss.h"
      3
      4int sun4i_ss_prng_seed(struct crypto_rng *tfm, const u8 *seed,
      5		       unsigned int slen)
      6{
      7	struct sun4i_ss_alg_template *algt;
      8	struct rng_alg *alg = crypto_rng_alg(tfm);
      9
     10	algt = container_of(alg, struct sun4i_ss_alg_template, alg.rng);
     11	memcpy(algt->ss->seed, seed, slen);
     12
     13	return 0;
     14}
     15
     16int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
     17			   unsigned int slen, u8 *dst, unsigned int dlen)
     18{
     19	struct sun4i_ss_alg_template *algt;
     20	struct rng_alg *alg = crypto_rng_alg(tfm);
     21	int i, err;
     22	u32 v;
     23	u32 *data = (u32 *)dst;
     24	const u32 mode = SS_OP_PRNG | SS_PRNG_CONTINUE | SS_ENABLED;
     25	size_t len;
     26	struct sun4i_ss_ctx *ss;
     27	unsigned int todo = (dlen / 4) * 4;
     28
     29	algt = container_of(alg, struct sun4i_ss_alg_template, alg.rng);
     30	ss = algt->ss;
     31
     32	err = pm_runtime_resume_and_get(ss->dev);
     33	if (err < 0)
     34		return err;
     35
     36	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
     37		algt->stat_req++;
     38		algt->stat_bytes += todo;
     39	}
     40
     41	spin_lock_bh(&ss->slock);
     42
     43	writel(mode, ss->base + SS_CTL);
     44
     45	while (todo > 0) {
     46		/* write the seed */
     47		for (i = 0; i < SS_SEED_LEN / BITS_PER_LONG; i++)
     48			writel(ss->seed[i], ss->base + SS_KEY0 + i * 4);
     49
     50		/* Read the random data */
     51		len = min_t(size_t, SS_DATA_LEN / BITS_PER_BYTE, todo);
     52		readsl(ss->base + SS_TXFIFO, data, len / 4);
     53		data += len / 4;
     54		todo -= len;
     55
     56		/* Update the seed */
     57		for (i = 0; i < SS_SEED_LEN / BITS_PER_LONG; i++) {
     58			v = readl(ss->base + SS_KEY0 + i * 4);
     59			ss->seed[i] = v;
     60		}
     61	}
     62
     63	writel(0, ss->base + SS_CTL);
     64	spin_unlock_bh(&ss->slock);
     65
     66	pm_runtime_put(ss->dev);
     67
     68	return 0;
     69}