lua-arc4random

Cryptographically secure PRNG for Lua
Log | Files | Refs | README

getentropy_win.c (1743B)


      1 /*	$OpenBSD: getentropy_win.c,v 1.2 2014/07/13 13:03:09 deraadt Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org> 
      5  * Copyright (c) 2014, Bob Beck <beck@obtuse.com>
      6  *
      7  * Permission to use, copy, modify, and distribute this software for any
      8  * purpose with or without fee is hereby granted, provided that the above
      9  * copyright notice and this permission notice appear in all copies.
     10  *
     11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18  *
     19  * Emulation of getentropy(2) as documented at:
     20  * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
     21  */
     22 
     23 #include <windows.h>
     24 #include <errno.h>
     25 #include <stdint.h>
     26 #include <sys/types.h>
     27 #include <wincrypt.h>
     28 #include <process.h>
     29 
     30 int	getentropy(void *buf, size_t len);
     31 
     32 /*
     33  * On Windows, CryptGenRandom is supposed to be a well-seeded
     34  * cryptographically strong random number generator.
     35  */
     36 int
     37 getentropy(void *buf, size_t len)
     38 {
     39 	HCRYPTPROV provider;
     40 
     41 	if (len > 256) {
     42 		errno = EIO;
     43 		return -1;
     44 	}
     45 
     46 	if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
     47 	    CRYPT_VERIFYCONTEXT) == 0)
     48 		goto fail;
     49 	if (CryptGenRandom(provider, len, buf) == 0) {
     50 		CryptReleaseContext(provider, 0);
     51 		goto fail;
     52 	}
     53 	CryptReleaseContext(provider, 0);
     54 	return (0);
     55 
     56 fail:
     57 	errno = EIO;
     58 	return (-1);
     59 }