예제 #1
0
파일: bcrypt.c 프로젝트: Crobin83/wine
static void test_BCryptGenRandom(void)
{
    NTSTATUS ret;
    UCHAR buffer[256];

    ret = BCryptGenRandom(NULL, NULL, 0, 0);
    ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
    ret = BCryptGenRandom(NULL, buffer, 0, 0);
    ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
    ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), 0);
    ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret);
    ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
    ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
    ret = BCryptGenRandom(NULL, buffer, sizeof(buffer),
          BCRYPT_USE_SYSTEM_PREFERRED_RNG|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER);
    ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
    ret = BCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
    ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret);

    /* Zero sized buffer should work too */
    ret = BCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
    ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);

    /* Test random number generation - It's impossible for a sane RNG to return 8 zeros */
    memset(buffer, 0, 16);
    ret = BCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
    ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret);
    ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n");
}
예제 #2
0
int xpfurandom_get_random_data(void** data, uint32_t size, void* win_alg_handle, xpfurandom_settings* s){
	NTSTATUS st;
	st = BCryptGenRandom(win_alg_handle, *data, size, 0);
	switch (st){
		case STATUS_SUCCESS:break;
		case STATUS_INVALID_HANDLE: {
			fprintf(stderr, "XPFUrandom: BCryptGenRandom failed: invalid algorithm handle(STATUS_INVALID_HANDLE)\n");
			return FAIL;
		}break;
		case STATUS_INVALID_PARAMETER: {
			fprintf(stderr, "XPFUrandom: BCryptGenRandom failed: invalid parameter(STATUS_INVALID_PARAMETER)\n");
			return FAIL;
		}break;
	}
	if (s->file_out) {
		st = fwrite(*data, 1, size, s->file_out);
		if (st != size) {
			fprintf(stderr, "XPFUrandom: fwrite failed\n");
			return FAIL;
		}
		st = fflush(s->file_out);
		if (st) {
			fprintf(stderr, "XPFUrandom: fflush failed: %s\n",strerror(errno));
			return FAIL;
		}
	}
	return OK;
}
예제 #3
0
int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE])
{
	char input[RANDBYTES];
	int workf;
	char *aux;

#ifdef WIN32
    BCryptGenRandom(NULL, input, RANDBYTES, BCRYPT_USE_SYSTEM_PREFERRED_RNG);    
#else
    int fd;
    fd = open("/dev/urandom", O_RDONLY);
	if (fd == -1)
		return 1;

	if (try_read(fd, input, RANDBYTES) != 0) {
		if (try_close(fd) != 0)
			return 4;
		return 2;
	}

	if (try_close(fd) != 0)
		return 3;
#endif
	/* Generate salt. */
	workf = (factor < 4 || factor > 31)?12:factor;
	aux = crypt_gensalt_rn("$2a$", workf, input, RANDBYTES,
			       salt, BCRYPT_HASHSIZE);
	return (aux == NULL)?5:0;
}
예제 #4
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
}
예제 #5
0
파일: wincng.c 프로젝트: infinitude-cn/cpp
int
_libssh2_wincng_random(void *buf, int len)
{
    int ret;

    ret = BCryptGenRandom(_libssh2_wincng.hAlgRNG, buf, len, 0);

    return BCRYPT_SUCCESS(ret) ? 0 : -1;
}
예제 #6
0
//***_cpri__GenerateRandom()
// Generate a 'randomSize' number or random bytes.
UINT16
_cpri__GenerateRandom(
    INT32       randomSize,  
    BYTE       *buffer
    )
{
    //
    // We don't do negative sizes or ones that are too large
    if (randomSize < 0 || randomSize > UINT16_MAX)
        return 0;
    return (BCryptGenRandom(g_hRngAlg, buffer, randomSize, 0) == ERROR_SUCCESS) ? (UINT16)randomSize : 0;
}
예제 #7
0
int main(int argc, char* argv[])
{
	int data_amount = 0;
	int data_read = 0;
	if (argv[1] == NULL) {
		puts("No argument detected, exiting. Run with -h argument for help.");
		return -1;
	}
	if (strcmp("-h", argv[1]) == 0) {
		puts("Valid arguments:\n-h: Prints this\nX: Number of output bytes desired, 0<=X<2147483647");
		return 0;
	}
	else {
		data_amount = strtol(argv[1], NULL, 10);
		if (data_amount == 0) {
			puts("Invalid argument, reading default amount of data (1KB)");
			data_amount = 1024;
		}
	}

	PUCHAR data = calloc(data_amount+1,1);
	if (data == NULL) {
		puts("Allocation failed, exiting.");
		return 1;
	}
	while (data_read < data_amount) {
		NTSTATUS status = BCryptGenRandom(NULL, data+data_read, data_amount-data_read, 0x00000003);
		// argument 1 : algorithm to use, iff NULL AND (arg4 & 0x2) uses system-preferred CSPRNG (not supported on Vista)
		// arg 2 : pointer to data storage
		// arg 3 : number of bytes of data to be read
		// arg 4 : flags; 0x2 see above, 0x1 uses entropy in arg3 as extra(ignored on Win8+), 
		//			else uses just a random number for entropy
		switch (status) {
			case STATUS_SUCCESS: //just continue, all good
				break;
			case STATUS_INVALID_HANDLE:
				puts("RNG algorithm handle invalid, exiting.");
				return 2;
				break;
			case STATUS_INVALID_PARAMETER:
				puts("Most likely invalid flags, exiting");
				return 2;
		}
		data_read = strlen(data);
	}
	//while-loop is necessary, test runs sometimes came up with less data than desired
	puts(data); // demonstrates functionality
    return 0;
}
예제 #8
0
int RAND_poll(void)
{
    MEMORYSTATUS mst;
# ifndef RAND_WINDOWS_USE_BCRYPT
    HCRYPTPROV hProvider;
# endif
    DWORD w;
    BYTE buf[64];

# ifdef RAND_WINDOWS_USE_BCRYPT
    if (BCryptGenRandom(NULL, buf, (ULONG)sizeof(buf), BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) {
        RAND_add(buf, sizeof(buf), sizeof(buf));
    }
# else
    /* poll the CryptoAPI PRNG */
    /* The CryptoAPI returns sizeof(buf) bytes of randomness */
    if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
        if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
            RAND_add(buf, sizeof(buf), sizeof(buf));
        }
        CryptReleaseContext(hProvider, 0);
    }

    /* poll the Pentium PRG with CryptoAPI */
    if (CryptAcquireContextW(&hProvider, NULL, INTEL_DEF_PROV, PROV_INTEL_SEC, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
        if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
            RAND_add(buf, sizeof(buf), sizeof(buf));
        }
        CryptReleaseContext(hProvider, 0);
    }
# endif

    /* timer data */
    readtimer();

    /* memory usage statistics */
    GlobalMemoryStatus(&mst);
    RAND_add(&mst, sizeof(mst), 1);

    /* process ID */
    w = GetCurrentProcessId();
    RAND_add(&w, sizeof(w), 1);

    return (1);
}
예제 #9
0
파일: cifra.c 프로젝트: devnexen/h2o
 static void read_entropy(uint8_t *entropy, size_t size)
 {
    NTSTATUS nts = 0;
    BCRYPT_ALG_HANDLE hAlgorithm = 0;

    nts = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_RNG_ALGORITHM, NULL, 0);

    if (BCRYPT_SUCCESS(nts)) {
        nts = BCryptGenRandom(hAlgorithm, (PUCHAR)entropy, (ULONG)size, 0);

        (void)BCryptCloseAlgorithmProvider(hAlgorithm, 0); 
    } 

    if (!BCRYPT_SUCCESS(nts)) {
        perror("ptls_minicrypto_random_bytes: could not open BCrypt RNG Algorithm");
        abort();
    }
}
예제 #10
0
int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen)
{
	((void)data);
	*olen = 0;

	/*
	 * size_t may be 64 bits, but ULONG is always 32.
	 * If len is larger than the maximum for ULONG, just fail.
	 * It's unlikely anything ever will want to ask for this much randomness.
	 */
	if (len > 0xFFFFFFFFULL) {
		return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
	}

	if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, (ULONG) len, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
		return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
	}

	*olen = len;

	return (0);
}
예제 #11
0
int
_mongoc_rand_bytes (uint8_t *buf, int num)
{
   static BCRYPT_ALG_HANDLE algorithm = 0;
   NTSTATUS status = 0;

   if (!algorithm) {
      status = BCryptOpenAlgorithmProvider (
         &algorithm, BCRYPT_RNG_ALGORITHM, NULL, 0);
      if (!NT_SUCCESS (status)) {
         MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %d", status);
         return 0;
      }
   }

   status = BCryptGenRandom (algorithm, buf, num, 0);
   if (NT_SUCCESS (status)) {
      return 1;
   }

   MONGOC_ERROR ("BCryptGenRandom(): %d", status);
   return 0;
}
예제 #12
0
파일: myssl.c 프로젝트: captdeaf/pennmush
/** Generate 128 bits of random noise for seeding RNGs. Attempts to
 * use various OS-specific sources of random bits, with a fallback
 * based on time and pid. */
void
generate_seed(uint64_t seeds[])
{
  bool seed_generated = false;
  static int stream_count = 0;
  int len = sizeof(uint64_t) * 2;

#ifdef HAVE_GETENTROPY
  /* On OpenBSD and up to date Linux, use getentropy() to avoid the
     open/read/close sequence with /dev/urandom */
  if (!seed_generated && getentropy(seeds, len) == 0) {
    fprintf(stderr, "Seeded RNG with getentropy()\n");
    seed_generated = true;
  }
#endif

#ifdef HAVE_ARC4RANDOM_BUF
  /* Most (all?) of the BSDs have this seeder. Use it for the reasons
     above. Also available on Linux with libbsd, but we don't check
     for that. */
  if (!seed_generated) {
    arc4random_buf(seeds, len);
    fprintf(stderr, "Seeded RNG with arc4random\n");
    seed_generated = true;
  }
#endif

#ifdef WIN32
  if (!seed_generated) {
    /* Use the Win32 bcrypto RNG interface */
    if (BCryptGenRandom(NULL, (PUCHAR) seeds, len,
                        BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) {
      fprintf(stderr, "Seeding RNG with BCryptGenRandom()\n");
      seed_generated = true;
    }
  }
#endif

#ifdef HAVE_DEV_URANDOM
  if (!seed_generated) {
    /* Seed from /dev/urandom if available */
    int fd;

    fd = open("/dev/urandom", O_RDONLY);
    if (fd >= 0) {
      int r = read(fd, (void *) seeds, len);
      close(fd);
      if (r != len) {
        fprintf(stderr, "Couldn't read from /dev/urandom! Resorting to normal "
                        "seeding method.\n");
      } else {
        fprintf(stderr, "Seeding RNG with /dev/urandom\n");
        seed_generated = true;
      }
    } else {
      fprintf(stderr, "Couldn't open /dev/urandom to seed random number "
                      "generator. Resorting to normal seeding method.\n");
    }
  }
#endif

  if (!seed_generated) {
    /* Default seeder. Pick a seed that's slightly random */
#ifdef WIN32
    seeds[0] = (uint64_t) time(NULL);
    seeds[1] = (uint64_t) GetCurrentProcessId() + stream_count;
#else
    seeds[0] = (uint64_t) time(NULL);
    seeds[1] = (uint64_t) getpid() + stream_count;
#endif
    stream_count += 1;
  }
}