xref: /llvm-project/libc/src/unistd/windows/getentropy.cpp (revision defd0d966d5ebae37787e76b86f2f2ff2a5cfd59)
1*defd0d96SSchrodinger ZHU Yifan //===-- Windows implementation of getentropy ------------------------------===//
2*defd0d96SSchrodinger ZHU Yifan //
3*defd0d96SSchrodinger ZHU Yifan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*defd0d96SSchrodinger ZHU Yifan // See https://llvm.org/LICENSE.txt for license information.
5*defd0d96SSchrodinger ZHU Yifan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*defd0d96SSchrodinger ZHU Yifan //
7*defd0d96SSchrodinger ZHU Yifan //===----------------------------------------------------------------------===//
8*defd0d96SSchrodinger ZHU Yifan 
9*defd0d96SSchrodinger ZHU Yifan #include "src/unistd/getentropy.h"
10*defd0d96SSchrodinger ZHU Yifan #include "hdr/errno_macros.h"
11*defd0d96SSchrodinger ZHU Yifan #include "src/__support/common.h"
12*defd0d96SSchrodinger ZHU Yifan #include "src/errno/libc_errno.h"
13*defd0d96SSchrodinger ZHU Yifan 
14*defd0d96SSchrodinger ZHU Yifan #define WIN32_LEAN_AND_MEAN
15*defd0d96SSchrodinger ZHU Yifan #include <Windows.h>
16*defd0d96SSchrodinger ZHU Yifan #include <bcrypt.h>
17*defd0d96SSchrodinger ZHU Yifan #include <ntstatus.h>
18*defd0d96SSchrodinger ZHU Yifan #pragma comment(lib, "bcrypt.lib")
19*defd0d96SSchrodinger ZHU Yifan 
20*defd0d96SSchrodinger ZHU Yifan namespace LIBC_NAMESPACE_DECL {
21*defd0d96SSchrodinger ZHU Yifan 
22*defd0d96SSchrodinger ZHU Yifan LLVM_LIBC_FUNCTION(int, getentropy, (void *buffer, size_t length)) {
23*defd0d96SSchrodinger ZHU Yifan   __try {
24*defd0d96SSchrodinger ZHU Yifan     // check the length limit
25*defd0d96SSchrodinger ZHU Yifan     if (length > 256)
26*defd0d96SSchrodinger ZHU Yifan       __leave;
27*defd0d96SSchrodinger ZHU Yifan 
28*defd0d96SSchrodinger ZHU Yifan     NTSTATUS result = ::BCryptGenRandom(nullptr, static_cast<PUCHAR>(buffer),
29*defd0d96SSchrodinger ZHU Yifan                                         static_cast<ULONG>(length),
30*defd0d96SSchrodinger ZHU Yifan                                         BCRYPT_USE_SYSTEM_PREFERRED_RNG);
31*defd0d96SSchrodinger ZHU Yifan 
32*defd0d96SSchrodinger ZHU Yifan     if (result == STATUS_SUCCESS)
33*defd0d96SSchrodinger ZHU Yifan       return 0;
34*defd0d96SSchrodinger ZHU Yifan 
35*defd0d96SSchrodinger ZHU Yifan   } __except (EXCEPTION_EXECUTE_HANDLER) {
36*defd0d96SSchrodinger ZHU Yifan     // no need to handle exceptions specially
37*defd0d96SSchrodinger ZHU Yifan   }
38*defd0d96SSchrodinger ZHU Yifan 
39*defd0d96SSchrodinger ZHU Yifan   libc_errno = EIO;
40*defd0d96SSchrodinger ZHU Yifan   return -1;
41*defd0d96SSchrodinger ZHU Yifan }
42*defd0d96SSchrodinger ZHU Yifan } // namespace LIBC_NAMESPACE_DECL
43