/*
 * Copyright IBM Corp. 2006,2007
 * Author(s): Jan Glauber <jan.glauber@de.ibm.com>
 * Driver for the s390 pseudo random number generator
 */
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/smp_lock.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/random.h>
#include <asm/debug.h>
#include <asm/uaccess.h>

#include "crypt_s390.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jan Glauber <jan.glauber@de.ibm.com>");
MODULE_DESCRIPTION("s390 PRNG interface");

static int prng_chunk_size = 256;
module_param(prng_chunk_size, int, S_IRUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(prng_chunk_size, "PRNG read chunk size in bytes");

static int prng_entropy_limit = 4096;
module_param(prng_entropy_limit, int, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
MODULE_PARM_DESC(prng_entropy_limit,
	"PRNG add entropy after that much bytes were produced");

/*
 * Any one who considers arithmetical methods of producing random digits is,
 * of course, in a state of sin. -- John von Neumann
 */

struct s390_prng_data {
	unsigned long count; /* how many bytes were produced */
	char *buf;
};

static struct s390_prng_data *p;

/* copied from libica, use a non-zero initial parameter block */
static unsigned char parm_block[32] = {
0x0F,0x2B,0x8E,0x63,0x8C,0x8E,0xD2,0x52,0x64,0xB7,0xA0,0x7B,0x75,0x28,0xB8,0xF4,
0x75,0x5F,0xD2,0xA6,0x8D,0x97,0x11,0xFF,0x49,0xD8,0x23,0xF3,0x7E,0x21,0xEC,0xA0,
};

static int prng_open(struct inode *inode, struct file *file)
{
	cycle_kernel_lock();
	return nonseekable_open(inode, file);
}

static void prng_add_entropy(void)
{
	__u64 entropy[4];
	unsigned int i;
	int ret;

	for (i = 0; i < 16; i++) {
		ret = crypt_s390_kmc(KMC_PRNG, parm_block, (char *)entropy,
				     (char *)entropy, sizeof(entropy));
		BUG_ON(ret < 0 || ret != sizeof(entropy));
		memcpy(parm_block, entropy, sizeof(entropy));
	}
}

static void prng_seed(int nbytes)
{
	char buf[16];
	int i = 0;

	BUG_ON(nbytes > 16);
	get_random_bytes(buf, nbytes);

	/* Add the entropy */
	while (nbytes >= 8) {
		*((__u64 *)parm_block) ^= *((__u64 *)buf+i*8);
		prng_add_entropy();
		i += 8;
		nbytes -= 8;
	}
	prng_add_entropy();
}

static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
			 loff_t *ppos)
{
	int chunk, n;
	int ret = 0;
	int tmp;

	/* nbytes can be arbitrary length, we split it into chunks */
	while (nbytes) {
		/* same as in extract_entropy_user in random.c */
		if (need_resched()) {
			if (signal_pending(current)) {
				if (ret == 0)
					ret = -ERESTARTSYS;
				break;
			}
			schedule();
		}

		/*
		 * we lose some random bytes if an attacker issues
		 * reads < 8 bytes, but we don't care
		 */
		chunk = min_t(int, nbytes, prng_chunk_size);

		/* PRNG only likes multiples of 8 bytes */
		n = (chunk + 7) & -8;

		if (p->count > prng_entropy_limit)
			prng_seed(8);

		/* if the CPU supports PRNG stckf is present too */
		asm volatile(".insn     s,0xb27c0000,%0"
			     : "=m" (*((unsigned long long *)p->buf)) : : "cc");

		/*
		 * Beside the STCKF the input for the TDES-EDE is the output
		 * of the last operation. We differ here from X9.17 since we
		 * only store one timestamp into the buffer. Padding the whole
		 * buffer with timestamps does not improve security, since
		 * successive stckf have nearly constant offsets.
		 * If an attacker knows the first timestamp it would be
		 * trivial to guess the additional values. One timestamp
		 * is therefore enough and still guarantees unique input values.
		 *
		 * Note: you can still get strict X9.17 conformity by setting
		 * prng_chunk_size to 8 bytes.
		*/
		tmp = crypt_s390_kmc(KMC_PRNG, parm_block, p->buf, p->buf, n);
		BUG_ON((tmp < 0) || (tmp != n));

		p->count += n;

		if (copy_to_user(ubuf, p->buf, chunk))
			return -EFAULT;

		nbytes -= chunk;
		ret += chunk;
		ubuf += chunk;
	}
	return ret;
}

static const struct file_operations prng_fops = {
	.owner		= THIS_MODULE,
	.open		= &prng_open,
	.release	= NULL,
	.read		= &prng_read,
};

static struct miscdevice prng_dev = {
	.name	= "prandom",
	.minor	= MISC_DYNAMIC_MINOR,
	.fops	= &prng_fops,
};

static int __init prng_init(void)
{
	int ret;

	/* check if the CPU has a PRNG */
	if (!crypt_s390_func_available(KMC_PRNG))
		return -EOPNOTSUPP;

	if (prng_chunk_size < 8)
		return -EINVAL;

	p = kmalloc(sizeof(struct s390_prng_data), GFP_KERNEL);
	if (!p)
		return -ENOMEM;
	p->count = 0;

	p->buf = kmalloc(prng_chunk_size, GFP_KERNEL);
	if (!p->buf) {
		ret = -ENOMEM;
		goto out_free;
	}

	/* initialize the PRNG, add 128 bits of entropy */
	prng_seed(16);

	ret = misc_register(&prng_dev);
	if (ret)
		goto out_buf;
	return 0;

out_buf:
	kfree(p->buf);
out_free:
	kfree(p);
	return ret;
}

static void __exit prng_exit(void)
{
	/* wipe me */
	kzfree(p->buf);
	kfree(p);

	misc_deregister(&prng_dev);
}

module_init(prng_init);
module_exit(prng_exit);
