Received: by 2002:a05:6358:a55:b0:ec:fcf4:3ecf with SMTP id 21csp606478rwb; Thu, 12 Jan 2023 09:55:07 -0800 (PST) X-Google-Smtp-Source: AMrXdXvv7Tggx6eiFNxMB3XEANjj9Fq5HqsaQfr9HgIS29ef2xj/Vp0o+xdUocUa0dCaHgJv+cvE X-Received: by 2002:a05:6402:685:b0:470:25cf:99d1 with SMTP id f5-20020a056402068500b0047025cf99d1mr65328105edy.31.1673546107131; Thu, 12 Jan 2023 09:55:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673546107; cv=none; d=google.com; s=arc-20160816; b=cfOWGl0lCDto3B2okj8AefhXB8XZCuoDGJx9LaWfc9iP/NPnV29KDv468ddv9E7Wgv fcFfCPXg3FqKqun5t1Gh8hJF9Kiqpz5vlQtqu8YVUknJ929jl+A/rEyc3K3mNBBGviC9 v3BGUa9p6ysnsT4ZtZqszpf7o19821G4Si2Ji65/snOUlR1Tbdf4tJPf6HPFGcYbE6pV 1JBD+aUw0Jyh8cvFFdwmj556roz0hQakjz87lBcPYL7R/mbuUeF6eXAomW/Dk+5zjXEE w8iYtOIPxJWMuBAlXgEABPvWIwDX46NOhjbbDwDTtY1nKhVRCOfmgajZqInFiCGcaVsm +BPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=3ZfikeYUdVx0FNVUbMiAr6Hcndu56cJCvatlL312VyM=; b=U8nb+Kv9nEyt5tvC1UQat15kVgPoAxLIUz0Ob4uoG4O5onna1XbFo1CLz0rvKuCKyY L+e1uZypzXrSq1QT2a68AUj0tt9Uggwfw3R2TOgOYMMEOKsa0G2bxW3tOlFGAdbv9SpF dGO14w9CytqCgJF1a7vl2O9Oy7kLZu0k1FhYJNuOtQBTov6kgMEvkD0u/kVlR81fiAje u9Jm0rCaix0FZLuFo5UfIT5T1OHMJryd7ulOAfsJnuGPi1e7Baempam62aoMiRGwdP8G 9DVxgOGuIMmozblNUeM8tk8RC9Y6CzSWtkt/JzxKwjULZha40Ds14LAyJYJQc4lhoVTZ eqsg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c26-20020aa7c99a000000b0048e82d753a3si13877580edt.227.2023.01.12.09.54.43; Thu, 12 Jan 2023 09:55:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232065AbjALRqD (ORCPT + 99 others); Thu, 12 Jan 2023 12:46:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237643AbjALRo7 (ORCPT ); Thu, 12 Jan 2023 12:44:59 -0500 Received: from smtp6-g21.free.fr (smtp6-g21.free.fr [IPv6:2a01:e0c:1:1599::15]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7760644378; Thu, 12 Jan 2023 09:03:57 -0800 (PST) Received: from localhost (unknown [IPv6:2a01:e35:39f2:1220:dc8b:b602:9bcd:3004]) by smtp6-g21.free.fr (Postfix) with ESMTPS id 87B7078036C; Thu, 12 Jan 2023 18:03:39 +0100 (CET) From: Yann Droneaud To: "Jason A. Donenfeld" , "Theodore Ts'o" Cc: Yann Droneaud , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Andy Lutomirski , Vincenzo Frascino , x86@kernel.org, linux-crypto@vger.kernel.org, linux-api@vger.kernel.org, linux-kernel@vger.kernel.org, Florian Weimer , Adhemerval Zanella Netto , "Carlos O'Donell" Subject: [RFC PATCH 2/4] random: introduce generic vDSO getrandom(,, GRND_TIMESTAMP) fast path Date: Thu, 12 Jan 2023 18:02:34 +0100 Message-Id: X-Mailer: git-send-email 2.37.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org From: "Jason A. Donenfeld" Exports base_crng.generation to vDSO and adds getrandom() to the vDSO. Based on Jason A. Donenfeld patch [1] "[PATCH v14 6/7] random: introduce generic vDSO getrandom() implementation", but deal only with GRND_TIMESTAMP in vDSO: generating random stream is left to the getrandom() syscall. [1] https://lore.kernel.org/all/20230101162910.710293-7-Jason@zx2c4.com/ Link: https://lore.kernel.org/all/cover.1673539719.git.ydroneaud@opteya.com/ Signed-off-by: Yann Droneaud --- MAINTAINERS | 1 + drivers/char/random.c | 6 +++++ include/vdso/datapage.h | 9 ++++++++ lib/vdso/Kconfig | 5 ++++ lib/vdso/getrandom.c | 51 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 lib/vdso/getrandom.c diff --git a/MAINTAINERS b/MAINTAINERS index 7f86d02cb427..20e1fabcb2e9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17521,6 +17521,7 @@ T: git https://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git S: Maintained F: drivers/char/random.c F: drivers/virt/vmgenid.c +F: lib/vdso/getrandom.c RAPIDIO SUBSYSTEM M: Matt Porter diff --git a/drivers/char/random.c b/drivers/char/random.c index 9e2a37e432c0..a60f50c95ab1 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -56,6 +56,9 @@ #include #include #include +#ifdef CONFIG_VDSO_GETRANDOM +#include +#endif #include #include #include @@ -271,6 +274,9 @@ static void crng_reseed(struct work_struct *work) if (next_gen == ULONG_MAX) ++next_gen; WRITE_ONCE(base_crng.generation, next_gen); +#ifdef CONFIG_VDSO_GETRANDOM + smp_store_release(&_vdso_rng_data.generation, next_gen); +#endif if (!static_branch_likely(&crng_is_ready)) crng_init = CRNG_READY; spin_unlock_irqrestore(&base_crng.lock, flags); diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h index 73eb622e7663..7ae8e7ffe3ba 100644 --- a/include/vdso/datapage.h +++ b/include/vdso/datapage.h @@ -109,6 +109,14 @@ struct vdso_data { struct arch_vdso_data arch_data; }; +/** + * struct vdso_rng_data - vdso RNG state information + * @generation: counter representing the number of RNG reseeds + */ +struct vdso_rng_data { + u64 generation; +}; + /* * We use the hidden visibility to prevent the compiler from generating a GOT * relocation. Not only is going through a GOT useless (the entry couldn't and @@ -120,6 +128,7 @@ struct vdso_data { */ extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden"))); extern struct vdso_data _timens_data[CS_BASES] __attribute__((visibility("hidden"))); +extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden"))); /* * The generic vDSO implementation requires that gettimeofday.h diff --git a/lib/vdso/Kconfig b/lib/vdso/Kconfig index d883ac299508..3b394fa83f65 100644 --- a/lib/vdso/Kconfig +++ b/lib/vdso/Kconfig @@ -31,3 +31,8 @@ config GENERIC_VDSO_TIME_NS VDSO endif + +config VDSO_GETRANDOM + bool + help + Selected by architectures that support vDSO getrandom(). diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c new file mode 100644 index 000000000000..827351a87002 --- /dev/null +++ b/lib/vdso/getrandom.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Jason A. Donenfeld . All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include + +/** + * __cvdso_getrandom_data - Generic vDSO implementation of getrandom() syscall. + * @rng_info: Describes state of kernel RNG, memory shared with kernel. + * @buffer: Input/Output buffer. + * @len: Size of @buffer in bytes. + * @flags: Zero or more GRND_* flags. + */ +static __always_inline ssize_t +__cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_t len, + unsigned int flags) +{ + if (flags != GRND_TIMESTAMP) + goto fallback; + + if (unlikely(!buffer)) + goto fallback; + + /* want aligned access */ + if (unlikely(!IS_ALIGNED((uintptr_t)buffer, __alignof__(u64)))) + goto fallback; + + if (unlikely(len != sizeof(u64))) + goto fallback; + + if (!get_random_timestamp_update((u64 *)buffer, + READ_ONCE(rng_info->generation))) + return 0; + + return sizeof(u64); + +fallback: + return getrandom_syscall(buffer, len, flags); +} + +static __always_inline ssize_t +__cvdso_getrandom(void *buffer, size_t len, unsigned int flags) +{ + return __cvdso_getrandom_data(__arch_get_vdso_rng_data(), buffer, len, flags); +} -- 2.37.2