195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (c) 2014, Google Inc. 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Permission to use, copy, modify, and/or distribute this software for any 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * purpose with or without fee is hereby granted, provided that the above 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copyright notice and this permission notice appear in all copies. 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/rand.h> 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/thread.h> 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if defined(OPENSSL_WINDOWS) 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <stdlib.h> 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <Windows.h> 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <Wincrypt.h> 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic char global_provider_init; 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic HCRYPTPROV global_provider; 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid RAND_cleanup(void) { 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_RAND); 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CryptReleaseContext(global_provider, 0); 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley global_provider_init = 0; 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint RAND_bytes(uint8_t *out, size_t requested) { 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley HCRYPTPROV provider = 0; 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ok; 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_RAND); 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!global_provider_init) { 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_RAND); 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_RAND); 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!global_provider_init) { 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (CryptAcquireContext(&global_provider, NULL, NULL, PROV_RSA_FULL, 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley global_provider_init = 1; 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_RAND); 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ok = global_provider_init; 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley provider = global_provider; 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_RAND); 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ok) { 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley abort(); 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ok; 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (TRUE != CryptGenRandom(provider, requested, out)) { 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley abort(); 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif /* OPENSSL_WINDOWS */ 72