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