getRandomBytes(): use HMAC-SHA256.
Now that we have an interface to use this API directly, via ACL GENPASS, we are no longer sure what people could do with it. So why don't make it a strong primitive exported by Redis in order to create unique IDs and so forth? The implementation was tested against the test vectors that can be found in RFC4231.
This commit is contained in:
parent
a95a086be7
commit
9ae8254e20
38
src/util.c
38
src/util.c
@ -42,7 +42,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "sha1.h"
|
#include "sha256.h"
|
||||||
|
|
||||||
/* Glob-style pattern matching. */
|
/* Glob-style pattern matching. */
|
||||||
int stringmatchlen(const char *pattern, int patternLen,
|
int stringmatchlen(const char *pattern, int patternLen,
|
||||||
@ -622,7 +622,7 @@ int ld2string(char *buf, size_t len, long double value, ld2string_mode mode) {
|
|||||||
void getRandomBytes(unsigned char *p, size_t len) {
|
void getRandomBytes(unsigned char *p, size_t len) {
|
||||||
/* Global state. */
|
/* Global state. */
|
||||||
static int seed_initialized = 0;
|
static int seed_initialized = 0;
|
||||||
static unsigned char seed[20]; /* The SHA1 seed, from /dev/urandom. */
|
static unsigned char seed[64]; /* 512 bit internal block size. */
|
||||||
static uint64_t counter = 0; /* The counter we hash with the seed. */
|
static uint64_t counter = 0; /* The counter we hash with the seed. */
|
||||||
|
|
||||||
if (!seed_initialized) {
|
if (!seed_initialized) {
|
||||||
@ -647,14 +647,34 @@ void getRandomBytes(unsigned char *p, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while(len) {
|
while(len) {
|
||||||
unsigned char digest[20];
|
/* This implements SHA256-HMAC. */
|
||||||
SHA1_CTX ctx;
|
unsigned char digest[SHA256_BLOCK_SIZE];
|
||||||
unsigned int copylen = len > 20 ? 20 : len;
|
unsigned char kxor[64];
|
||||||
|
unsigned int copylen =
|
||||||
|
len > SHA256_BLOCK_SIZE ? SHA256_BLOCK_SIZE : len;
|
||||||
|
|
||||||
SHA1Init(&ctx);
|
/* IKEY: key xored with 0x36. */
|
||||||
SHA1Update(&ctx, seed, sizeof(seed));
|
memcpy(kxor,seed,sizeof(kxor));
|
||||||
SHA1Update(&ctx, (unsigned char*)&counter,sizeof(counter));
|
for (unsigned int i = 0; i < sizeof(kxor); i++) kxor[i] ^= 0x36;
|
||||||
SHA1Final(digest, &ctx);
|
|
||||||
|
/* Obtain HASH(IKEY||MESSAGE). */
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
sha256_init(&ctx);
|
||||||
|
sha256_update(&ctx,kxor,sizeof(kxor));
|
||||||
|
sha256_update(&ctx,(unsigned char*)&counter,sizeof(counter));
|
||||||
|
sha256_final(&ctx,digest);
|
||||||
|
|
||||||
|
/* OKEY: key xored with 0x5c. */
|
||||||
|
memcpy(kxor,seed,sizeof(kxor));
|
||||||
|
for (unsigned int i = 0; i < sizeof(kxor); i++) kxor[i] ^= 0x5C;
|
||||||
|
|
||||||
|
/* Obtain HASH(OKEY || HASH(IKEY||MESSAGE)). */
|
||||||
|
sha256_init(&ctx);
|
||||||
|
sha256_update(&ctx,kxor,sizeof(kxor));
|
||||||
|
sha256_update(&ctx,digest,SHA256_BLOCK_SIZE);
|
||||||
|
sha256_final(&ctx,digest);
|
||||||
|
|
||||||
|
/* Increment the counter for the next iteration. */
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
memcpy(p,digest,copylen);
|
memcpy(p,digest,copylen);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user