MCPcopy Create free account
hub / github.com/F-Stack/f-stack / getRandomBytes

Function getRandomBytes

app/redis-6.2.6/src/util.c:647–709  ·  view source on GitHub ↗

Get random bytes, attempts to get an initial seed from /dev/urandom and * the uses a one way hash function in counter mode to generate a random * stream. However if /dev/urandom is not available, a weaker seed is used. * * This function is not thread safe, since the state is global. */

Source from the content-addressed store, hash-verified

645 *
646 * This function is not thread safe, since the state is global. */
647void getRandomBytes(unsigned char *p, size_t len) {
648 /* Global state. */
649 static int seed_initialized = 0;
650 static unsigned char seed[64]; /* 512 bit internal block size. */
651 static uint64_t counter = 0; /* The counter we hash with the seed. */
652
653 if (!seed_initialized) {
654 /* Initialize a seed and use SHA1 in counter mode, where we hash
655 * the same seed with a progressive counter. For the goals of this
656 * function we just need non-colliding strings, there are no
657 * cryptographic security needs. */
658 FILE *fp = fopen("/dev/urandom","r");
659 if (fp == NULL || fread(seed,sizeof(seed),1,fp) != 1) {
660 /* Revert to a weaker seed, and in this case reseed again
661 * at every call.*/
662 for (unsigned int j = 0; j < sizeof(seed); j++) {
663 struct timeval tv;
664 gettimeofday(&tv,NULL);
665 pid_t pid = getpid();
666 seed[j] = tv.tv_sec ^ tv.tv_usec ^ pid ^ (long)fp;
667 }
668 } else {
669 seed_initialized = 1;
670 }
671 if (fp) fclose(fp);
672 }
673
674 while(len) {
675 /* This implements SHA256-HMAC. */
676 unsigned char digest[SHA256_BLOCK_SIZE];
677 unsigned char kxor[64];
678 unsigned int copylen =
679 len > SHA256_BLOCK_SIZE ? SHA256_BLOCK_SIZE : len;
680
681 /* IKEY: key xored with 0x36. */
682 memcpy(kxor,seed,sizeof(kxor));
683 for (unsigned int i = 0; i < sizeof(kxor); i++) kxor[i] ^= 0x36;
684
685 /* Obtain HASH(IKEY||MESSAGE). */
686 SHA256_CTX ctx;
687 sha256_init(&ctx);
688 sha256_update(&ctx,kxor,sizeof(kxor));
689 sha256_update(&ctx,(unsigned char*)&counter,sizeof(counter));
690 sha256_final(&ctx,digest);
691
692 /* OKEY: key xored with 0x5c. */
693 memcpy(kxor,seed,sizeof(kxor));
694 for (unsigned int i = 0; i < sizeof(kxor); i++) kxor[i] ^= 0x5C;
695
696 /* Obtain HASH(OKEY || HASH(IKEY||MESSAGE)). */
697 sha256_init(&ctx);
698 sha256_update(&ctx,kxor,sizeof(kxor));
699 sha256_update(&ctx,digest,SHA256_BLOCK_SIZE);
700 sha256_final(&ctx,digest);
701
702 /* Increment the counter for the next iteration. */
703 counter++;
704

Callers 3

mainFunction · 0.85
RM_GetRandomBytesFunction · 0.85
getRandomHexCharsFunction · 0.85

Calls 4

sha256_initFunction · 0.85
sha256_updateFunction · 0.85
sha256_finalFunction · 0.85
memcpyFunction · 0.50

Tested by

no test coverage detected