Skip to content

Commit 89454af

Browse files
Merge branch 'master' of https://www.bearssl.org/git/BearSSL
2 parents 9247320 + b715b43 commit 89454af

File tree

8 files changed

+138
-15
lines changed

8 files changed

+138
-15
lines changed

inc/bearssl_ssl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,8 +1251,8 @@ static inline void
12511251
br_ssl_engine_set_versions(br_ssl_engine_context *cc,
12521252
unsigned version_min, unsigned version_max)
12531253
{
1254-
cc->version_min = version_min;
1255-
cc->version_max = version_max;
1254+
cc->version_min = (uint16_t)version_min;
1255+
cc->version_max = (uint16_t)version_max;
12561256
}
12571257

12581258
/**
@@ -1325,7 +1325,7 @@ br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx,
13251325
const char **names, size_t num)
13261326
{
13271327
ctx->protocol_names = names;
1328-
ctx->protocol_names_num = num;
1328+
ctx->protocol_names_num = (uint16_t)num;
13291329
}
13301330

13311331
/**

src/config.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,27 @@
109109
#define BR_RDRAND 1
110110
*/
111111

112+
/*
113+
* When BR_USE_GETENTROPY is enabled, the SSL engine will use the
114+
* getentropy() function to obtain quality randomness for seeding its
115+
* internal PRNG. On Linux and FreeBSD, getentropy() is implemented by
116+
* the standard library with the system call getrandom(); on OpenBSD,
117+
* getentropy() is the system call, and there is no getrandom() wrapper,
118+
* hence the use of the getentropy() function for maximum portability.
119+
*
120+
* If the getentropy() call fails, and BR_USE_URANDOM is not explicitly
121+
* disabled, then /dev/urandom will be used as a fallback mechanism. On
122+
* FreeBSD and OpenBSD, this does not change much, since /dev/urandom
123+
* will block if not enough entropy has been obtained since last boot.
124+
* On Linux, /dev/urandom might not block, which can be troublesome in
125+
* early boot stages, which is why getentropy() is preferred.
126+
*
127+
#define BR_USE_GETENTROPY 1
128+
*/
129+
112130
/*
113131
* When BR_USE_URANDOM is enabled, the SSL engine will use /dev/urandom
114-
* to automatically obtain quality randomness for seedings its internal
132+
* to automatically obtain quality randomness for seeding its internal
115133
* PRNG.
116134
*
117135
#define BR_USE_URANDOM 1
@@ -127,7 +145,7 @@
127145
/*
128146
* When BR_USE_WIN32_RAND is enabled, the SSL engine will use the Win32
129147
* (CryptoAPI) functions (CryptAcquireContext(), CryptGenRandom()...) to
130-
* automatically obtain quality randomness for seedings its internal PRNG.
148+
* automatically obtain quality randomness for seeding its internal PRNG.
131149
*
132150
* Note: if both BR_USE_URANDOM and BR_USE_WIN32_RAND are defined, the
133151
* former takes precedence.

src/inner.h

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,20 @@
325325
* values are documented on:
326326
* https://sourceforge.net/p/predef/wiki/OperatingSystems/
327327
*
328-
* TODO: enrich the list of detected system. Also add detection for
329-
* alternate system calls like getentropy(), which are usually
330-
* preferable when available.
328+
* Win32's CryptGenRandom() should be available on Windows systems.
329+
*
330+
* /dev/urandom should work on all Unix-like systems (including macOS X).
331+
*
332+
* getentropy() is present on Linux (Glibc 2.25+), FreeBSD (12.0+) and
333+
* OpenBSD (5.6+). For OpenBSD, there does not seem to be easy to use
334+
* macros to test the minimum version, so we just assume that it is
335+
* recent enough (last version without getentropy() has gone out of
336+
* support in May 2015).
337+
*
338+
* Ideally we should use getentropy() on macOS (10.12+) too, but I don't
339+
* know how to test the exact OS version with preprocessor macros.
340+
*
341+
* TODO: enrich the list of detected system.
331342
*/
332343

333344
#ifndef BR_USE_URANDOM
@@ -344,6 +355,15 @@
344355
#endif
345356
#endif
346357

358+
#ifndef BR_USE_GETENTROPY
359+
#if (defined __linux__ \
360+
&& (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))) \
361+
|| (defined __FreeBSD__ && __FreeBSD__ >= 12) \
362+
|| defined __OpenBSD__
363+
#define BR_USE_GETENTROPY 1
364+
#endif
365+
#endif
366+
347367
#ifndef BR_USE_WIN32_RAND
348368
#if defined _WIN32 || defined _WIN64
349369
#define BR_USE_WIN32_RAND 1

src/rand/sysrng.c

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
#define BR_ENABLE_INTRINSICS 1
2626
#include "inner.h"
2727

28+
#if BR_USE_GETENTROPY
29+
#include <unistd.h>
30+
#endif
31+
2832
#if BR_USE_URANDOM
2933
#include <sys/types.h>
3034
#include <unistd.h>
@@ -38,6 +42,9 @@
3842
#pragma comment(lib, "advapi32")
3943
#endif
4044

45+
/*
46+
* Seeder that uses the RDRAND opcodes (on x86 CPU).
47+
*/
4148
#if BR_RDRAND
4249
BR_TARGETS_X86_UP
4350
BR_TARGET("rdrnd")
@@ -57,9 +64,24 @@ seeder_rdrand(const br_prng_class **ctx)
5764
*
5865
* Intel recommends trying at least 10 times in case of
5966
* failure.
67+
*
68+
* AMD bug: there are reports that some AMD processors
69+
* have a bug that makes them fail silently after a
70+
* suspend/resume cycle, in which case RDRAND will report
71+
* a success but always return 0xFFFFFFFF.
72+
* see: https://bugzilla.kernel.org/show_bug.cgi?id=85911
73+
*
74+
* As a mitigation, if the 32-bit value is 0 or -1, then
75+
* it is considered a failure and tried again. This should
76+
* reliably detect the buggy case, at least. This also
77+
* implies that the selected seed values can never be
78+
* 0x00000000 or 0xFFFFFFFF, which is not a problem since
79+
* we are generating a seed for a PRNG, and we overdo it
80+
* a bit (we generate 32 bytes of randomness, and 256 bits
81+
* of entropy are really overkill).
6082
*/
6183
for (j = 0; j < 10; j ++) {
62-
if (_rdrand32_step(&x)) {
84+
if (_rdrand32_step(&x) && x != 0 && x != (uint32_t)-1) {
6385
goto next_word;
6486
}
6587
}
@@ -80,9 +102,11 @@ rdrand_supported(void)
80102
*/
81103
return br_cpuid(0, 0, 0x40000000, 0);
82104
}
83-
84105
#endif
85106

107+
/*
108+
* Seeder that uses /dev/urandom (on Unix-like systems).
109+
*/
86110
#if BR_USE_URANDOM
87111
static int
88112
seeder_urandom(const br_prng_class **ctx)
@@ -116,6 +140,32 @@ seeder_urandom(const br_prng_class **ctx)
116140
}
117141
#endif
118142

143+
/*
144+
* Seeder that uses getentropy() (backed by getrandom() on some systems,
145+
* e.g. Linux). On failure, it will use the /dev/urandom seeder (if
146+
* enabled).
147+
*/
148+
#if BR_USE_GETENTROPY
149+
static int
150+
seeder_getentropy(const br_prng_class **ctx)
151+
{
152+
unsigned char tmp[32];
153+
154+
if (getentropy(tmp, sizeof tmp) == 0) {
155+
(*ctx)->update(ctx, tmp, sizeof tmp);
156+
return 1;
157+
}
158+
#if BR_USE_URANDOM
159+
return seeder_urandom(ctx);
160+
#else
161+
return 0;
162+
#endif
163+
}
164+
#endif
165+
166+
/*
167+
* Seeder that uses CryptGenRandom() (on Windows).
168+
*/
119169
#if BR_USE_WIN32_RAND
120170
static int
121171
seeder_win32(const br_prng_class **ctx)
@@ -153,7 +203,31 @@ seeder_esp8266(const br_prng_class **ctx)
153203
}
154204

155205
(*ctx)->update(ctx, tmp, sizeof tmp);
206+
return 1;
207+
}
208+
#endif
156209

210+
/*
211+
* An aggregate seeder that uses RDRAND, and falls back to an OS-provided
212+
* source if RDRAND fails.
213+
*/
214+
#if BR_RDRAND && (BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND)
215+
static int
216+
seeder_rdrand_with_fallback(const br_prng_class **ctx)
217+
{
218+
if (!seeder_rdrand(ctx)) {
219+
#if BR_USE_GETENTROPY
220+
return seeder_getentropy(ctx);
221+
#elif BR_USE_URANDOM
222+
return seeder_urandom(ctx);
223+
#elif BR_USE_WIN32_RAND
224+
return seeder_win32(ctx);
225+
#elif BR_USE_ESP8266_RAND
226+
return seeder_esp8266(ctx);
227+
#else
228+
#error "macro selection has gone wrong"
229+
#endif
230+
}
157231
return 1;
158232
}
159233
#endif
@@ -168,10 +242,19 @@ br_prng_seeder_system(const char **name)
168242
if (name != NULL) {
169243
*name = "rdrand";
170244
}
245+
#if BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND
246+
return &seeder_rdrand_with_fallback;
247+
#else
171248
return &seeder_rdrand;
249+
#endif
172250
}
173251
#endif
174-
#if BR_USE_URANDOM
252+
#if BR_USE_GETENTROPY
253+
if (name != NULL) {
254+
*name = "getentropy";
255+
}
256+
return &seeder_getentropy;
257+
#elif BR_USE_URANDOM
175258
if (name != NULL) {
176259
*name = "urandom";
177260
}

src/x509/asn1.t0

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ OID: id-at-commonName 2.5.4.3
480480
\ 66 noncharacters, and also the surrogate range; this function does NOT
481481
\ check that the value is in the 0..10FFFF range.
482482
: valid-unicode? ( val -- bool )
483-
dup 0xFDD0 0xFEDF between? if drop 0 ret then
483+
dup 0xFDD0 0xFDEF between? if drop 0 ret then
484484
dup 0xD800 0xDFFF between? if drop 0 ret then
485485
0xFFFF and 0xFFFE < ;
486486

src/x509/skey_decoder.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ static const unsigned char t0_codeblock[] PROGMEM = {
158158
0x02, 0x06, 0x1E, 0x00, 0x00, 0x19, 0x19, 0x00, 0x00, 0x01, 0x0B, 0x00,
159159
0x00, 0x01, 0x00, 0x20, 0x14, 0x06, 0x08, 0x01, 0x01, 0x21, 0x20, 0x22,
160160
0x20, 0x04, 0x75, 0x13, 0x00, 0x00, 0x01,
161-
T0_INT2(3 * BR_X509_BUFSIZE_KEY), 0x00, 0x01, 0x01, 0x87, 0xFF, 0xFF,
161+
T0_INT2(3 * BR_X509_BUFSIZE_SIG), 0x00, 0x01, 0x01, 0x87, 0xFF, 0xFF,
162162
0x7F, 0x54, 0x57, 0x01, 0x02, 0x3E, 0x55, 0x01, 0x01, 0x0E, 0x06, 0x02,
163163
0x30, 0x16, 0x57, 0x01, 0x02, 0x19, 0x0D, 0x06, 0x06, 0x13, 0x3B, 0x44,
164164
0x32, 0x04, 0x1C, 0x01, 0x04, 0x19, 0x0D, 0x06, 0x08, 0x13, 0x3B, 0x01,

src/x509/skey_decoder.t0

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ cc: read-blob-inner ( addr len -- addr len ) {
8080

8181
\ Get the length of the key_data buffer.
8282
: len-key_data
83-
CX 0 8191 { 3 * BR_X509_BUFSIZE_KEY } ;
83+
CX 0 8191 { 3 * BR_X509_BUFSIZE_SIG } ;
8484

8585
\ Get the address and length for the key_data buffer.
8686
: addr-len-key_data ( -- addr len )

src/x509/x509_minimal.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ static const unsigned char t0_codeblock[] PROGMEM = {
780780
0x76, 0x00, 0x00, 0x01, 0x00, 0x30, 0x31, 0x0B, 0x42, 0x00, 0x00, 0x01,
781781
0x81, 0x70, 0x00, 0x00, 0x01, 0x82, 0x0D, 0x00, 0x00, 0x01, 0x82, 0x22,
782782
0x00, 0x00, 0x01, 0x82, 0x05, 0x00, 0x00, 0x01, 0x03, 0x33, 0x01, 0x03,
783-
0x33, 0x00, 0x00, 0x25, 0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFD, 0x5F,
783+
0x33, 0x00, 0x00, 0x25, 0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFB, 0x6F,
784784
0x72, 0x06, 0x04, 0x24, 0x01, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB0, 0x00,
785785
0x01, 0x83, 0xBF, 0x7F, 0x72, 0x06, 0x04, 0x24, 0x01, 0x00, 0x00, 0x01,
786786
0x83, 0xFF, 0x7F, 0x15, 0x01, 0x83, 0xFF, 0x7E, 0x0D, 0x00
@@ -1774,3 +1774,5 @@ verify_signature(br_x509_minimal_context *ctx, const br_x509_pkey *pk)
17741774
return BR_ERR_X509_UNSUPPORTED;
17751775
}
17761776
}
1777+
1778+

0 commit comments

Comments
 (0)