From patchwork Fri Aug 31 20:42:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 145692 Delivered-To: patch@linaro.org Received: by 2002:a2e:1648:0:0:0:0:0 with SMTP id 8-v6csp1210451ljw; Fri, 31 Aug 2018 13:43:21 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaW8qVRdbip9PYIVgN2wJeQkFCLn4Ryu18GPxEvdNFTJwLXvK1JdNkGDdLSc7fpU4ptXFSF X-Received: by 2002:a63:740f:: with SMTP id p15-v6mr16276050pgc.395.1535748201692; Fri, 31 Aug 2018 13:43:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535748201; cv=none; d=google.com; s=arc-20160816; b=AGZdFTcomAVVeNLDt0dLD4QrE/CwhUzirdVoXJCL+Z+uuWF2X6UY5cLFMWgmxMw2DU 1t93+lRhZ3BxEqf1jvm5Fk3z9YQABbVq+GGt/zvGO0Kmu3TQQqAu4UbR167MzrBzC3OH fcnX8haKVfFBlvNMaAJWj7L3mm3kFLhOWrBsMFUnApFsGggMxNYysrgE0vKqwOAjeZqb bzxIHJySac0WI7NCJ/V5UUP1i7frrkO+XxA5IVymPT94zhqIynyZ0okUywEjs8MF5Y7n SEy/KIt6L+jx0sYRRZTqXPgW1JSPwAScLvdIJJcbTkgnkJgmwwqCOw+gRQa5RI5d7hb4 J+sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature:arc-authentication-results; bh=yZyyjfojeCu0/fTxm4tkjc7oXIDo6lf0EW8Sb8YJY18=; b=Fb+916fjjNg/w/i+qH0DzqGntMbGQjCIBAhRxNcewVs0OE9D42cX7KCszfHAUWzMY8 r5zYEivjrPNTi0ozfvdXyy4K4FhDuyZ77NMjaZPbyHdUhmdFwKrh1BdmxDDpgmvLZrLn OZptRQHWAtFg/3a2Yo9qfU63HWE8KoLXz1NdiDjxKbeq5hZmrNh6KFbWLvjKhp9yQLVU 5kxeeTcW6/wIa86IiDbmvN3jINDP9iTeDzrl5TzottBWhXwJ9HRTBBH/xZkpTJ8OVP1K ZrxLHYJ/FHr5OJkUFYhFfB/eHc6lpZ8wsQ5G11x2NVYTmK7YZ4GYTkJ0R2a3ErOpHzHU K+Dg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=vBhZWtLt; dkim=pass header.i=@linaro.org header.s=google header.b=DDmzFIdt; spf=pass (google.com: domain of libc-alpha-return-95624-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-95624-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id az1-v6si3371719plb.513.2018.08.31.13.43.21 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 13:43:21 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-95624-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=vBhZWtLt; dkim=pass header.i=@linaro.org header.s=google header.b=DDmzFIdt; spf=pass (google.com: domain of libc-alpha-return-95624-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-95624-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=x/wGEPDLx5IhvARgCpRF3ylh+pvU5W6 1osxq4yvEX5S6xil9NhYuk8y3LdcuzsuA4ZD5jY9MCN6yCo3n8Ma9iN7zYT4ypzg Sj8aIrRGuJGrkeTBI8ngcwk0VZLrbRDwVIYq66lUye6wsCGtRn+wFBsPZQ4sRfQg 7tzncnFBaCMs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=LwBI2xo+mx/9qGOBqcqBtSgoNIM=; b=vBhZW tLtJCwRswh3i+MNdQh0FiSB2gsaQ1qcE4T05mm7p3Q4fOk9WADbqiOrz/+kW9bJW N8NIDfaLXg8ZN0YHALxrJ1RAAlU7H8fKEIoBBPjPuxAX7A9hdyIxRrG5IkyNYkew crBLCzXfth1irAffeICRrTPBWoDP5a8GA78+eQ= Received: (qmail 54226 invoked by alias); 31 Aug 2018 20:42:53 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 54107 invoked by uid 89); 31 Aug 2018 20:42:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SEM_URI, SEM_URIRED, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-qt0-f193.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=yZyyjfojeCu0/fTxm4tkjc7oXIDo6lf0EW8Sb8YJY18=; b=DDmzFIdt1/eqmH4PgBAsT7jcCixVQ9IdaxV6XZKF8cJk3pgngHbB6BVripTACCwNfY a8Eq94F0816z5FXROj1KkwytE/nv0w8bxwRpAFkv4vQzedOOZ4P1FB13bXTz8NFHyiVl S7+iL+ReJM6uow3Jj5Sn8EKmiv9xIVJN4PiCI= Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 2/7] support: Add pseudo-random number generator interface Date: Fri, 31 Aug 2018 17:42:33 -0300 Message-Id: <20180831204238.10626-3-adhemerval.zanella@linaro.org> In-Reply-To: <20180831204238.10626-1-adhemerval.zanella@linaro.org> References: <20180831204238.10626-1-adhemerval.zanella@linaro.org> This is based on POSIX mrand48 and the interfaces provided is just wrapping around common usages (buffer fill and uniform distribution). Although better PNRGs exists, the already in place POSIXs one is used for simplicity and a better de factor one is being discussed for inclusion (arc4random based on AES-CTR). Ideally it would replace the mrand48 usage for this interface. Checked on x86_64-linux-gnu. * support/Makefile (libsupport-routines): Add support_random. (tests): Add tst-support_random. * support/support_random.c: New file. * support/support_random.h: Likewise. --- support/Makefile | 3 +- support/support_random.c | 90 ++++++++++++++++++++++++++++++++++++++++ support/support_random.h | 59 ++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 support/support_random.c create mode 100644 support/support_random.h -- 2.17.1 diff --git a/support/Makefile b/support/Makefile index 9063046c23..db46be606e 100644 --- a/support/Makefile +++ b/support/Makefile @@ -56,6 +56,7 @@ libsupport-routines = \ support_openpty \ support_quote_blob \ support_record_failure \ + support_random \ support_run_diff \ support_shared_allocate \ support_test_compare_blob \ @@ -161,7 +162,7 @@ tests = \ tst-support_record_failure \ tst-test_compare \ tst-test_compare_blob \ - tst-xreadlink \ + tst-xreadlink ifeq ($(run-built-tests),yes) tests-special = \ diff --git a/support/support_random.c b/support/support_random.c new file mode 100644 index 0000000000..5feee1a213 --- /dev/null +++ b/support/support_random.c @@ -0,0 +1,90 @@ +/* Function for pseudo-random number generation. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +void +support_random_seed (support_random_state *state, uint32_t seed) +{ + unsigned short int seed16v[3] = { 0 }; + memcpy (seed16v, &seed, sizeof (seed)); + seed48_r (seed16v, state); +} + +void +support_random_rseed (support_random_state *state) +{ + unsigned short int buf[3]; + size_t len = sizeof buf; + + ssize_t ret = getrandom (buf, len, 0); + if (ret != len) + { + int fd = xopen ("/dev/urandom", O_RDONLY, 0); + uintptr_t pbuf = (uintptr_t) buf; + uintptr_t pend = pbuf + len; + while (pbuf < pend) + { + ret = read (fd, buf, pend - pbuf); + if (ret <= 0) + FAIL_EXIT1 ("read %zu bytes from /dev/urandom failed: %m", + pend - pbuf); + pbuf += ret; + } + close (fd); + } + + seed48_r (buf, state); +} + +uint32_t +support_random_u32 (support_random_state *state) +{ + long int rl; + mrand48_r (state, &rl); + return rl; +} + +void +support_random_buf (support_random_state *state, void *buf, size_t nbytes) +{ + size_t nw = nbytes / sizeof (uint32_t); + for (size_t i = 0; i < nw; i++) + { + uint32_t r = support_random_u32 (state); + memcpy (buf, &r, sizeof (uint32_t)); + buf = (void*)((uintptr_t)buf + sizeof (uint32_t)); + } + + size_t nb = nbytes % sizeof (uint32_t); + if (nb != 0) + { + uint32_t r = support_random_u32 (state); + memcpy (buf, &r, nb); + } +} diff --git a/support/support_random.h b/support/support_random.h new file mode 100644 index 0000000000..8224c2b774 --- /dev/null +++ b/support/support_random.h @@ -0,0 +1,59 @@ +/* Function for pseudo-random number generation. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef SUPPORT_MT_RAND_H +#define SUPPORT_MT_RAND_H + +#include +#include + +typedef struct drand48_data support_random_state; + +void support_random_seed (support_random_state *state, uint32_t seed); +void support_random_rseed (support_random_state *state); + +uint32_t support_random_u32 (support_random_state *state); +void support_random_buf (support_random_state *state, void *buf, + size_t nbytes); + +/* Scales the number NUMBER to the uniformly distributed closed internal + [min, max]. */ +static inline uint32_t +support_random_uniform_distribution (support_random_state *state, + uint32_t min, uint32_t max) +{ + uint32_t ret; + uint32_t range = max - min; + /* It assumes the input random number RANDOM range is as larger or equal + than the RANGE, so the result will either returned or downscaled. */ + if (range != UINT32_MAX) + { + uint32_t urange = range + 1; /* range can be 0. */ + uint32_t scaling = UINT32_MAX / urange; + uint32_t past = urange * scaling; + do + ret = support_random_u32 (state); + while (ret >= past); + ret /= scaling; + } + else + ret = support_random_u32 (state); + return ret + min; +} + +#endif