| Line | Count | Source | 
| 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 | 851k | { | 
| 54 | 851k |         ssize_t r; | 
| 55 |  |  | 
| 56 | 851k |         if ((r = getrandom(buf, len, 0)) < 0 || (size_t)r != len) | 
| 57 | 2.09k |                 return (-1); | 
| 58 |  |  | 
| 59 | 849k |         return (0); | 
| 60 | 851k | } | 
| 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 */ |