core.c 11.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
        Added support for the AMD Geode LX RNG
	(c) Copyright 2004-2005 Advanced Micro Devices, Inc.

	derived from

 	Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
	(c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>

 	derived from

        Hardware driver for the AMD 768 Random Number Generator (RNG)
        (c) Copyright 2001 Red Hat Inc <alan@redhat.com>

 	derived from

	Hardware driver for Intel i810 Random Number Generator (RNG)
	Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
	Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>

	Added generic RNG API
M
Michael Büsch 已提交
22
	Copyright 2006 Michael Buesch <m@bues.ch>
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
	Copyright 2005 (c) MontaVista Software, Inc.

	Please read Documentation/hw_random.txt for details on use.

	----------------------------------------------------------
	This software may be used and distributed according to the terms
        of the GNU General Public License, incorporated herein by reference.

 */


#include <linux/device.h>
#include <linux/hw_random.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
39
#include <linux/sched.h>
40
#include <linux/miscdevice.h>
T
Torsten Duwe 已提交
41
#include <linux/kthread.h>
42
#include <linux/delay.h>
43
#include <linux/slab.h>
44
#include <linux/random.h>
45
#include <linux/err.h>
46 47 48 49 50 51 52 53 54
#include <asm/uaccess.h>


#define RNG_MODULE_NAME		"hw_random"
#define PFX			RNG_MODULE_NAME ": "
#define RNG_MISCDEV_MINOR	183 /* official */


static struct hwrng *current_rng;
T
Torsten Duwe 已提交
55
static struct task_struct *hwrng_fill;
56
static LIST_HEAD(rng_list);
57
/* Protects rng_list and current_rng */
58
static DEFINE_MUTEX(rng_mutex);
59 60
/* Protects rng read functions, data_avail, rng_buffer and rng_fillbuf */
static DEFINE_MUTEX(reading_mutex);
61
static int data_avail;
T
Torsten Duwe 已提交
62
static u8 *rng_buffer, *rng_fillbuf;
63 64
static unsigned short current_quality;
static unsigned short default_quality; /* = 0; default to "off" */
T
Torsten Duwe 已提交
65 66 67 68

module_param(current_quality, ushort, 0644);
MODULE_PARM_DESC(current_quality,
		 "current hwrng entropy estimation per mill");
69 70 71
module_param(default_quality, ushort, 0644);
MODULE_PARM_DESC(default_quality,
		 "default entropy content of hwrng per mill");
T
Torsten Duwe 已提交
72 73

static void start_khwrngd(void);
74

75 76 77
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
			       int wait);

78 79 80 81
static size_t rng_buffer_size(void)
{
	return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
}
82

83 84 85 86 87
static void add_early_randomness(struct hwrng *rng)
{
	unsigned char bytes[16];
	int bytes_read;

88
	mutex_lock(&reading_mutex);
89
	bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
90
	mutex_unlock(&reading_mutex);
91 92 93 94
	if (bytes_read > 0)
		add_device_randomness(bytes, bytes_read);
}

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
static inline void cleanup_rng(struct kref *kref)
{
	struct hwrng *rng = container_of(kref, struct hwrng, ref);

	if (rng->cleanup)
		rng->cleanup(rng);
}

static void set_current_rng(struct hwrng *rng)
{
	BUG_ON(!mutex_is_locked(&rng_mutex));
	kref_get(&rng->ref);
	current_rng = rng;
}

static void drop_current_rng(void)
{
	BUG_ON(!mutex_is_locked(&rng_mutex));
	if (!current_rng)
		return;

	/* decrease last reference for triggering the cleanup */
	kref_put(&current_rng->ref, cleanup_rng);
	current_rng = NULL;
}

/* Returns ERR_PTR(), NULL or refcounted hwrng */
static struct hwrng *get_current_rng(void)
{
	struct hwrng *rng;

	if (mutex_lock_interruptible(&rng_mutex))
		return ERR_PTR(-ERESTARTSYS);

	rng = current_rng;
	if (rng)
		kref_get(&rng->ref);

	mutex_unlock(&rng_mutex);
	return rng;
}

static void put_rng(struct hwrng *rng)
{
	/*
	 * Hold rng_mutex here so we serialize in case they set_current_rng
	 * on rng again immediately.
	 */
	mutex_lock(&rng_mutex);
	if (rng)
		kref_put(&rng->ref, cleanup_rng);
	mutex_unlock(&rng_mutex);
}

149 150
static inline int hwrng_init(struct hwrng *rng)
{
151 152 153 154 155 156 157 158
	if (rng->init) {
		int ret;

		ret =  rng->init(rng);
		if (ret)
			return ret;
	}
	add_early_randomness(rng);
T
Torsten Duwe 已提交
159

160 161 162 163 164
	current_quality = rng->quality ? : default_quality;
	current_quality &= 1023;

	if (current_quality == 0 && hwrng_fill)
		kthread_stop(hwrng_fill);
T
Torsten Duwe 已提交
165 166 167
	if (current_quality > 0 && !hwrng_fill)
		start_khwrngd();

168
	return 0;
169 170 171 172 173 174 175 176 177 178 179 180
}

static int rng_dev_open(struct inode *inode, struct file *filp)
{
	/* enforce read-only access to this chrdev */
	if ((filp->f_mode & FMODE_READ) == 0)
		return -EINVAL;
	if (filp->f_mode & FMODE_WRITE)
		return -EINVAL;
	return 0;
}

181 182 183 184
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
			int wait) {
	int present;

185
	BUG_ON(!mutex_is_locked(&reading_mutex));
186 187 188 189 190 191 192 193 194 195 196 197 198 199
	if (rng->read)
		return rng->read(rng, (void *)buffer, size, wait);

	if (rng->data_present)
		present = rng->data_present(rng, wait);
	else
		present = 1;

	if (present)
		return rng->data_read(rng, (u32 *)buffer);

	return 0;
}

200 201 202 203
static ssize_t rng_dev_read(struct file *filp, char __user *buf,
			    size_t size, loff_t *offp)
{
	ssize_t ret = 0;
204
	int err = 0;
205
	int bytes_read, len;
206
	struct hwrng *rng;
207 208

	while (size) {
209 210 211
		rng = get_current_rng();
		if (IS_ERR(rng)) {
			err = PTR_ERR(rng);
212
			goto out;
213
		}
214
		if (!rng) {
215
			err = -ENODEV;
216
			goto out;
217
		}
218

219
		mutex_lock(&reading_mutex);
220
		if (!data_avail) {
221
			bytes_read = rng_get_data(rng, rng_buffer,
222
				rng_buffer_size(),
223 224 225
				!(filp->f_flags & O_NONBLOCK));
			if (bytes_read < 0) {
				err = bytes_read;
226
				goto out_unlock_reading;
227 228
			}
			data_avail = bytes_read;
229
		}
230

231 232 233
		if (!data_avail) {
			if (filp->f_flags & O_NONBLOCK) {
				err = -EAGAIN;
234
				goto out_unlock_reading;
235 236 237 238 239 240 241 242 243 244 245
			}
		} else {
			len = data_avail;
			if (len > size)
				len = size;

			data_avail -= len;

			if (copy_to_user(buf + ret, rng_buffer + data_avail,
								len)) {
				err = -EFAULT;
246
				goto out_unlock_reading;
247 248 249 250
			}

			size -= len;
			ret += len;
251 252
		}

253
		mutex_unlock(&reading_mutex);
254
		put_rng(rng);
255

256 257
		if (need_resched())
			schedule_timeout_interruptible(1);
258 259 260

		if (signal_pending(current)) {
			err = -ERESTARTSYS;
261
			goto out;
262
		}
263 264 265
	}
out:
	return ret ? : err;
266

267 268
out_unlock_reading:
	mutex_unlock(&reading_mutex);
269 270
	put_rng(rng);
	goto out;
271 272 273
}


274
static const struct file_operations rng_chrdev_ops = {
275 276 277
	.owner		= THIS_MODULE,
	.open		= rng_dev_open,
	.read		= rng_dev_read,
278
	.llseek		= noop_llseek,
279 280 281 282 283
};

static struct miscdevice rng_miscdev = {
	.minor		= RNG_MISCDEV_MINOR,
	.name		= RNG_MODULE_NAME,
284
	.nodename	= "hwrng",
285 286 287 288
	.fops		= &rng_chrdev_ops,
};


289 290
static ssize_t hwrng_attr_current_store(struct device *dev,
					struct device_attribute *attr,
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
					const char *buf, size_t len)
{
	int err;
	struct hwrng *rng;

	err = mutex_lock_interruptible(&rng_mutex);
	if (err)
		return -ERESTARTSYS;
	err = -ENODEV;
	list_for_each_entry(rng, &rng_list, list) {
		if (strcmp(rng->name, buf) == 0) {
			if (rng == current_rng) {
				err = 0;
				break;
			}
			err = hwrng_init(rng);
			if (err)
				break;
309 310
			drop_current_rng();
			set_current_rng(rng);
311 312 313 314 315 316 317 318 319
			err = 0;
			break;
		}
	}
	mutex_unlock(&rng_mutex);

	return err ? : len;
}

320 321
static ssize_t hwrng_attr_current_show(struct device *dev,
				       struct device_attribute *attr,
322 323 324
				       char *buf)
{
	ssize_t ret;
325
	struct hwrng *rng;
326

327 328 329 330 331 332
	rng = get_current_rng();
	if (IS_ERR(rng))
		return PTR_ERR(rng);

	ret = snprintf(buf, PAGE_SIZE, "%s\n", rng ? rng->name : "none");
	put_rng(rng);
333 334 335 336

	return ret;
}

337 338
static ssize_t hwrng_attr_available_show(struct device *dev,
					 struct device_attribute *attr,
339 340 341 342 343 344 345 346 347 348
					 char *buf)
{
	int err;
	struct hwrng *rng;

	err = mutex_lock_interruptible(&rng_mutex);
	if (err)
		return -ERESTARTSYS;
	buf[0] = '\0';
	list_for_each_entry(rng, &rng_list, list) {
349 350
		strlcat(buf, rng->name, PAGE_SIZE);
		strlcat(buf, " ", PAGE_SIZE);
351
	}
352
	strlcat(buf, "\n", PAGE_SIZE);
353 354
	mutex_unlock(&rng_mutex);

355
	return strlen(buf);
356 357
}

358 359 360 361 362 363
static DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR,
		   hwrng_attr_current_show,
		   hwrng_attr_current_store);
static DEVICE_ATTR(rng_available, S_IRUGO,
		   hwrng_attr_available_show,
		   NULL);
364 365


366
static void unregister_miscdev(void)
367
{
368 369
	device_remove_file(rng_miscdev.this_device, &dev_attr_rng_available);
	device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current);
370
	misc_deregister(&rng_miscdev);
371 372 373 374 375 376 377 378 379
}

static int register_miscdev(void)
{
	int err;

	err = misc_register(&rng_miscdev);
	if (err)
		goto out;
380 381
	err = device_create_file(rng_miscdev.this_device,
				 &dev_attr_rng_current);
382 383
	if (err)
		goto err_misc_dereg;
384 385
	err = device_create_file(rng_miscdev.this_device,
				 &dev_attr_rng_available);
386 387 388 389 390 391
	if (err)
		goto err_remove_current;
out:
	return err;

err_remove_current:
392
	device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current);
393 394 395 396 397
err_misc_dereg:
	misc_deregister(&rng_miscdev);
	goto out;
}

T
Torsten Duwe 已提交
398 399 400 401 402
static int hwrng_fillfn(void *unused)
{
	long rc;

	while (!kthread_should_stop()) {
403 404 405 406
		struct hwrng *rng;

		rng = get_current_rng();
		if (IS_ERR(rng) || !rng)
T
Torsten Duwe 已提交
407
			break;
408
		mutex_lock(&reading_mutex);
409
		rc = rng_get_data(rng, rng_fillbuf,
T
Torsten Duwe 已提交
410
				  rng_buffer_size(), 1);
411
		mutex_unlock(&reading_mutex);
412
		put_rng(rng);
T
Torsten Duwe 已提交
413 414 415 416 417
		if (rc <= 0) {
			pr_warn("hwrng: no data available\n");
			msleep_interruptible(10000);
			continue;
		}
418
		/* Outside lock, sure, but y'know: randomness. */
T
Torsten Duwe 已提交
419
		add_hwgenerator_randomness((void *)rng_fillbuf, rc,
420
					   rc * current_quality * 8 >> 10);
T
Torsten Duwe 已提交
421
	}
422
	hwrng_fill = NULL;
T
Torsten Duwe 已提交
423 424 425 426 427 428 429 430 431 432 433 434
	return 0;
}

static void start_khwrngd(void)
{
	hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
	if (hwrng_fill == ERR_PTR(-ENOMEM)) {
		pr_err("hwrng_fill thread creation failed");
		hwrng_fill = NULL;
	}
}

435 436 437 438 439 440
int hwrng_register(struct hwrng *rng)
{
	int err = -EINVAL;
	struct hwrng *old_rng, *tmp;

	if (rng->name == NULL ||
441
	    (rng->data_read == NULL && rng->read == NULL))
442 443 444 445
		goto out;

	mutex_lock(&rng_mutex);

446 447 448 449 450 451 452
	/* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
	err = -ENOMEM;
	if (!rng_buffer) {
		rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
		if (!rng_buffer)
			goto out_unlock;
	}
T
Torsten Duwe 已提交
453 454 455 456 457 458 459
	if (!rng_fillbuf) {
		rng_fillbuf = kmalloc(rng_buffer_size(), GFP_KERNEL);
		if (!rng_fillbuf) {
			kfree(rng_buffer);
			goto out_unlock;
		}
	}
460

461 462 463 464 465 466 467 468 469 470 471 472
	/* Must not register two RNGs with the same name. */
	err = -EEXIST;
	list_for_each_entry(tmp, &rng_list, list) {
		if (strcmp(tmp->name, rng->name) == 0)
			goto out_unlock;
	}

	old_rng = current_rng;
	if (!old_rng) {
		err = hwrng_init(rng);
		if (err)
			goto out_unlock;
473
		set_current_rng(rng);
474 475
	}
	err = 0;
476
	if (!old_rng) {
477 478
		err = register_miscdev();
		if (err) {
479
			drop_current_rng();
480 481 482 483 484
			goto out_unlock;
		}
	}
	INIT_LIST_HEAD(&rng->list);
	list_add_tail(&rng->list, &rng_list);
485

486 487 488 489 490 491 492 493 494 495 496
	if (old_rng && !rng->init) {
		/*
		 * Use a new device's input to add some randomness to
		 * the system.  If this rng device isn't going to be
		 * used right away, its init function hasn't been
		 * called yet; so only use the randomness from devices
		 * that don't need an init callback.
		 */
		add_early_randomness(rng);
	}

497 498 499 500 501 502 503
out_unlock:
	mutex_unlock(&rng_mutex);
out:
	return err;
}
EXPORT_SYMBOL_GPL(hwrng_register);

504
void hwrng_unregister(struct hwrng *rng)
505 506 507 508 509
{
	mutex_lock(&rng_mutex);

	list_del(&rng->list);
	if (current_rng == rng) {
510 511 512 513 514 515 516 517
		drop_current_rng();
		if (!list_empty(&rng_list)) {
			struct hwrng *tail;

			tail = list_entry(rng_list.prev, struct hwrng, list);

			if (hwrng_init(tail) == 0)
				set_current_rng(tail);
518 519
		}
	}
520

T
Torsten Duwe 已提交
521
	if (list_empty(&rng_list)) {
522
		mutex_unlock(&rng_mutex);
523
		unregister_miscdev();
T
Torsten Duwe 已提交
524 525
		if (hwrng_fill)
			kthread_stop(hwrng_fill);
526 527
	} else
		mutex_unlock(&rng_mutex);
528
}
529
EXPORT_SYMBOL_GPL(hwrng_unregister);
530

531 532 533 534 535
static void __exit hwrng_exit(void)
{
	mutex_lock(&rng_mutex);
	BUG_ON(current_rng);
	kfree(rng_buffer);
T
Torsten Duwe 已提交
536
	kfree(rng_fillbuf);
537 538 539 540
	mutex_unlock(&rng_mutex);
}

module_exit(hwrng_exit);
541 542 543

MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
MODULE_LICENSE("GPL");