core.c 11.7 KB
Newer Older
1
/*
C
Corentin LABBE 已提交
2 3 4 5 6 7 8 9 10
 * hw_random/core.c: HWRNG core API
 *
 * Copyright 2006 Michael Buesch <m@bues.ch>
 * 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.
11 12
 */

13
#include <linux/delay.h>
14
#include <linux/device.h>
15 16
#include <linux/err.h>
#include <linux/fs.h>
17 18
#include <linux/hw_random.h>
#include <linux/kernel.h>
T
Torsten Duwe 已提交
19
#include <linux/kthread.h>
20 21
#include <linux/miscdevice.h>
#include <linux/module.h>
22
#include <linux/random.h>
23 24
#include <linux/sched.h>
#include <linux/slab.h>
25
#include <linux/uaccess.h>
26 27 28 29 30 31

#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 已提交
32
static struct task_struct *hwrng_fill;
33
static LIST_HEAD(rng_list);
34
/* Protects rng_list and current_rng */
35
static DEFINE_MUTEX(rng_mutex);
36 37
/* Protects rng read functions, data_avail, rng_buffer and rng_fillbuf */
static DEFINE_MUTEX(reading_mutex);
38
static int data_avail;
T
Torsten Duwe 已提交
39
static u8 *rng_buffer, *rng_fillbuf;
40 41
static unsigned short current_quality;
static unsigned short default_quality; /* = 0; default to "off" */
T
Torsten Duwe 已提交
42 43 44 45

module_param(current_quality, ushort, 0644);
MODULE_PARM_DESC(current_quality,
		 "current hwrng entropy estimation per mill");
46 47 48
module_param(default_quality, ushort, 0644);
MODULE_PARM_DESC(default_quality,
		 "default entropy content of hwrng per mill");
T
Torsten Duwe 已提交
49

50
static void drop_current_rng(void);
51
static int hwrng_init(struct hwrng *rng);
T
Torsten Duwe 已提交
52
static void start_khwrngd(void);
53

54 55 56
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
			       int wait);

57 58 59 60
static size_t rng_buffer_size(void)
{
	return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
}
61

62 63 64
static void add_early_randomness(struct hwrng *rng)
{
	int bytes_read;
65
	size_t size = min_t(size_t, 16, rng_buffer_size());
66

67
	mutex_lock(&reading_mutex);
68
	bytes_read = rng_get_data(rng, rng_buffer, size, 1);
69
	mutex_unlock(&reading_mutex);
70
	if (bytes_read > 0)
71
		add_device_randomness(rng_buffer, bytes_read);
72
	memset(rng_buffer, 0, size);
73 74
}

75 76 77 78 79 80
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 已提交
81

82
	complete(&rng->cleanup_done);
83 84
}

85
static int set_current_rng(struct hwrng *rng)
86
{
87 88
	int err;

89
	BUG_ON(!mutex_is_locked(&rng_mutex));
90 91 92 93 94

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

95
	drop_current_rng();
96
	current_rng = rng;
97 98

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

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

140
static int hwrng_init(struct hwrng *rng)
141
{
142 143 144
	if (kref_get_unless_zero(&rng->ref))
		goto skip_init;

145 146 147 148 149 150 151
	if (rng->init) {
		int ret;

		ret =  rng->init(rng);
		if (ret)
			return ret;
	}
152 153 154 155 156

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

skip_init:
157
	add_early_randomness(rng);
T
Torsten Duwe 已提交
158

159
	current_quality = rng->quality ? : default_quality;
160 161
	if (current_quality > 1024)
		current_quality = 1024;
162 163 164

	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 220 221 222
		if (mutex_lock_interruptible(&reading_mutex)) {
			err = -ERESTARTSYS;
			goto out_put;
		}
223
		if (!data_avail) {
224
			bytes_read = rng_get_data(rng, rng_buffer,
225
				rng_buffer_size(),
226 227 228
				!(filp->f_flags & O_NONBLOCK));
			if (bytes_read < 0) {
				err = bytes_read;
229
				goto out_unlock_reading;
230 231
			}
			data_avail = bytes_read;
232
		}
233

234 235 236
		if (!data_avail) {
			if (filp->f_flags & O_NONBLOCK) {
				err = -EAGAIN;
237
				goto out_unlock_reading;
238 239 240 241 242 243 244 245 246 247 248
			}
		} 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;
249
				goto out_unlock_reading;
250 251 252 253
			}

			size -= len;
			ret += len;
254 255
		}

256
		mutex_unlock(&reading_mutex);
257
		put_rng(rng);
258

259 260
		if (need_resched())
			schedule_timeout_interruptible(1);
261 262 263

		if (signal_pending(current)) {
			err = -ERESTARTSYS;
264
			goto out;
265
		}
266 267
	}
out:
268
	memset(rng_buffer, 0, rng_buffer_size());
269
	return ret ? : err;
270

271 272
out_unlock_reading:
	mutex_unlock(&reading_mutex);
273
out_put:
274 275
	put_rng(rng);
	goto out;
276 277
}

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

285 286
static const struct attribute_group *rng_dev_groups[];

287 288 289
static struct miscdevice rng_miscdev = {
	.minor		= RNG_MISCDEV_MINOR,
	.name		= RNG_MODULE_NAME,
290
	.nodename	= "hwrng",
291
	.fops		= &rng_chrdev_ops,
292
	.groups		= rng_dev_groups,
293 294
};

295 296
static ssize_t hwrng_attr_current_store(struct device *dev,
					struct device_attribute *attr,
297 298 299 300 301 302 303 304 305 306
					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) {
307
		if (sysfs_streq(rng->name, buf)) {
308
			err = 0;
309 310
			if (rng != current_rng)
				err = set_current_rng(rng);
311 312 313 314 315 316 317 318
			break;
		}
	}
	mutex_unlock(&rng_mutex);

	return err ? : len;
}

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

326 327 328 329 330 331
	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);
332 333 334 335

	return ret;
}

336 337
static ssize_t hwrng_attr_available_show(struct device *dev,
					 struct device_attribute *attr,
338 339 340 341 342 343 344 345 346 347
					 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) {
348 349
		strlcat(buf, rng->name, PAGE_SIZE);
		strlcat(buf, " ", PAGE_SIZE);
350
	}
351
	strlcat(buf, "\n", PAGE_SIZE);
352 353
	mutex_unlock(&rng_mutex);

354
	return strlen(buf);
355 356
}

357 358 359 360 361 362
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);
363

364 365 366 367 368 369 370
static struct attribute *rng_dev_attrs[] = {
	&dev_attr_rng_current.attr,
	&dev_attr_rng_available.attr,
	NULL
};

ATTRIBUTE_GROUPS(rng_dev);
371

372
static void __exit unregister_miscdev(void)
373
{
374
	misc_deregister(&rng_miscdev);
375 376
}

377
static int __init register_miscdev(void)
378
{
379
	return misc_register(&rng_miscdev);
380 381
}

T
Torsten Duwe 已提交
382 383 384 385 386
static int hwrng_fillfn(void *unused)
{
	long rc;

	while (!kthread_should_stop()) {
387 388 389 390
		struct hwrng *rng;

		rng = get_current_rng();
		if (IS_ERR(rng) || !rng)
T
Torsten Duwe 已提交
391
			break;
392
		mutex_lock(&reading_mutex);
393
		rc = rng_get_data(rng, rng_fillbuf,
T
Torsten Duwe 已提交
394
				  rng_buffer_size(), 1);
395
		mutex_unlock(&reading_mutex);
396
		put_rng(rng);
T
Torsten Duwe 已提交
397 398 399 400 401
		if (rc <= 0) {
			pr_warn("hwrng: no data available\n");
			msleep_interruptible(10000);
			continue;
		}
402
		/* Outside lock, sure, but y'know: randomness. */
T
Torsten Duwe 已提交
403
		add_hwgenerator_randomness((void *)rng_fillbuf, rc,
404
					   rc * current_quality * 8 >> 10);
405
		memset(rng_fillbuf, 0, rng_buffer_size());
T
Torsten Duwe 已提交
406
	}
407
	hwrng_fill = NULL;
T
Torsten Duwe 已提交
408 409 410 411 412 413
	return 0;
}

static void start_khwrngd(void)
{
	hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
414
	if (IS_ERR(hwrng_fill)) {
T
Torsten Duwe 已提交
415 416 417 418 419
		pr_err("hwrng_fill thread creation failed");
		hwrng_fill = NULL;
	}
}

420 421 422 423 424
int hwrng_register(struct hwrng *rng)
{
	int err = -EINVAL;
	struct hwrng *old_rng, *tmp;

425
	if (!rng->name || (!rng->data_read && !rng->read))
426 427 428 429 430 431 432 433 434 435
		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;
	}

436 437 438
	init_completion(&rng->cleanup_done);
	complete(&rng->cleanup_done);

439
	old_rng = current_rng;
R
Rusty Russell 已提交
440
	err = 0;
441
	if (!old_rng) {
442
		err = set_current_rng(rng);
443 444 445 446
		if (err)
			goto out_unlock;
	}
	list_add_tail(&rng->list, &rng_list);
447

448 449 450 451 452 453 454 455 456 457 458
	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);
	}

459 460 461 462 463 464 465
out_unlock:
	mutex_unlock(&rng_mutex);
out:
	return err;
}
EXPORT_SYMBOL_GPL(hwrng_register);

466
void hwrng_unregister(struct hwrng *rng)
467 468 469 470 471
{
	mutex_lock(&rng_mutex);

	list_del(&rng->list);
	if (current_rng == rng) {
472 473 474 475 476 477
		drop_current_rng();
		if (!list_empty(&rng_list)) {
			struct hwrng *tail;

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

478
			set_current_rng(tail);
479 480
		}
	}
481

T
Torsten Duwe 已提交
482
	if (list_empty(&rng_list)) {
483
		mutex_unlock(&rng_mutex);
T
Torsten Duwe 已提交
484 485
		if (hwrng_fill)
			kthread_stop(hwrng_fill);
486 487
	} else
		mutex_unlock(&rng_mutex);
R
Rusty Russell 已提交
488

489
	wait_for_completion(&rng->cleanup_done);
490
}
491
EXPORT_SYMBOL_GPL(hwrng_unregister);
492

D
Dmitry Torokhov 已提交
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
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);

535 536
static int __init hwrng_modinit(void)
{
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
	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;
557 558 559
}

static void __exit hwrng_modexit(void)
560 561 562 563
{
	mutex_lock(&rng_mutex);
	BUG_ON(current_rng);
	kfree(rng_buffer);
T
Torsten Duwe 已提交
564
	kfree(rng_fillbuf);
565
	mutex_unlock(&rng_mutex);
566 567

	unregister_miscdev();
568 569
}

570 571
module_init(hwrng_modinit);
module_exit(hwrng_modexit);
572 573 574

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