Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_random.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
27#include "nilorea/n_common.h"
28#include "nilorea/n_log.h"
29#include "nilorea/n_random.h"
30#include "nilorea/n_str.h"
31
32#include <ctype.h>
33#include <stdio.h>
34#include <string.h>
35
36static int failures = 0;
37
38/* Parse the -V LOG_LEVEL verbosity argument. */
39void process_args(int argc, char** argv) {
40 int opt = 0;
41 while ((opt = getopt(argc, argv, "hvV:")) != EOF) {
42 switch (opt) {
43 case 'V':
44 if (!strncmp("LOG_NULL", optarg, 8))
46 else if (!strncmp("LOG_NOTICE", optarg, 10))
48 else if (!strncmp("LOG_INFO", optarg, 8))
50 else if (!strncmp("LOG_ERR", optarg, 7))
52 else if (!strncmp("LOG_DEBUG", optarg, 9))
54 else {
55 fprintf(stderr, "Unknown log level %s\n", optarg);
56 exit(1);
57 }
58 break;
59 case 'v':
60 fprintf(stderr, "ex_random\n");
61 exit(1);
62 case 'h':
63 default:
64 fprintf(stderr, "usage: %s [-V LOG_LEVEL]\n", argv[0]);
65 break;
66 }
67 }
68}
69
70static void test_bytes(void) {
71 unsigned char a[32];
72 unsigned char b[32];
73 memset(a, 0, sizeof(a));
74 memset(b, 0, sizeof(b));
75
76 if (n_random_bytes(a, sizeof(a)) != 0 || n_random_bytes(b, sizeof(b)) != 0) {
77 n_log(LOG_ERR, "n_random_bytes failed");
78 failures++;
79 return;
80 }
81 /* two independent 32-byte draws colliding is cryptographically impossible */
82 if (memcmp(a, b, sizeof(a)) == 0) {
83 n_log(LOG_ERR, "two random draws were identical");
84 failures++;
85 }
86 /* an all-zero 32-byte buffer after a fill is effectively impossible */
87 int all_zero = 1;
88 for (size_t i = 0; i < sizeof(a); i++) {
89 if (a[i] != 0) {
90 all_zero = 0;
91 break;
92 }
93 }
94 if (all_zero) {
95 n_log(LOG_ERR, "random buffer is all zero");
96 failures++;
97 }
98
99 /* zero length is a no-op success; NULL with n>0 is rejected */
100 if (n_random_bytes(NULL, 0) != 0) {
101 n_log(LOG_ERR, "n_random_bytes(NULL,0) should succeed");
102 failures++;
103 }
104 if (n_random_bytes(NULL, 8) == 0) {
105 n_log(LOG_ERR, "n_random_bytes(NULL,8) should fail");
106 failures++;
107 }
108}
109
110static void test_token(void) {
111 N_STR* t1 = n_random_hex_token(16);
112 N_STR* t2 = n_random_hex_token(16);
113 if (!t1 || !t2) {
114 n_log(LOG_ERR, "n_random_hex_token returned NULL");
115 failures++;
116 } else {
117 if (t1->written != 32 || t2->written != 32) {
118 n_log(LOG_ERR, "token length: got %zu/%zu expected 32", t1->written, t2->written);
119 failures++;
120 }
121 for (size_t i = 0; i < t1->written; i++) {
122 if (!isxdigit((unsigned char)t1->data[i]) || (t1->data[i] >= 'A' && t1->data[i] <= 'F')) {
123 n_log(LOG_ERR, "token has a non-lowercase-hex character at %zu", i);
124 failures++;
125 break;
126 }
127 }
128 if (strcmp(t1->data, t2->data) == 0) {
129 n_log(LOG_ERR, "two tokens were identical");
130 failures++;
131 }
132 }
133 free_nstr(&t1);
134 free_nstr(&t2);
135
136 /* a zero-byte token is the empty string */
137 N_STR* t0 = n_random_hex_token(0);
138 if (!t0 || t0->written != 0) {
139 n_log(LOG_ERR, "zero-byte token should be empty");
140 failures++;
141 }
142 free_nstr(&t0);
143}
144
145int main(int argc, char** argv) {
147 process_args(argc, argv);
148
149 test_bytes();
150 test_token();
151
152 if (failures) {
153 n_log(LOG_ERR, "ex_random: %d failure(s)", failures);
154 return 1;
155 }
156 n_log(LOG_NOTICE, "ex_random: all checks passed");
157 return 0;
158}
static int failures
int main(void)
void process_args(int argc, char **argv)
Definition ex_common.c:48
static void test_bytes(void)
Definition ex_random.c:70
static void test_token(void)
Definition ex_random.c:110
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_DEBUG
debug-level messages
Definition n_log.h:84
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_NOTICE
normal but significant condition
Definition n_log.h:80
#define LOG_NULL
no log output
Definition n_log.h:46
#define LOG_INFO
informational
Definition n_log.h:82
int n_random_bytes(unsigned char *buf, size_t n)
fill buf with n cryptographically secure random bytes (getrandom(2) when available,...
Definition n_random.c:62
N_STR * n_random_hex_token(size_t nbytes)
generate nbytes secure random bytes and return them as a lowercase hex N_STR (2*nbytes characters); f...
Definition n_random.c:91
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
Definition n_str.h:68
char * data
the string
Definition n_str.h:63
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:203
A box including a string and his lenght.
Definition n_str.h:61
Common headers and low-level functions & define.
Generic log system.
Cryptographically secure random bytes and hex tokens (POSIX)
N_STR and string function declaration.