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 30 int 31 fido_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) 44 int 45 fido_get_random(void *buf, size_t len) 46 { 47 arc4random_buf(buf, len); 48 return (0); 49 } 50 #elif defined(HAVE_GETRANDOM) 51 int 52 fido_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) 62 int 63 fido_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; 75 fail: 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