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
	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>
38
#include <linux/sched.h>
39
#include <linux/miscdevice.h>
T
Torsten Duwe 已提交
40
#include <linux/kthread.h>
41
#include <linux/delay.h>
42
#include <linux/slab.h>
43
#include <linux/random.h>
44
#include <linux/err.h>
45
#include <linux/uaccess.h>
46 47 48 49 50 51

#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 已提交
52
static struct task_struct *hwrng_fill;
53
static LIST_HEAD(rng_list);
54
/* Protects rng_list and current_rng */
55
static DEFINE_MUTEX(rng_mutex);
56 57
/* Protects rng read functions, data_avail, rng_buffer and rng_fillbuf */
static DEFINE_MUTEX(reading_mutex);
58
static int data_avail;
T
Torsten Duwe 已提交
59
static u8 *rng_buffer, *rng_fillbuf;
60 61
static unsigned short current_quality;
static unsigned short default_quality; /* = 0; default to "off" */
T
Torsten Duwe 已提交
62 63 64 65

module_param(current_quality, ushort, 0644);
MODULE_PARM_DESC(current_quality,
		 "current hwrng entropy estimation per mill");
66 67 68
module_param(default_quality, ushort, 0644);
MODULE_PARM_DESC(default_quality,
		 "default entropy content of hwrng per mill");
T
Torsten Duwe 已提交
69

70
static void drop_current_rng(void);
71
static int hwrng_init(struct hwrng *rng);
T
Torsten Duwe 已提交
72
static void start_khwrngd(void);
73

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

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

82 83 84
static void add_early_randomness(struct hwrng *rng)
{
	int bytes_read;
85
	size_t size = min_t(size_t, 16, rng_buffer_size());
86

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

95 96 97 98 99 100
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 已提交
101

102
	complete(&rng->cleanup_done);
103 104
}

105
static int set_current_rng(struct hwrng *rng)
106
{
107 108
	int err;

109
	BUG_ON(!mutex_is_locked(&rng_mutex));
110 111 112 113 114

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

115
	drop_current_rng();
116
	current_rng = rng;
117 118

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

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

160
static int hwrng_init(struct hwrng *rng)
161
{
162 163 164
	if (kref_get_unless_zero(&rng->ref))
		goto skip_init;

165 166 167 168 169 170 171
	if (rng->init) {
		int ret;

		ret =  rng->init(rng);
		if (ret)
			return ret;
	}
172 173 174 175 176

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

skip_init:
177
	add_early_randomness(rng);
T
Torsten Duwe 已提交
178

179
	current_quality = rng->quality ? : default_quality;
180 181
	if (current_quality > 1024)
		current_quality = 1024;
182 183 184

	if (current_quality == 0 && hwrng_fill)
		kthread_stop(hwrng_fill);
T
Torsten Duwe 已提交
185 186 187
	if (current_quality > 0 && !hwrng_fill)
		start_khwrngd();

188
	return 0;
189 190 191 192 193 194 195 196 197 198 199 200
}

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

201 202 203 204
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
			int wait) {
	int present;

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

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

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

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

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

			size -= len;
			ret += len;
274 275
		}

276
		mutex_unlock(&reading_mutex);
277
		put_rng(rng);
278

279 280
		if (need_resched())
			schedule_timeout_interruptible(1);
281 282 283

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

291 292
out_unlock_reading:
	mutex_unlock(&reading_mutex);
293
out_put:
294 295
	put_rng(rng);
	goto out;
296 297
}

298
static const struct file_operations rng_chrdev_ops = {
299 300 301
	.owner		= THIS_MODULE,
	.open		= rng_dev_open,
	.read		= rng_dev_read,
302
	.llseek		= noop_llseek,
303 304
};

305 306
static const struct attribute_group *rng_dev_groups[];

307 308 309
static struct miscdevice rng_miscdev = {
	.minor		= RNG_MISCDEV_MINOR,
	.name		= RNG_MODULE_NAME,
310
	.nodename	= "hwrng",
311
	.fops		= &rng_chrdev_ops,
312
	.groups		= rng_dev_groups,
313 314
};

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

	return err ? : len;
}

339 340
static ssize_t hwrng_attr_current_show(struct device *dev,
				       struct device_attribute *attr,
341 342 343
				       char *buf)
{
	ssize_t ret;
344
	struct hwrng *rng;
345

346 347 348 349 350 351
	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);
352 353 354 355

	return ret;
}

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

374
	return strlen(buf);
375 376
}

377 378 379 380 381 382
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);
383

384 385 386 387 388 389 390
static struct attribute *rng_dev_attrs[] = {
	&dev_attr_rng_current.attr,
	&dev_attr_rng_available.attr,
	NULL
};

ATTRIBUTE_GROUPS(rng_dev);
391

392
static void __exit unregister_miscdev(void)
393
{
394
	misc_deregister(&rng_miscdev);
395 396
}

397
static int __init register_miscdev(void)
398
{
399
	return misc_register(&rng_miscdev);
400 401
}

T
Torsten Duwe 已提交
402 403 404 405 406
static int hwrng_fillfn(void *unused)
{
	long rc;

	while (!kthread_should_stop()) {
407 408 409 410
		struct hwrng *rng;

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

static void start_khwrngd(void)
{
	hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
434
	if (IS_ERR(hwrng_fill)) {
T
Torsten Duwe 已提交
435 436 437 438 439
		pr_err("hwrng_fill thread creation failed");
		hwrng_fill = NULL;
	}
}

440 441 442 443 444
int hwrng_register(struct hwrng *rng)
{
	int err = -EINVAL;
	struct hwrng *old_rng, *tmp;

445
	if (!rng->name || (!rng->data_read && !rng->read))
446 447 448 449 450 451 452 453 454 455
		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;
	}

456 457 458
	init_completion(&rng->cleanup_done);
	complete(&rng->cleanup_done);

459
	old_rng = current_rng;
R
Rusty Russell 已提交
460
	err = 0;
461
	if (!old_rng) {
462
		err = set_current_rng(rng);
463 464 465 466
		if (err)
			goto out_unlock;
	}
	list_add_tail(&rng->list, &rng_list);
467

468 469 470 471 472 473 474 475 476 477 478
	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);
	}

479 480 481 482 483 484 485
out_unlock:
	mutex_unlock(&rng_mutex);
out:
	return err;
}
EXPORT_SYMBOL_GPL(hwrng_register);

486
void hwrng_unregister(struct hwrng *rng)
487 488 489 490 491
{
	mutex_lock(&rng_mutex);

	list_del(&rng->list);
	if (current_rng == rng) {
492 493 494 495 496 497
		drop_current_rng();
		if (!list_empty(&rng_list)) {
			struct hwrng *tail;

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

498
			set_current_rng(tail);
499 500
		}
	}
501

T
Torsten Duwe 已提交
502
	if (list_empty(&rng_list)) {
503
		mutex_unlock(&rng_mutex);
T
Torsten Duwe 已提交
504 505
		if (hwrng_fill)
			kthread_stop(hwrng_fill);
506 507
	} else
		mutex_unlock(&rng_mutex);
R
Rusty Russell 已提交
508

509
	wait_for_completion(&rng->cleanup_done);
510
}
511
EXPORT_SYMBOL_GPL(hwrng_unregister);
512

D
Dmitry Torokhov 已提交
513 514 515 516 517 518 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
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);

555 556
static int __init hwrng_modinit(void)
{
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
	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;
577 578 579
}

static void __exit hwrng_modexit(void)
580 581 582 583
{
	mutex_lock(&rng_mutex);
	BUG_ON(current_rng);
	kfree(rng_buffer);
T
Torsten Duwe 已提交
584
	kfree(rng_fillbuf);
585
	mutex_unlock(&rng_mutex);
586 587

	unregister_miscdev();
588 589
}

590 591
module_init(hwrng_modinit);
module_exit(hwrng_modexit);
592 593 594

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