xref: /netbsd-src/external/bsd/unbound/dist/compat/getentropy_win.c (revision 01049ae6d55a7fce6c6379cd1e0c997c04dc0061)
1*01049ae6Schristos /*	$OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $	*/
23b6c3722Schristos 
33b6c3722Schristos /*
43b6c3722Schristos  * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
53b6c3722Schristos  * Copyright (c) 2014, Bob Beck <beck@obtuse.com>
63b6c3722Schristos  *
73b6c3722Schristos  * Permission to use, copy, modify, and distribute this software for any
83b6c3722Schristos  * purpose with or without fee is hereby granted, provided that the above
93b6c3722Schristos  * copyright notice and this permission notice appear in all copies.
103b6c3722Schristos  *
113b6c3722Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
123b6c3722Schristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
133b6c3722Schristos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
143b6c3722Schristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
153b6c3722Schristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
163b6c3722Schristos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
173b6c3722Schristos  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18*01049ae6Schristos  *
19*01049ae6Schristos  * Emulation of getentropy(2) as documented at:
20*01049ae6Schristos  * http://man.openbsd.org/getentropy.2
213b6c3722Schristos  */
223b6c3722Schristos 
233b6c3722Schristos #include <windows.h>
243b6c3722Schristos #include <errno.h>
253b6c3722Schristos #include <stdint.h>
263b6c3722Schristos #include <sys/types.h>
273b6c3722Schristos #include <wincrypt.h>
283b6c3722Schristos #include <process.h>
293b6c3722Schristos 
303b6c3722Schristos int	getentropy(void *buf, size_t len);
313b6c3722Schristos 
323b6c3722Schristos /*
333b6c3722Schristos  * On Windows, CryptGenRandom is supposed to be a well-seeded
343b6c3722Schristos  * cryptographically strong random number generator.
353b6c3722Schristos  */
363b6c3722Schristos int
getentropy(void * buf,size_t len)373b6c3722Schristos getentropy(void *buf, size_t len)
383b6c3722Schristos {
393b6c3722Schristos 	HCRYPTPROV provider;
403b6c3722Schristos 
413b6c3722Schristos 	if (len > 256) {
423b6c3722Schristos 		errno = EIO;
43*01049ae6Schristos 		return (-1);
443b6c3722Schristos 	}
453b6c3722Schristos 
463b6c3722Schristos 	if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
473b6c3722Schristos 	    CRYPT_VERIFYCONTEXT) == 0)
483b6c3722Schristos 		goto fail;
493b6c3722Schristos 	if (CryptGenRandom(provider, len, buf) == 0) {
503b6c3722Schristos 		CryptReleaseContext(provider, 0);
513b6c3722Schristos 		goto fail;
523b6c3722Schristos 	}
533b6c3722Schristos 	CryptReleaseContext(provider, 0);
543b6c3722Schristos 	return (0);
553b6c3722Schristos 
563b6c3722Schristos fail:
573b6c3722Schristos 	errno = EIO;
583b6c3722Schristos 	return (-1);
593b6c3722Schristos }
60