getentropy_win.c revision 285206
1145519Sdarrenr/*	$OpenBSD$	*/
2145510Sdarrenr
3145510Sdarrenr/*
4255332Scy * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
5145510Sdarrenr * Copyright (c) 2014, Bob Beck <beck@obtuse.com>
6145510Sdarrenr *
7145510Sdarrenr * Permission to use, copy, modify, and distribute this software for any
8255332Scy * purpose with or without fee is hereby granted, provided that the above
9145510Sdarrenr * copyright notice and this permission notice appear in all copies.
10145510Sdarrenr *
11145510Sdarrenr * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12145510Sdarrenr * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13145510Sdarrenr * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14145510Sdarrenr * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15255332Scy * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16255332Scy * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17255332Scy * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18145510Sdarrenr */
19145510Sdarrenr
20145510Sdarrenr#include <windows.h>
21145510Sdarrenr#include <errno.h>
22145510Sdarrenr#include <stdint.h>
23145510Sdarrenr#include <sys/types.h>
24145510Sdarrenr#include <wincrypt.h>
25145510Sdarrenr#include <process.h>
26145510Sdarrenr
27145510Sdarrenrint	getentropy(void *buf, size_t len);
28145510Sdarrenr
29145510Sdarrenr/*
30145510Sdarrenr * On Windows, CryptGenRandom is supposed to be a well-seeded
31145510Sdarrenr * cryptographically strong random number generator.
32145510Sdarrenr */
33145510Sdarrenrint
34145510Sdarrenrgetentropy(void *buf, size_t len)
35145510Sdarrenr{
36145510Sdarrenr	HCRYPTPROV provider;
37145510Sdarrenr
38145510Sdarrenr	if (len > 256) {
39145510Sdarrenr		errno = EIO;
40145510Sdarrenr		return -1;
41145510Sdarrenr	}
42145510Sdarrenr
43145510Sdarrenr	if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
44145510Sdarrenr	    CRYPT_VERIFYCONTEXT) == 0)
45145510Sdarrenr		goto fail;
46145510Sdarrenr	if (CryptGenRandom(provider, len, buf) == 0) {
47145510Sdarrenr		CryptReleaseContext(provider, 0);
48145510Sdarrenr		goto fail;
49145510Sdarrenr	}
50145510Sdarrenr	CryptReleaseContext(provider, 0);
51145510Sdarrenr	return (0);
52145510Sdarrenr
53145510Sdarrenrfail:
54145510Sdarrenr	errno = EIO;
55145510Sdarrenr	return (-1);
56145510Sdarrenr}
57145510Sdarrenr