Skip to content

Commit

Permalink
random: Introduce a random generator
Browse files Browse the repository at this point in the history
This adds flb_randombytes(), which fills the given buffer with random
numbers using each OS's built-in Crypt API.

The most common use scenario is:

    unsigned char buf[64]

    if (get_randombytes(buf, 64)) {
        flb_error("cannot get random bytes");
    }

This function supports both UNIX and Windows. You can use this
function without caring the underlying OS.

Signed-off-by: Fujimoto Seiji <[email protected]>
  • Loading branch information
fujimotos committed Sep 16, 2020
1 parent 61ca4ee commit db0bade
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 0 deletions.
30 changes: 30 additions & 0 deletions include/fluent-bit/flb_random.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/* Fluent Bit
* ==========
* Copyright (C) 2019-2020 The Fluent Bit Authors
* Copyright (C) 2015-2018 Treasure Data Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef FLB_RANDOM_H
#define FLB_RANDOM_H

/*
* Fill buffer with the random bytes. Return 0 on success;
* -1 on error.
*/
int flb_randombytes(unsigned char *buf, int len);

#endif
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ set(src
flb_time.c
flb_sosreport.c
flb_sha512.c
flb_random.c
flb_plugin.c
flb_gzip.c
flb_http_client.c
Expand Down Expand Up @@ -195,6 +196,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(FLB_DEPS
"ws2_32.lib"
"crypt32.lib"
"Bcrypt.lib"
)
else()
set(FLB_DEPS
Expand Down
64 changes: 64 additions & 0 deletions src/flb_random.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/* Fluent Bit
* ==========
* Copyright (C) 2019-2020 The Fluent Bit Authors
* Copyright (C) 2015-2018 Treasure Data Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <fluent-bit/flb_compat.h>
#include <fcntl.h>

/*
* This module provides a random number generator for common use cases.
*
* On Windows, we use BCryptGenRandom() from CNG API. This function
* is available since Windows Vista, and should be compliant to the
* official recommendation.
*
* On Unix, we use /dev/urandom as a secure random source.
*/

int flb_randombytes(unsigned char *buf, int len)
{
#ifdef FLB_SYSTEM_WINDOWS
NTSTATUS ret;
ret = BCryptGenRandom(NULL, buf, len, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (!BCRYPT_SUCCESS(ret)) {
return -1;
}
return 0;
#else
int fd;
int bytes;

fd = open("/dev/urandom", O_RDONLY);
if (fd == -1) {
return -1;
}

while (len > 0) {
bytes = read(fd, buf, len);
if (bytes <= 0) {
close(fd);
return -1;
}
len -= bytes;
buf += bytes;
}
close(fd);
return 0;
#endif
}
1 change: 1 addition & 0 deletions tests/internal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set(UNIT_TESTS_FILES
utils.c
gzip.c
gelf.c
random.c
config_map.c
)

Expand Down
33 changes: 33 additions & 0 deletions tests/internal/random.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

#include <fluent-bit/flb_random.h>

#include "flb_tests_internal.h"

void test_randombytes()
{
int ret;
unsigned char buf1[64] = {0};
unsigned char buf2[64] = {0};

/* The following tests check whether:
*
* (1) the random generator fills the buffer with numbers at all.
* (2) a successive call generates different numbers.
*
* These tests are probabilistic by nature; If we assume an ideal random
* generator, they are expected to fail once in 2^192 (= 10^57) runs.
*/
ret = flb_randombytes(buf1, 64);
TEST_CHECK(ret == 0);
TEST_CHECK(memcmp(buf1, buf2, 64) != 0);

ret = flb_randombytes(buf2, 64);
TEST_CHECK(ret == 0);
TEST_CHECK(memcmp(buf1, buf2, 64) != 0);
}

TEST_LIST = {
{"randombytes", test_randombytes},
{ 0 }
};

0 comments on commit db0bade

Please sign in to comment.