Repository: valkey-io/valkey
File: src/util.c (C)

Code before:
    if (fp) fclose(fp);
}

/* This function receives a string with 64 bytes encoded as 128 hexadecimal
 * digits, and sets the 64 byte random seed. */
void setRandomSeedCString(char *seed_str, size_t len) {
    assert(len == sizeof(seed) * 2);
    for (size_t i = 0; i < sizeof(seed); i++) {
        sscanf(seed_str + (i * 2), "%02hhX", &seed[i]);
    }
    seed_initialized = 1;
}

/* This function populates a char buffer with 129 bytes with the 64 bytes
 * random seed encoded as 128 hexadecimal digits. */
void getRandomSeedCString(char *buff, size_t len) {
    assert(len == (sizeof(seed) * 2 + 1));

    if (!seed_initialized) {
        initializeRandomSeed();
    }

    for (size_t i = 0; i < sizeof(seed); i++) {
        snprintf(buff + (i * 2), 3, "%02hhX", seed[i]);
    }
    buff[sizeof(seed) * 2] = 0;
}

/* 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. */
void getRandomBytes(unsigned char *p, size_t len) {
    static uint64_t counter = 0; /* The counter we hash with the seed. */

    if (!seed_initialized) {
        initializeRandomSeed();
    }

    while (len) {
        /* This implements SHA256-HMAC. */
        unsigned char digest[SHA256_BLOCK_SIZE];
        unsigned char kxor[64];
        unsigned int copylen = len > SHA256_BLOCK_SIZE ? SHA256_BLOCK_SIZE : len;

        /* IKEY: key xored with 0x36. */
        memcpy(kxor, seed, sizeof(kxor));
        for (unsigned int i = 0; i < sizeof(kxor); i++) kxor[i] ^= 0x36;

        /* Obtain HASH(IKEY||MESSAGE). */

Review comment (suggestion):
`\0` is a more common way to express the ASCII nul character.

```suggestion
    buff[sizeof(seed) * 2] = '\0';
```

Code after:
    if (fp) fclose(fp);
}

/* This function receives a string with 64 bytes encoded as 128 hexadecimal
 * digits, and sets the 64 byte random seed. */
void setRandomSeedCString(char *seed_str, size_t len) {
    assert(len == sizeof(seed) * 2);
    for (size_t i = 0; i < sizeof(seed); i++) {
        sscanf(seed_str + (i * 2), "%02hhX", &seed[i]);
    }
    seed_initialized = 1;
}

/* This function populates a char buffer with 129 bytes with the 64 bytes
 * random seed encoded as 128 hexadecimal digits and a null terminator. */
void getRandomSeedCString(char *buff, size_t len) {
    assert(len == (sizeof(seed) * 2 + 1));

    if (!seed_initialized) {
        initializeRandomSeed();
    }

    for (size_t i = 0; i < sizeof(seed); i++) {
        snprintf(buff + (i * 2), 3, "%02hhX", seed[i]);
    }
    buff[sizeof(seed) * 2] = '\0';
}

/* 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. */
void getRandomBytes(unsigned char *p, size_t len) {
    static uint64_t counter = 0; /* The counter we hash with the seed. */

    if (!seed_initialized) {
        initializeRandomSeed();
    }

    while (len) {
        /* This implements SHA256-HMAC. */
        unsigned char digest[SHA256_BLOCK_SIZE];
        unsigned char kxor[64];
        unsigned int copylen = len > SHA256_BLOCK_SIZE ? SHA256_BLOCK_SIZE : len;

        /* IKEY: key xored with 0x36. */
        memcpy(kxor, seed, sizeof(kxor));
        for (unsigned int i = 0; i < sizeof(kxor); i++) kxor[i] ^= 0x36;

        /* Obtain HASH(IKEY||MESSAGE). */