Skip to content

Commit

Permalink
Merge pull request #145 from siemens/jan/openssl
Browse files Browse the repository at this point in the history
example: openssl: Add random numbers according to FIPS 186-4 B.1.1
  • Loading branch information
BaochengSu authored Dec 26, 2019
2 parents 6ffbfdb + b6fdbed commit aaf54c9
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
From 8c17c622d4eba6cfda935a1de7ff85dc99f4b2e7 Mon Sep 17 00:00:00 2001
From: Markus Heintel <[email protected]>
Date: Fri, 20 Dec 2019 10:35:30 +0100
Subject: [PATCH] make bnrand_range() reliable with deterministic run time

This reworks bnrand_range() to the recommendation of BSI TR-02102-1 as
well as FIPS 186-4 B.1.1, using a Lemire algorithm with bounded
runtime.
---
crypto/bn/bn_rand.c | 69 ++++++++++++++++++++++++-----------------------------
1 file changed, 31 insertions(+), 38 deletions(-)

diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c
index 6b4b50a068..c3715a24e1 100644
--- a/crypto/bn/bn_rand.c
+++ b/crypto/bn/bn_rand.c
@@ -14,6 +14,8 @@
#include <openssl/rand.h>
#include <openssl/sha.h>

+#define BN_RAND_RANGE_BSI_TR_02102_1_EXTRA_BITS 64
+
typedef enum bnrand_flag_e {
NORMAL, TESTING, PRIVATE
} BNRAND_FLAG;
@@ -124,50 +126,41 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range)

/* BN_is_bit_set(range, n - 1) always holds */

- if (n == 1)
+ if (n == 1) {
BN_zero(r);
- else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {
+ } else {
/*
- * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer
- * than range
+ * Bounded random number according to Method 2 in Table B4 on p. 70
+ * of the BSI document "BSI - Technical Guideline, Cryptographic
+ * Mechanisms: Recommendations and Key Lengths, BSI TR-02102-1,
+ * Version 2018-02, May 29, 2018"
+ *
+ * Instead of a modulo reduction a mapping according to Lemire is
+ * used to convert from 0 < r < 2^n to 0 < r < range.
*/
- do {
- if (!bnrand(flag, r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
- return 0;
-
- /*
- * If r < 3*range, use r := r MOD range (which is either r, r -
- * range, or r - 2*range). Otherwise, iterate once more. Since
- * 3*range = 11..._2, each iteration succeeds with probability >=
- * .75.
- */
- if (BN_cmp(r, range) >= 0) {
- if (!BN_sub(r, r, range))
- return 0;
- if (BN_cmp(r, range) >= 0)
- if (!BN_sub(r, r, range))
- return 0;
- }
-
- if (!--count) {
- BNerr(BN_F_BNRAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
- return 0;
- }
+ BIGNUM *rl = NULL;
+ BN_CTX *rctx = NULL;

+ if ((rl = BN_new()) == NULL) {
+ return 0;
}
- while (BN_cmp(r, range) >= 0);
- } else {
- do {
- /* range = 11..._2 or range = 101..._2 */
- if (!bnrand(flag, r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
- return 0;
-
- if (!--count) {
- BNerr(BN_F_BNRAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
- return 0;
- }
+ if (!bnrand(flag, rl, n + BN_RAND_RANGE_BSI_TR_02102_1_EXTRA_BITS,
+ BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
+ BN_free(rl);
+ return 0;
}
- while (BN_cmp(r, range) >= 0);
+ if (((rctx = BN_CTX_new()) == NULL)
+ || !BN_mul(rl, rl, range, rctx)
+ || !BN_rshift(rl, rl,
+ n + BN_RAND_RANGE_BSI_TR_02102_1_EXTRA_BITS)
+ || (BN_copy(r, rl) == NULL)) {
+ BN_free(rl);
+ BN_CTX_free(rctx);
+ return 0;
+ }
+
+ BN_free(rl);
+ BN_CTX_free(rctx);
}

bn_check_top(r);
--
2.16.4

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"

SRC_URI += "file://0001-make-bnrand_range-reliable-with-deterministic-run-ti.patch"

0 comments on commit aaf54c9

Please sign in to comment.