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