1/*
2 * Copyright (c) 2018 Yubico AB. All rights reserved.
3 * Use of this source code is governed by a BSD-style
4 * license that can be found in the LICENSE file.
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <sys/types.h>
9#include <sys/stat.h>
10#ifdef HAVE_SYS_RANDOM_H
11#include <sys/random.h>
12#endif
13
14#include <fcntl.h>
15#ifdef HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#include "fido.h"
20
21#if defined(_WIN32)
22#include <windows.h>
23
24#include <winternl.h>
25#include <winerror.h>
26#include <stdio.h>
27#include <bcrypt.h>
28#include <sal.h>
29
30int
31fido_get_random(void *buf, size_t len)
32{
33	NTSTATUS status;
34
35	status = BCryptGenRandom(NULL, buf, (ULONG)len,
36	    BCRYPT_USE_SYSTEM_PREFERRED_RNG);
37
38	if (!NT_SUCCESS(status))
39		return (-1);
40
41	return (0);
42}
43#elif defined(HAVE_ARC4RANDOM_BUF)
44int
45fido_get_random(void *buf, size_t len)
46{
47	arc4random_buf(buf, len);
48	return (0);
49}
50#elif defined(HAVE_GETRANDOM)
51int
52fido_get_random(void *buf, size_t len)
53{
54	ssize_t	r;
55
56	if ((r = getrandom(buf, len, 0)) < 0 || (size_t)r != len)
57		return (-1);
58
59	return (0);
60}
61#elif defined(HAVE_DEV_URANDOM)
62int
63fido_get_random(void *buf, size_t len)
64{
65	int	fd = -1;
66	int	ok = -1;
67	ssize_t	r;
68
69	if ((fd = open(FIDO_RANDOM_DEV, O_RDONLY)) < 0)
70		goto fail;
71	if ((r = read(fd, buf, len)) < 0 || (size_t)r != len)
72		goto fail;
73
74	ok = 0;
75fail:
76	if (fd != -1)
77		close(fd);
78
79	return (ok);
80}
81#else
82#error "please provide an implementation of fido_get_random() for your platform"
83#endif /* _WIN32 */
84