Skip to content

Commit 0d54feb

Browse files
committed
fix PRGN warnings + make room for more secrets
1 parent 7bf078d commit 0d54feb

File tree

5 files changed

+174
-56
lines changed

5 files changed

+174
-56
lines changed

fio-stl.h

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3308,7 +3308,7 @@ Defining a Pseudo-Random Number Generator Function (deterministic / not)
33083308
0x4bb8d885a0fe47d5ULL + seed_offset, \
33093309
0x95561f0927ad7ecdULL, \
33103310
0}; \
3311-
extern void name##_reset(void) { \
3311+
extern __attribute__((unused)) void name##_reset(void) { \
33123312
name##___state[0] = 0x9c65875be1fce7b9ULL + seed_offset; \
33133313
name##___state[1] = 0x7cc568e838f6a40dULL; \
33143314
name##___state[2] = 0x4bb8d885a0fe47d5ULL + seed_offset; \
@@ -3335,12 +3335,12 @@ Defining a Pseudo-Random Number Generator Function (deterministic / not)
33353335
} \
33363336
} \
33373337
/** Re-seeds the PNGR so forked processes don't match. */ \
3338-
extern void name##_on_fork(void *is_null) { \
3338+
extern __attribute__((unused)) void name##_on_fork(void *is_null) { \
33393339
(void)is_null; \
33403340
name##___state_reseed(name##___state); \
33413341
} \
33423342
/** Returns a 128 bit pseudo-random number. */ \
3343-
extern fio_u128 name##128(void) { \
3343+
extern __attribute__((unused)) fio_u128 name##128(void) { \
33443344
fio_u256 r; \
33453345
if (!((name##___state[4]++) & ((1ULL << reseed_log) - 1)) && \
33463346
((size_t)(reseed_log - 1) < 63)) \
@@ -3375,15 +3375,15 @@ Defining a Pseudo-Random Number Generator Function (deterministic / not)
33753375
return r.u128[0]; \
33763376
} \
33773377
/** Returns a 64 bit pseudo-random number. */ \
3378-
extern uint64_t name##64(void) { \
3378+
extern __attribute__((unused)) uint64_t name##64(void) { \
33793379
static size_t counter; \
33803380
static fio_u128 r; \
33813381
if (!((counter++) & 1)) \
33823382
r = name##128(); \
33833383
return r.u64[counter & 1]; \
33843384
} \
33853385
/** Fills the `dest` buffer with pseudo-random noise. */ \
3386-
extern void name##_bytes(void *dest, size_t len) { \
3386+
extern __attribute__((unused)) void name##_bytes(void *dest, size_t len) { \
33873387
if (!dest || !len) \
33883388
return; \
33893389
uint8_t *d = (uint8_t *)dest; \
@@ -24500,6 +24500,12 @@ SFUNC fio_u512 fio_secret(void);
2450024500
/** Sets a (possibly shared) secret and stores its SHA512 hash. */
2450124501
SFUNC void fio_secret_set(char *str, size_t len, bool is_random);
2450224502

24503+
/** Sets a (possibly shared) secret and stores its SHA512 hash. */
24504+
SFUNC void fio_secret_set_at(fio_u512 *secret, char *str, size_t len);
24505+
24506+
/** Gets the SHA512 of a (possibly shared) secret. */
24507+
SFUNC fio_u512 fio_secret_at(fio_u512 *secret);
24508+
2450324509
/* *****************************************************************************
2450424510
Module Implementation - possibly externed functions.
2450524511
***************************************************************************** */
@@ -24509,6 +24515,8 @@ static fio_u512 fio___secret;
2450924515
static bool fio___secret_is_random;
2451024516
static uint64_t fio___secret_masker;
2451124517

24518+
FIO_DEFINE_RANDOM128_FN(static, fio___secret_rand, 1, 0)
24519+
2451224520
/** Returns true if the secret was randomly generated. */
2451324521
SFUNC bool fio_secret_is_random(void) { return fio___secret_is_random; }
2451424522

@@ -24522,10 +24530,21 @@ SFUNC fio_u512 fio_secret(void) {
2452224530
/** Sets a (possibly shared) secret and stores its SHA512 hash. */
2452324531
SFUNC void fio_secret_set(char *str, size_t len, bool is_random) {
2452424532
if (!str || !len)
24533+
is_random = 1;
24534+
fio_secret_set_at(&fio___secret, str, len);
24535+
fio___secret_is_random = is_random;
24536+
}
24537+
24538+
/** Sets a (possibly shared) secret and stores its SHA512 hash. */
24539+
SFUNC void fio_secret_set_at(fio_u512 *secret, char *str, size_t len) {
24540+
if (!secret)
2452524541
return;
24542+
fio_u512 random_buffer = {0};
2452624543
fio_u512 zero = {0};
2452724544
size_t i = 0;
2452824545
FIO_STR_INFO_TMP_VAR(from_hex, 4096);
24546+
if (!str)
24547+
len = 0;
2452924548
if (len > 8191)
2453024549
goto done;
2453124550
/* convert any Hex data to bytes */
@@ -24551,37 +24570,45 @@ SFUNC void fio_secret_set(char *str, size_t len, bool is_random) {
2455124570
str = from_hex.buf;
2455224571
len = from_hex.len;
2455324572
}
24573+
if (!len) {
24574+
str = (char *)random_buffer.u8;
24575+
len = sizeof(random_buffer);
24576+
fio___secret_rand_bytes(random_buffer.u8, sizeof(random_buffer));
24577+
}
2455424578

2455524579
done:
24556-
fio___secret_is_random = is_random;
24557-
fio___secret = fio_sha512(str, len);
24558-
if (fio_u512_is_eq(&zero, &fio___secret)) {
24559-
fio___secret.u64[0] = len;
24560-
fio___secret = fio_sha512(fio___secret.u8, sizeof(fio___secret));
24580+
24581+
*secret = fio_sha512(str, len);
24582+
if (fio_u512_is_eq(&zero, secret)) {
24583+
secret->u64[0] = len;
24584+
secret[0] = fio_sha512(secret->u8, sizeof(*secret));
2456124585
}
24562-
while (!(fio___secret_masker = fio_rand64()))
24586+
while (!(fio___secret_masker = fio___secret_rand64()))
2456324587
;
24564-
fio_u512_cxor64(&fio___secret, &fio___secret, fio___secret_masker);
24588+
fio_u512_cxor64(secret, secret, fio___secret_masker);
24589+
}
24590+
24591+
/** Gets the SHA512 of a (possibly shared) secret. */
24592+
SFUNC fio_u512 fio_secret_at(fio_u512 *secret) {
24593+
fio_u512 r;
24594+
fio_u512_cxor64(&r, secret, fio___secret_masker);
24595+
return r;
2456524596
}
2456624597

2456724598
FIO_CONSTRUCTOR(fio___secret_constructor) {
2456824599
char *str = NULL;
2456924600
size_t len = 0;
24570-
uint64_t fallback_secret = 0;
24571-
bool is_random = 0;
2457224601
if ((str = getenv("SECRET"))) {
2457324602
const char *secret_length = getenv("SECRET_LENGTH");
2457424603
len = secret_length ? fio_atol((char **)&secret_length) : 0;
2457524604
if (!len)
2457624605
len = strlen(str);
24577-
} else {
24578-
fallback_secret = fio_rand64();
24579-
str = (char *)&fallback_secret;
24580-
len = sizeof(fallback_secret);
24581-
is_random = 1;
24606+
if (!len)
24607+
str = NULL;
2458224608
}
24583-
fio_secret_set(str, len, is_random);
24609+
fio_secret_set(str, len, 0);
2458424610
}
24611+
2458524612
/* *****************************************************************************
2458624613
Module Cleanup
2458724614
***************************************************************************** */

fio-stl.md

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6986,39 +6986,71 @@ Secrets should be kept secret.
69866986

69876987
Secrets should **not** be kept in source files, which too often end up end up exposed.
69886988

6989-
Additionally, secrets should **not** be used directly. It is better to use a hashed value of the secret, possible with some time based salt or spice.
6989+
Secrets should **not** be logged (such as in case of a crash or a core dump).
69906990

6991-
This way, if somehow information leaks regarding the secret, what is exposed is actually the hashed value and not the secret itself.
6991+
Additionally, secrets should **not** be used directly if possible. It is better to use a hashed value of the secret, possible with some time based salt or spice. This way, if somehow information leaks regarding the secret, what is exposed is actually the hashed value and not the secret itself.
69926992

69936993
For this reason, the most common place to place a secret is as a hashed value in the OS environment (often as a Hex encoded String).
69946994

6995-
The following helper functions are defined:
6995+
**Note**: some secrets, such as TLS certificates, are often stored as system files somewhere separate from the source code.
69966996

6997+
To help with managing a program wide secret, the following helper functions are defined:
69976998

6998-
#### `fio_secret_is_random`
6999+
7000+
#### `fio_secret_set_at`
69997001

70007002
```c
7001-
bool fio_secret_is_random(void);
7003+
void fio_secret_set_at(fio_u512 *secret, char *str, size_t len);
70027004
```
70037005

7004-
Returns true if the secret was randomly generated.
7006+
Sets a (possibly shared) secret and stores its (masked) SHA512 hash in `secret`.
7007+
7008+
**Note**: the SHA512 hash in `secret` is masked before it is stored, so that the final secret isn't logged in case of a core dump.
7009+
7010+
#### `fio_secret_at`
7011+
7012+
```c
7013+
fio_u512 fio_secret_at(fio_u512 *secret);
7014+
```
7015+
7016+
Gets the SHA512 of a (possibly shared) masked secret stored in `secret`.
7017+
7018+
Please store the returned value on the stack or not at all. The secret is stored masked in memory and unmasked copies should be temporary with short life-spans.
70057019

70067020
#### `fio_secret`
70077021

70087022
```c
70097023
fio_u512 fio_secret(void);
70107024
```
70117025

7012-
Gets the SHA512 of a (possibly shared) secret.
7026+
Returns the SHA512 of a (possibly shared) secret.
7027+
7028+
Unless updated using `fio_secret_set`, this is either a random secret or the one derived from the `SECRET` environment variable.
7029+
7030+
Please store the returned value on the stack or not at all. The secret is stored masked in memory and unmasked copies should be temporary with short life-spans.
70137031

70147032
#### `fio_secret_set`
70157033

70167034
```c
7017-
void fio_secret_set(char *str, size_t len, bool is_random);
7035+
void fio_secret_set(char *secret, size_t len, bool is_random);
70187036
```
70197037

70207038
Sets a (possibly shared) secret and stores its SHA512 hash.
70217039

7040+
If `secret` is Hex encoded, it will be decoded before it is hashed and white spaces will be ignored.
7041+
7042+
**Note**: the SHA512 hash is masked before it is stored, so that the final secret isn't logged in case of a core dump.
7043+
7044+
7045+
#### `fio_secret_is_random`
7046+
7047+
```c
7048+
bool fio_secret_is_random(void);
7049+
```
7050+
7051+
Returns true if the secret was randomly generated.
7052+
7053+
70227054
-------------------------------------------------------------------------------
70237055
## Dynamic Strings
70247056

fio-stl/000 core.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3271,7 +3271,7 @@ Defining a Pseudo-Random Number Generator Function (deterministic / not)
32713271
0x4bb8d885a0fe47d5ULL + seed_offset, \
32723272
0x95561f0927ad7ecdULL, \
32733273
0}; \
3274-
extern void name##_reset(void) { \
3274+
extern __attribute__((unused)) void name##_reset(void) { \
32753275
name##___state[0] = 0x9c65875be1fce7b9ULL + seed_offset; \
32763276
name##___state[1] = 0x7cc568e838f6a40dULL; \
32773277
name##___state[2] = 0x4bb8d885a0fe47d5ULL + seed_offset; \
@@ -3298,12 +3298,12 @@ Defining a Pseudo-Random Number Generator Function (deterministic / not)
32983298
} \
32993299
} \
33003300
/** Re-seeds the PNGR so forked processes don't match. */ \
3301-
extern void name##_on_fork(void *is_null) { \
3301+
extern __attribute__((unused)) void name##_on_fork(void *is_null) { \
33023302
(void)is_null; \
33033303
name##___state_reseed(name##___state); \
33043304
} \
33053305
/** Returns a 128 bit pseudo-random number. */ \
3306-
extern fio_u128 name##128(void) { \
3306+
extern __attribute__((unused)) fio_u128 name##128(void) { \
33073307
fio_u256 r; \
33083308
if (!((name##___state[4]++) & ((1ULL << reseed_log) - 1)) && \
33093309
((size_t)(reseed_log - 1) < 63)) \
@@ -3338,15 +3338,15 @@ Defining a Pseudo-Random Number Generator Function (deterministic / not)
33383338
return r.u128[0]; \
33393339
} \
33403340
/** Returns a 64 bit pseudo-random number. */ \
3341-
extern uint64_t name##64(void) { \
3341+
extern __attribute__((unused)) uint64_t name##64(void) { \
33423342
static size_t counter; \
33433343
static fio_u128 r; \
33443344
if (!((counter++) & 1)) \
33453345
r = name##128(); \
33463346
return r.u64[counter & 1]; \
33473347
} \
33483348
/** Fills the `dest` buffer with pseudo-random noise. */ \
3349-
extern void name##_bytes(void *dest, size_t len) { \
3349+
extern __attribute__((unused)) void name##_bytes(void *dest, size_t len) { \
33503350
if (!dest || !len) \
33513351
return; \
33523352
uint8_t *d = (uint8_t *)dest; \

fio-stl/160 secret.h

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ SFUNC fio_u512 fio_secret(void);
2828
/** Sets a (possibly shared) secret and stores its SHA512 hash. */
2929
SFUNC void fio_secret_set(char *str, size_t len, bool is_random);
3030

31+
/** Sets a (possibly shared) secret and stores its SHA512 hash. */
32+
SFUNC void fio_secret_set_at(fio_u512 *secret, char *str, size_t len);
33+
34+
/** Gets the SHA512 of a (possibly shared) secret. */
35+
SFUNC fio_u512 fio_secret_at(fio_u512 *secret);
36+
3137
/* *****************************************************************************
3238
Module Implementation - possibly externed functions.
3339
***************************************************************************** */
@@ -37,6 +43,8 @@ static fio_u512 fio___secret;
3743
static bool fio___secret_is_random;
3844
static uint64_t fio___secret_masker;
3945

46+
FIO_DEFINE_RANDOM128_FN(static, fio___secret_rand, 1, 0)
47+
4048
/** Returns true if the secret was randomly generated. */
4149
SFUNC bool fio_secret_is_random(void) { return fio___secret_is_random; }
4250

@@ -50,10 +58,21 @@ SFUNC fio_u512 fio_secret(void) {
5058
/** Sets a (possibly shared) secret and stores its SHA512 hash. */
5159
SFUNC void fio_secret_set(char *str, size_t len, bool is_random) {
5260
if (!str || !len)
61+
is_random = 1;
62+
fio_secret_set_at(&fio___secret, str, len);
63+
fio___secret_is_random = is_random;
64+
}
65+
66+
/** Sets a (possibly shared) secret and stores its SHA512 hash. */
67+
SFUNC void fio_secret_set_at(fio_u512 *secret, char *str, size_t len) {
68+
if (!secret)
5369
return;
70+
fio_u512 random_buffer = {0};
5471
fio_u512 zero = {0};
5572
size_t i = 0;
5673
FIO_STR_INFO_TMP_VAR(from_hex, 4096);
74+
if (!str)
75+
len = 0;
5776
if (len > 8191)
5877
goto done;
5978
/* convert any Hex data to bytes */
@@ -79,37 +98,45 @@ SFUNC void fio_secret_set(char *str, size_t len, bool is_random) {
7998
str = from_hex.buf;
8099
len = from_hex.len;
81100
}
101+
if (!len) {
102+
str = (char *)random_buffer.u8;
103+
len = sizeof(random_buffer);
104+
fio___secret_rand_bytes(random_buffer.u8, sizeof(random_buffer));
105+
}
82106

83107
done:
84-
fio___secret_is_random = is_random;
85-
fio___secret = fio_sha512(str, len);
86-
if (fio_u512_is_eq(&zero, &fio___secret)) {
87-
fio___secret.u64[0] = len;
88-
fio___secret = fio_sha512(fio___secret.u8, sizeof(fio___secret));
108+
109+
*secret = fio_sha512(str, len);
110+
if (fio_u512_is_eq(&zero, secret)) {
111+
secret->u64[0] = len;
112+
secret[0] = fio_sha512(secret->u8, sizeof(*secret));
89113
}
90-
while (!(fio___secret_masker = fio_rand64()))
114+
while (!(fio___secret_masker = fio___secret_rand64()))
91115
;
92-
fio_u512_cxor64(&fio___secret, &fio___secret, fio___secret_masker);
116+
fio_u512_cxor64(secret, secret, fio___secret_masker);
117+
}
118+
119+
/** Gets the SHA512 of a (possibly shared) secret. */
120+
SFUNC fio_u512 fio_secret_at(fio_u512 *secret) {
121+
fio_u512 r;
122+
fio_u512_cxor64(&r, secret, fio___secret_masker);
123+
return r;
93124
}
94125

95126
FIO_CONSTRUCTOR(fio___secret_constructor) {
96127
char *str = NULL;
97128
size_t len = 0;
98-
uint64_t fallback_secret = 0;
99-
bool is_random = 0;
100129
if ((str = getenv("SECRET"))) {
101130
const char *secret_length = getenv("SECRET_LENGTH");
102131
len = secret_length ? fio_atol((char **)&secret_length) : 0;
103132
if (!len)
104133
len = strlen(str);
105-
} else {
106-
fallback_secret = fio_rand64();
107-
str = (char *)&fallback_secret;
108-
len = sizeof(fallback_secret);
109-
is_random = 1;
134+
if (!len)
135+
str = NULL;
110136
}
111-
fio_secret_set(str, len, is_random);
137+
fio_secret_set(str, len, 0);
112138
}
139+
113140
/* *****************************************************************************
114141
Module Cleanup
115142
***************************************************************************** */

0 commit comments

Comments
 (0)