core.c 12.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 drop_current_rng(void);
74
static int hwrng_init(struct hwrng *rng);
T
Torsten Duwe 已提交
75
static void start_khwrngd(void);
76

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

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

85 86 87
static void add_early_randomness(struct hwrng *rng)
{
	int bytes_read;
88
	size_t size = min_t(size_t, 16, rng_buffer_size());
89

90
	mutex_lock(&reading_mutex);
91
	bytes_read = rng_get_data(rng, rng_buffer, size, 1);
92
	mutex_unlock(&reading_mutex);
93
	if (bytes_read > 0)
94
		add_device_randomness(rng_buffer, bytes_read);
95
	memset(rng_buffer, 0, size);
96 97
}

98 99 100 101 102 103
static inline void cleanup_rng(struct kref *kref)
{
	struct hwrng *rng = container_of(kref, struct hwrng, ref);

	if (rng->cleanup)
		rng->cleanup(rng);
R
Rusty Russell 已提交
104

105
	complete(&rng->cleanup_done);
106 107
}

108
static int set_current_rng(struct hwrng *rng)
109
{
110 111
	int err;

112
	BUG_ON(!mutex_is_locked(&rng_mutex));
113 114 115 116 117

	err = hwrng_init(rng);
	if (err)
		return err;

118
	drop_current_rng();
119
	current_rng = rng;
120 121

	return 0;
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 149 150 151 152 153 154 155 156 157 158 159 160 161 162
}

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);
}

163
static int hwrng_init(struct hwrng *rng)
164
{
165 166 167
	if (kref_get_unless_zero(&rng->ref))
		goto skip_init;

168 169 170 171 172 173 174
	if (rng->init) {
		int ret;

		ret =  rng->init(rng);
		if (ret)
			return ret;
	}
175 176 177 178 179

	kref_init(&rng->ref);
	reinit_completion(&rng->cleanup_done);

skip_init:
180
	add_early_randomness(rng);
T
Torsten Duwe 已提交
181

182
	current_quality = rng->quality ? : default_quality;
183 184
	if (current_quality > 1024)
		current_quality = 1024;
185 186 187

	if (current_quality == 0 && hwrng_fill)
		kthread_stop(hwrng_fill);
T
Torsten Duwe 已提交
188 189 190
	if (current_quality > 0 && !hwrng_fill)
		start_khwrngd();

191
	return 0;
192 193 194 195 196 197 198 199 200 201 202 203
}

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;
}

204 205 206 207
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
			int wait) {
	int present;

208
	BUG_ON(!mutex_is_locked(&reading_mutex));
209 210 211 212 213 214 215 216 217 218 219 220 221 222
	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;
}

223 224 225 226
static ssize_t rng_dev_read(struct file *filp, char __user *buf,
			    size_t size, loff_t *offp)
{
	ssize_t ret = 0;
227
	int err = 0;
228
	int bytes_read, len;
229
	struct hwrng *rng;
230 231

	while (size) {
232 233 234
		rng = get_current_rng();
		if (IS_ERR(rng)) {
			err = PTR_ERR(rng);
235
			goto out;
236
		}
237
		if (!rng) {
238
			err = -ENODEV;
239
			goto out;
240
		}
241

242 243 244 245
		if (mutex_lock_interruptible(&reading_mutex)) {
			err = -ERESTARTSYS;
			goto out_put;
		}
246
		if (!data_avail) {
247
			bytes_read = rng_get_data(rng, rng_buffer,
248
				rng_buffer_size(),
249 250 251
				!(filp->f_flags & O_NONBLOCK));
			if (bytes_read < 0) {
				err = bytes_read;
252
				goto out_unlock_reading;
253 254
			}
			data_avail = bytes_read;
255
		}
256

257 258 259
		if (!data_avail) {
			if (filp->f_flags & O_NONBLOCK) {
				err = -EAGAIN;
260
				goto out_unlock_reading;
261 262 263 264 265 266 267 268 269 270 271
			}
		} 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;
272
				goto out_unlock_reading;
273 274 275 276
			}

			size -= len;
			ret += len;
277 278
		}

279
		mutex_unlock(&reading_mutex);
280
		put_rng(rng);
281

282 283
		if (need_resched())
			schedule_timeout_interruptible(1);
284 285 286

		if (signal_pending(current)) {
			err = -ERESTARTSYS;
287
			goto out;
288
		}
289 290
	}
out:
291
	memset(rng_buffer, 0, rng_buffer_size());
292
	return ret ? : err;
293

294 295
out_unlock_reading:
	mutex_unlock(&reading_mutex);
296
out_put:
297 298
	put_rng(rng);
	goto out;
299 300 301
}


302
static const struct file_operations rng_chrdev_ops = {
303 304 305
	.owner		= THIS_MODULE,
	.open		= rng_dev_open,
	.read		= rng_dev_read,
306
	.llseek		= noop_llseek,
307 308
};

309 310
static const struct attribute_group *rng_dev_groups[];

311 312 313
static struct miscdevice rng_miscdev = {
	.minor		= RNG_MISCDEV_MINOR,
	.name		= RNG_MODULE_NAME,
314
	.nodename	= "hwrng",
315
	.fops		= &rng_chrdev_ops,
316
	.groups		= rng_dev_groups,
317 318 319
};


320 321
static ssize_t hwrng_attr_current_store(struct device *dev,
					struct device_attribute *attr,
322 323 324 325 326 327 328 329 330 331
					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) {
332
		if (sysfs_streq(rng->name, buf)) {
333
			err = 0;
334 335
			if (rng != current_rng)
				err = set_current_rng(rng);
336 337 338 339 340 341 342 343
			break;
		}
	}
	mutex_unlock(&rng_mutex);

	return err ? : len;
}

344 345
static ssize_t hwrng_attr_current_show(struct device *dev,
				       struct device_attribute *attr,
346 347 348
				       char *buf)
{
	ssize_t ret;
349
	struct hwrng *rng;
350

351 352 353 354 355 356
	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);
357 358 359 360

	return ret;
}

361 362
static ssize_t hwrng_attr_available_show(struct device *dev,
					 struct device_attribute *attr,
363 364 365 366 367 368 369 370 371 372
					 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) {
373 374
		strlcat(buf, rng->name, PAGE_SIZE);
		strlcat(buf, " ", PAGE_SIZE);
375
	}
376
	strlcat(buf, "\n", PAGE_SIZE);
377 378
	mutex_unlock(&rng_mutex);

379
	return strlen(buf);
380 381
}

382 383 384 385 386 387
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);
388

389 390 391 392 393 394 395
static struct attribute *rng_dev_attrs[] = {
	&dev_attr_rng_current.attr,
	&dev_attr_rng_available.attr,
	NULL
};

ATTRIBUTE_GROUPS(rng_dev);
396

397
static void __exit unregister_miscdev(void)
398
{
399
	misc_deregister(&rng_miscdev);
400 401
}

402
static int __init register_miscdev(void)
403
{
404
	return misc_register(&rng_miscdev);
405 406
}

T
Torsten Duwe 已提交
407 408 409 410 411
static int hwrng_fillfn(void *unused)
{
	long rc;

	while (!kthread_should_stop()) {
412 413 414 415
		struct hwrng *rng;

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

static void start_khwrngd(void)
{
	hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
439
	if (IS_ERR(hwrng_fill)) {
T
Torsten Duwe 已提交
440 441 442 443 444
		pr_err("hwrng_fill thread creation failed");
		hwrng_fill = NULL;
	}
}

445 446 447 448 449 450
int hwrng_register(struct hwrng *rng)
{
	int err = -EINVAL;
	struct hwrng *old_rng, *tmp;

	if (rng->name == NULL ||
451
	    (rng->data_read == NULL && rng->read == NULL))
452 453 454 455 456 457 458 459 460 461
		goto out;

	mutex_lock(&rng_mutex);
	/* 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;
	}

462 463 464
	init_completion(&rng->cleanup_done);
	complete(&rng->cleanup_done);

465
	old_rng = current_rng;
R
Rusty Russell 已提交
466
	err = 0;
467
	if (!old_rng) {
468
		err = set_current_rng(rng);
469 470 471 472
		if (err)
			goto out_unlock;
	}
	list_add_tail(&rng->list, &rng_list);
473

474 475 476 477 478 479 480 481 482 483 484
	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);
	}

485 486 487 488 489 490 491
out_unlock:
	mutex_unlock(&rng_mutex);
out:
	return err;
}
EXPORT_SYMBOL_GPL(hwrng_register);

492
void hwrng_unregister(struct hwrng *rng)
493 494 495 496 497
{
	mutex_lock(&rng_mutex);

	list_del(&rng->list);
	if (current_rng == rng) {
498 499 500 501 502 503
		drop_current_rng();
		if (!list_empty(&rng_list)) {
			struct hwrng *tail;

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

504
			set_current_rng(tail);
505 506
		}
	}
507

T
Torsten Duwe 已提交
508
	if (list_empty(&rng_list)) {
509
		mutex_unlock(&rng_mutex);
T
Torsten Duwe 已提交
510 511
		if (hwrng_fill)
			kthread_stop(hwrng_fill);
512 513
	} else
		mutex_unlock(&rng_mutex);
R
Rusty Russell 已提交
514

515
	wait_for_completion(&rng->cleanup_done);
516
}
517
EXPORT_SYMBOL_GPL(hwrng_unregister);
518

D
Dmitry Torokhov 已提交
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
static void devm_hwrng_release(struct device *dev, void *res)
{
	hwrng_unregister(*(struct hwrng **)res);
}

static int devm_hwrng_match(struct device *dev, void *res, void *data)
{
	struct hwrng **r = res;

	if (WARN_ON(!r || !*r))
		return 0;

	return *r == data;
}

int devm_hwrng_register(struct device *dev, struct hwrng *rng)
{
	struct hwrng **ptr;
	int error;

	ptr = devres_alloc(devm_hwrng_release, sizeof(*ptr), GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;

	error = hwrng_register(rng);
	if (error) {
		devres_free(ptr);
		return error;
	}

	*ptr = rng;
	devres_add(dev, ptr);
	return 0;
}
EXPORT_SYMBOL_GPL(devm_hwrng_register);

void devm_hwrng_unregister(struct device *dev, struct hwrng *rng)
{
	devres_release(dev, devm_hwrng_release, devm_hwrng_match, rng);
}
EXPORT_SYMBOL_GPL(devm_hwrng_unregister);

561 562
static int __init hwrng_modinit(void)
{
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
	int ret = -ENOMEM;

	/* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
	rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
	if (!rng_buffer)
		return -ENOMEM;

	rng_fillbuf = kmalloc(rng_buffer_size(), GFP_KERNEL);
	if (!rng_fillbuf) {
		kfree(rng_buffer);
		return -ENOMEM;
	}

	ret = register_miscdev();
	if (ret) {
		kfree(rng_fillbuf);
		kfree(rng_buffer);
	}

	return ret;
583 584 585
}

static void __exit hwrng_modexit(void)
586 587 588 589
{
	mutex_lock(&rng_mutex);
	BUG_ON(current_rng);
	kfree(rng_buffer);
T
Torsten Duwe 已提交
590
	kfree(rng_fillbuf);
591
	mutex_unlock(&rng_mutex);
592 593

	unregister_miscdev();
594 595
}

596 597
module_init(hwrng_modinit);
module_exit(hwrng_modexit);
598 599 600

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