示例#1
1
文件: crypt.c 项目: Property404/OSIR
//Return random bytes
bool secureRand(char **output, const int size)
{
	//Allocate bytes
	*output = (char *) malloc(sizeof(char) * size);
#ifdef _WIN32
	HCRYPTPROV hCryptProv = 0;

	//Prepare CSPRNG
	if (!CryptAcquireContextW
	    (&hCryptProv, 0, 0, PROV_RSA_FULL,
	     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
		fprintf(stderr,
			"Error: secureRand: CryptAcquireContextW failed");
		return 0;
	}
	//Generate bytes
	if (!CryptGenRandom(hCryptProv, size, (unsigned char *) *output)) {
		fprintf(stderr,
			"Error: secureRand: CryptGenRandom failed");
		return 0;
	}
#else
	//FIXME: read from /dev/urandom
	for (int i = 0; i < size; i++) {
		(*output)[i] = rand() % 256 - 128;
	}
#endif
	return 1;
}
/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
   API. Return 0 on success, or raise an exception and return -1 on error. */
static int
win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
{
    Py_ssize_t chunk;

    if (hCryptProv == 0)
    {
        if (win32_urandom_init(raise) == -1)
            return -1;
    }

    while (size > 0)
    {
        chunk = size > INT_MAX ? INT_MAX : size;
        if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer))
        {
            /* CryptGenRandom() failed */
            if (raise)
                PyErr_SetFromWindowsErr(0);
            else
                Py_FatalError("Failed to initialized the randomized hash "
                        "secret using CryptoGen)");
            return -1;
        }
        buffer += chunk;
        size -= chunk;
    }
    return 0;
}
示例#3
0
static
nsresult
GenerateRandomBytes(uint32_t aSize,
                    uint8_t* _buffer)
{
  // On Windows, we'll use its built-in cryptographic API.
#if defined(XP_WIN)
  HCRYPTPROV cryptoProvider;
  BOOL rc = CryptAcquireContext(&cryptoProvider, 0, 0, PROV_RSA_FULL,
                                CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
  if (rc) {
    rc = CryptGenRandom(cryptoProvider, aSize, _buffer);
    (void)CryptReleaseContext(cryptoProvider, 0);
  }
  return rc ? NS_OK : NS_ERROR_FAILURE;

  // On Unix, we'll just read in from /dev/urandom.
#elif defined(XP_UNIX)
  NS_ENSURE_ARG_MAX(aSize, INT32_MAX);
  PRFileDesc* urandom = PR_Open("/dev/urandom", PR_RDONLY, 0);
  nsresult rv = NS_ERROR_FAILURE;
  if (urandom) {
    int32_t bytesRead = PR_Read(urandom, _buffer, aSize);
    if (bytesRead == static_cast<int32_t>(aSize)) {
      rv = NS_OK;
    }
    (void)PR_Close(urandom);
  }
  return rv;
#endif
}
示例#4
0
int make_random_string(char* out) {
    char buf[256];
#ifdef _WIN32
    HCRYPTPROV hCryptProv;
        
    if(! CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
        return -1;
    }
    
    if(! CryptGenRandom(hCryptProv, (DWORD) 32, (BYTE *) buf)) {
        CryptReleaseContext(hCryptProv, 0);
        return -1;
    }
        
    CryptReleaseContext(hCryptProv, 0);
#else
    FILE* f = fopen("/dev/random", "r");
    if (!f) {
        return -1;
    }
    size_t n = fread(buf, 32, 1, f);
    fclose(f);
    if (n != 1) return -1;
#endif
    md5_block((const unsigned char*)buf, 32, out);
    return 0;
}
示例#5
0
static rand_t *
rand_open(void)
{
	rand_t *r;
	u_char seed[256];
#if 0
#ifdef _WIN32
	HCRYPTPROV hcrypt = 0;

	CryptAcquireContext(&hcrypt, NULL, NULL, PROV_RSA_FULL,
	    CRYPT_VERIFYCONTEXT);
	CryptGenRandom(hcrypt, sizeof(seed), seed);
	CryptReleaseContext(hcrypt, 0);
#else
	struct timeval *tv = (struct timeval *)seed;
	int fd;

	if ((fd = open("/dev/arandom", O_RDONLY)) != -1 ||
	    (fd = open("/dev/urandom", O_RDONLY)) != -1) {
		read(fd, seed + sizeof(*tv), sizeof(seed) - sizeof(*tv));
		close(fd);
	}
	gettimeofday(tv, NULL);
#endif
#endif
	if ((r = (rand_t *)malloc(sizeof(*r))) != NULL) {
		rand_init(r);
		rand_addrandom(r, seed, 128);
		rand_addrandom(r, seed + 128, 128);
		r->tmp = NULL;
		r->tmplen = 0;
	}
	return (r);
}
示例#6
0
文件: osrng.cpp 项目: xyliuke/plan9
void NonblockingRng::GenerateBlock(byte *output, size_t size)
{
#ifdef CRYPTOPP_WIN32_AVAILABLE
    // Acquiring a provider is expensive. Do it once and retain the reference.
    static const MicrosoftCryptoProvider &hProvider = Singleton<MicrosoftCryptoProvider>().Ref();
# if defined(USE_MS_CRYPTOAPI)
    if (!CryptGenRandom(hProvider.GetProviderHandle(), (DWORD)size, output))
        throw OS_RNG_Err("CryptGenRandom");
# elif defined(USE_MS_CNGAPI)
    NTSTATUS ret = BCryptGenRandom(hProvider.GetProviderHandle(), output, (ULONG)size, 0);
    if (!(BCRYPT_SUCCESS(ret)))
    {
        // Hack... OS_RNG_Err calls GetLastError()
        SetLastError(NtStatusToErrorCode(ret));
        throw OS_RNG_Err("BCryptGenRandom");
    }
# endif
#else
    while (size)
    {
        ssize_t len = read(m_fd, output, size);
        if (len < 0)
        {
            // /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well)
            if (errno != EINTR && errno != EAGAIN)
                throw OS_RNG_Err("read /dev/urandom");

            continue;
        }

        output += len;
        size -= len;
    }
#endif  // CRYPTOPP_WIN32_AVAILABLE
}
示例#7
0
// from tweetnacl
__declspec(dllexport) void randombytes(unsigned char *x,int xlen)
{
    HCRYPTPROV prov = 0;
    CryptAcquireContextW(&prov, NULL, NULL,PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
    CryptGenRandom(prov, xlen, x);
    CryptReleaseContext(prov, 0);
}
示例#8
0
unsigned int I_MakeRNGSeed()
{
	unsigned int seed;

	// If RtlGenRandom is available, use that to avoid increasing the
	// working set by pulling in all of the crytographic API.
	HMODULE advapi = GetModuleHandle("advapi32.dll");
	if (advapi != NULL)
	{
		BOOLEAN (APIENTRY *RtlGenRandom)(void *, ULONG) =
			(BOOLEAN (APIENTRY *)(void *, ULONG))GetProcAddress(advapi, "SystemFunction036");
		if (RtlGenRandom != NULL)
		{
			if (RtlGenRandom(&seed, sizeof(seed)))
			{
				return seed;
			}
		}
	}

	// Use the full crytographic API to produce a seed. If that fails,
	// time() is used as a fallback.
	HCRYPTPROV prov;

	if (!CryptAcquireContext(&prov, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
	{
		return (unsigned int)time(NULL);
	}
	if (!CryptGenRandom(prov, sizeof(seed), (BYTE *)&seed))
	{
		seed = (unsigned int)time(NULL);
	}
	CryptReleaseContext(prov, 0);
	return seed;
}
示例#9
0
文件: core.c 项目: MesserLab/SLiM
static int TSK_WARN_UNUSED
get_random_bytes(uint8_t *buf)
{
    /* Based on CPython's code in bootstrap_hash.c */
    int ret = TSK_ERR_GENERATE_UUID;
    HCRYPTPROV hCryptProv = NULL;

    if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
        goto out;
    }
    if (!CryptGenRandom(hCryptProv, (DWORD) UUID_NUM_BYTES, buf)) {
        goto out;
    }
    if (!CryptReleaseContext(hCryptProv, 0)) {
        hCryptProv = NULL;
        goto out;
    }
    hCryptProv = NULL;
    ret = 0;
out:
    if (hCryptProv != NULL) {
        CryptReleaseContext(hCryptProv, 0);
    }
    return ret;
}
示例#10
0
static void test_gen_random(void)
{
	BOOL result;
	BYTE rnd1[16], rnd2[16];

	memset(rnd1, 0, sizeof(rnd1));
	memset(rnd2, 0, sizeof(rnd2));
	
	result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
	ok(result, "%08x\n", (unsigned int)GetLastError());

	result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
	ok(result, "%08x\n", (unsigned int)GetLastError());

	ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
}
示例#11
0
static int
w32crypto_bytes(unsigned char *outdata, int size)
{
    if (CryptGenRandom(_hc_CryptProvider(), size, outdata))
	return 1;
    return 0;
}
示例#12
0
static Gc_rc
randomize (int level, char *data, size_t datalen)
{
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  if (!g_hProv)
    return GC_RANDOM_ERROR;
  CryptGenRandom (g_hProv, (DWORD) datalen, data);
#else
  int fd;
  const char *device;
  size_t len = 0;
  int rc;

  switch (level)
    {
    case 0:
      device = NAME_OF_NONCE_DEVICE;
      break;

    case 1:
      device = NAME_OF_PSEUDO_RANDOM_DEVICE;
      break;

    default:
      device = NAME_OF_RANDOM_DEVICE;
      break;
    }

  if (strcmp (device, "no") == 0)
    return GC_RANDOM_ERROR;

  fd = open (device, O_RDONLY);
  if (fd < 0)
    return GC_RANDOM_ERROR;

  do
    {
      ssize_t tmp;

      tmp = read (fd, data, datalen);

      if (tmp < 0)
        {
          int save_errno = errno;
          close (fd);
          errno = save_errno;
          return GC_RANDOM_ERROR;
        }

      len += tmp;
    }
  while (len < datalen);

  rc = close (fd);
  if (rc < 0)
    return GC_RANDOM_ERROR;
#endif

  return GC_OK;
}
示例#13
0
PHPAPI int php_win32_get_random_bytes(unsigned char *buf, size_t size) {  /* {{{ */
	HCRYPTPROV   hCryptProv;
	int has_context = 0;
	BOOL ret;
	size_t i = 0;

	if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
		/* Could mean that the key container does not exist, let try 
		   again by asking for a new one */
		if (GetLastError() == NTE_BAD_KEYSET) {
			if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
				has_context = 1;
			} else {
				return FAILURE;
			}
		}
	}

	ret = CryptGenRandom(hCryptProv, size, buf);
	CryptReleaseContext(hCryptProv, 0);
	if (ret) {
		return SUCCESS;
	}
	return FAILURE;
}
示例#14
0
/** Get 32 bytes of system entropy. */
static void GetOSRand(unsigned char *ent32)
{
#ifdef WIN32
    HCRYPTPROV hProvider;
    int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    if (!ret) {
        RandFailure();
    }
    ret = CryptGenRandom(hProvider, 32, ent32);
    if (!ret) {
        RandFailure();
    }
    CryptReleaseContext(hProvider, 0);
#else
    int f = open("/dev/urandom", O_RDONLY);
    if (f == -1) {
        RandFailure();
    }
    int have = 0;
    do {
        ssize_t n = read(f, ent32 + have, 32 - have);
        if (n <= 0 || n + have > 32) {
            RandFailure();
        }
        have += n;
    } while (have < 32);
    close(f);
#endif
}
示例#15
0
void AJ_RandBytes(uint8_t* rand, uint32_t len)
{
    HCRYPTPROV hProvider;
    CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
    CryptGenRandom(hProvider, len, rand);
    CryptReleaseContext(hProvider, 0);
}
示例#16
0
static SRP_Result fill_buff()
{
	g_rand_idx = 0;

#ifdef WIN32
	HCRYPTPROV wctx;
#else
	FILE *fp = 0;
#endif

#ifdef WIN32

	if (!CryptAcquireContext(&wctx, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
		return SRP_ERR;
	if (!CryptGenRandom(wctx, sizeof(g_rand_buff), (BYTE *)g_rand_buff)) return SRP_ERR;
	if (!CryptReleaseContext(wctx, 0)) return SRP_ERR;

#else
	fp = fopen("/dev/urandom", "r");

	if (!fp) return SRP_ERR;

	if (fread(g_rand_buff, sizeof(g_rand_buff), 1, fp) != 1) { fclose(fp); return SRP_ERR; }
	if (fclose(fp)) return SRP_ERR;
#endif
	return SRP_OK;
}
示例#17
0
void initPRNG()
{
    bool seedsuccess = false;

#ifdef WIN32
    HCRYPTPROV hCryptProv;
    BYTE* pbData = reinterpret_cast<BYTE*>(&prng_seed);

    if (CryptAcquireContext(&hCryptProv, nullptr, nullptr, PROV_RSA_FULL, 0)) {
        if (CryptGenRandom(hCryptProv, sizeof(prng_seed), pbData)) {
            seedsuccess = true;
        }
        CryptReleaseContext(hCryptProv, 0);
    }
#else
    std::ifstream urandom("/dev/urandom");
    if (urandom) {
        urandom.read(reinterpret_cast<char*>(&prng_seed), sizeof(prng_seed));
        seedsuccess = true;
    }
#endif

    if (!seedsuccess) {
        prng_seed = static_cast<seed_type>(std::time(nullptr));
    }

    //std::cout << "Seeding the PRNG with: 0x" << std::hex << std::uppercase << std::setfill('0')
    //          << std::setw(2 * sizeof(MyRNG::result_type)) << prng_seed << std::endl;

    prng.seed(prng_seed);
}
/* good1() uses if(staticFalse) instead of if(staticTrue) */
static void good1()
{
    if(staticFalse)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        {
            HCRYPTPROV hCryptProv;
            int data;
            if (!CryptAcquireContextW(&hCryptProv, 0, 0, PROV_RSA_FULL, 0))
            {
                exit(1);
            }
            /* FIX: Use of CryptGenRandom() as a more secure PRNG */
            if (!CryptGenRandom(hCryptProv, sizeof(data), (BYTE *) &data))
            {
                CryptReleaseContext(hCryptProv, 0);
                exit(1);
            }
            if (hCryptProv)
            {
                CryptReleaseContext(hCryptProv, 0);
            }
            printIntLine(data);
        }
    }
}
/* good2() reverses the bodies in the if statement */
static void good2()
{
    if(staticTrue)
    {
        {
            HCRYPTPROV hCryptProv;
            int data;
            if (!CryptAcquireContextW(&hCryptProv, 0, 0, PROV_RSA_FULL, 0))
            {
                exit(1);
            }
            /* FIX: Use of CryptGenRandom() as a more secure PRNG */
            if (!CryptGenRandom(hCryptProv, sizeof(data), (BYTE *) &data))
            {
                CryptReleaseContext(hCryptProv, 0);
                exit(1);
            }
            if (hCryptProv)
            {
                CryptReleaseContext(hCryptProv, 0);
            }
            printIntLine(data);
        }
    }
}
示例#20
0
void
rng_gen_seed(rust_kernel* kernel, uint8_t* dest, size_t size) {
#ifdef __WIN32__
    HCRYPTPROV hProv;
    kernel->win32_require
    (_T("CryptAcquireContext"),
     CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
                         CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
    kernel->win32_require
    (_T("CryptGenRandom"), CryptGenRandom(hProv, size, (BYTE*) dest));
    kernel->win32_require
    (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0));
#else
    int fd = open("/dev/urandom", O_RDONLY);
    if (fd == -1)
        kernel->fatal("error opening /dev/urandom: %s", strerror(errno));
    size_t amount = 0;
    do {
        ssize_t ret = read(fd, dest+amount, size-amount);
        if (ret < 0)
            kernel->fatal("error reading /dev/urandom: %s", strerror(errno));
        else if (ret == 0)
            kernel->fatal("somehow hit eof reading from /dev/urandom");
        amount += (size_t)ret;
    } while (amount < size);
    int ret = close(fd);
    // FIXME #3697: Why does this fail sometimes?
    if (ret != 0)
        kernel->log(log_warn, "error closing /dev/urandom: %s",
                    strerror(errno));
#endif
}
示例#21
0
static int arc4_seed_win( void )
{
   /* This is adapted from Tor's crypto_seed_rng() */
   static int        s_provider_set = 0;
   static HCRYPTPROV s_provider;
   unsigned char     buf[ ADD_ENTROPY ];

   /* NOTE: CryptAcquireContextW() is not available on Win95, but
            because we don't need to pass any strings in this context,
            CryptAcquireContextA() can be used safely here. [vszakats] */
   #if ! defined( HB_OS_WIN_CE )
      #undef CryptAcquireContext
      #define CryptAcquireContext  CryptAcquireContextA
   #endif

   if( ! s_provider_set &&
       ! CryptAcquireContext( &s_provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT ) &&
       GetLastError() != ( DWORD ) NTE_BAD_KEYSET )
      return -1;

   s_provider_set = 1;

   if( ! CryptGenRandom( s_provider, sizeof( buf ), buf ) )
      return -1;

   arc4_addrandom( buf, sizeof( buf ) );
   memset( buf, 0, sizeof( buf ) );

   return 0;
}
示例#22
0
void windowsHandler::generateRandomBytes(unsigned char* buffer, const unsigned int count)
{
	HCRYPTPROV cryptProvider = 0;
	CryptAcquireContext(&cryptProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
	CryptGenRandom(cryptProvider, static_cast <unsigned long>(count), static_cast <unsigned char*>(buffer));
	CryptReleaseContext(cryptProvider, 0);
}
示例#23
0
// make a random 32-char string
// (the MD5 of some quasi-random bits)
//
int make_random_string(char* out) {
    char buf[256];
#ifdef _WIN32
    HCRYPTPROV hCryptProv;
        
    if(! CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
        return -1;
    }
    
    if(! CryptGenRandom(hCryptProv, (DWORD) 32, (BYTE *) buf)) {
        CryptReleaseContext(hCryptProv, 0);
        return -1;
    }
        
    CryptReleaseContext(hCryptProv, 0);
#elif defined ANDROID
    // /dev/random not available on Android, using stdlib function instead
    int i = rand();
    snprintf(buf, sizeof(buf), "%d", i);
#else
#ifndef _USING_FCGI_
    FILE* f = fopen("/dev/random", "r");
#else
    FILE* f = FCGI::fopen("/dev/random", "r");
#endif
    if (!f) {
        return -1;
    }
    size_t n = fread(buf, 32, 1, f);
    fclose(f);
    if (n != 1) return -1;
#endif
    md5_block((const unsigned char*)buf, 32, out);
    return 0;
}
示例#24
0
文件: osdep.c 项目: texane/bano
int32 psGetEntropy(unsigned char *bytes, uint32 size)
{
	if (CryptGenRandom(hProv, size, bytes)) {
		return size;
	}
	return PS_FAILURE;
}
void NonblockingRng::GenerateBlock(byte *output, size_t size)
{
#ifdef CRYPTOPP_WIN32_AVAILABLE
#	ifdef WORKAROUND_MS_BUG_Q258000
		const MicrosoftCryptoProvider &m_Provider = Singleton<MicrosoftCryptoProvider>().Ref();
#	endif
	if (!CryptGenRandom(m_Provider.GetProviderHandle(), (DWORD)size, output))
		throw OS_RNG_Err("CryptGenRandom");
#else
	while (size)
	{
		ssize_t len = read(m_fd, output, size);

		if (len < 0)
		{
			// /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well)
			if (errno != EINTR && errno != EAGAIN)
				throw OS_RNG_Err("read /dev/urandom");

			continue;
		}

		output += len;
		size -= len;
	}
#endif
}
示例#26
0
/*
 *   Random numbers 
 */
void os_gen_rand_bytes(unsigned char *buf, size_t len)
{
    /* make sure we have a crypto context */
    init_crypto_ctx();

    /* generate bytes via the system crypto API */
    CryptGenRandom(oswin_hcp, len, buf);
}
示例#27
0
		void generate(void *ptr,unsigned len)
		{
			if(CryptGenRandom(provider_,len,static_cast<BYTE *>(ptr)))
				return;
			std::ostringstream ss;
			ss<<"CryptGenRandom failed with code 0x"<<std::hex<<GetLastError();
			throw cppcms_error(ss.str());
		}
static void generate_system_random_bytes(size_t n, void *result) {
  HCRYPTPROV prov;
#define must_succeed(x) do if (!(x)) assert(0); while (0)
  must_succeed(CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT));
  must_succeed(CryptGenRandom(prov, (DWORD)n, result));
  must_succeed(CryptReleaseContext(prov, 0));
#undef must_succeed
}
示例#29
0
文件: Random.cpp 项目: zukisoft/vm
void Random::Generate(void* buffer, size_t length)
{
	if(!buffer) throw Exception{ E_ARGUMENTNULL, "buffer" };
	if(length > MAXDWORD) throw Exception{ E_ARGUMENTOUTOFRANGE, "length" };

	// Load the output buffer with random data using the statically defined provider handle
	if(!CryptGenRandom(s_provider, static_cast<DWORD>(length), reinterpret_cast<uint8_t*>(buffer))) throw Win32Exception{};
}
示例#30
0
void windows_random(uint8 *rand, int len)
{
	/* Declare and initialize variables */

	HCRYPTPROV hCryptProv = NULL;
	LPCSTR UserName = "{56E9D11F-76B8-42fa-8645-76980E4E8648}";

	/*
	Attempt to acquire a context and a key
	container. The context will use the default CSP
	for the RSA_FULL provider type. DwFlags is set to 0
	to attempt to open an existing key container.
	*/
	if (CryptAcquireContext(&hCryptProv,
		UserName,
		NULL,
		PROV_RSA_FULL,
		0))
	{
		/* do nothing */
	}
	else
	{
		/*
		An error occurred in acquiring the context. This could mean
		that the key container requested does not exist. In this case,
		the function can be called again to attempt to create a new key
		container. Error codes are defined in winerror.h.
		*/
		if (GetLastError() == NTE_BAD_KEYSET)
		{
			if (!CryptAcquireContext(&hCryptProv,
				UserName,
				NULL,
				PROV_RSA_FULL,
				CRYPT_NEWKEYSET))
			{
				printf("Could not create a new key container.\n");
			}
		}
		else
		{
			printf("A cryptographic service handle could not be acquired.\n");
		}
	}

	if (hCryptProv)
	{
		/* Generate a random initialization vector. */
		if (!CryptGenRandom(hCryptProv, len, rand))
		{
			printf("Error during CryptGenRandom.\n");
		}
		if (!CryptReleaseContext(hCryptProv, 0))
			printf("Failed CryptReleaseContext\n");
	}
	return;
}