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