public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Ard Biesheuvel" <ard.biesheuvel@linaro.org>
To: "Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: edk2-devel-groups-io <devel@edk2.groups.io>,
	"Wang, Jian J" <jian.j.wang@intel.com>,
	 "Yao, Jiewen" <jiewen.yao@intel.com>,
	"Zhang, Chao B" <chao.b.zhang@intel.com>,
	 "Gao, Liming" <liming.gao@intel.com>,
	"Ni, Ray" <ray.ni@intel.com>
Subject: Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
Date: Fri, 15 Nov 2019 17:35:09 +0000	[thread overview]
Message-ID: <CAKv+Gu8bLcpefG8C=5zCcM4vJsB6HcBXzNabtr4M-UNKQUErXw@mail.gmail.com> (raw)
In-Reply-To: <E92EE9817A31E24EB0585FDF735412F5B9E1DADA@ORSMSX113.amr.corp.intel.com>

On Fri, 15 Nov 2019 at 17:21, Kinney, Michael D
<michael.d.kinney@intel.com> wrote:
>
> Hi Ard,
>
> What would you recommend as way to provide these different
> types of services?  Some more new lib classes and instances?
>

Basically, yes.

RngLib could be backed by RDRAND, or by a fully generic DRBG
implementation which depends on EntropySourceLib.

EntropySourceLib could be backed by RDSEED, by another arch-specific
method, or [assuming we can prove it works] a generic jitter entropy
library.

BlockEncryptionIvLib could be implemented using a counter and a CRC
library, or backed by RngLib, depending on the execution context.


For DXE phase, I think it would actually make sense to have a single
driver consuming EntropySourceLib and implementing the DRBG, and then
expose that via a EDK2 specific protocol that is consumed by
DxeRngLib.

For the x86 implementation of EFI_RNG_PROTOCOL, which currently has
some dreadful code to harvest entropy from RDRAND, we could actually
instantiate in different ways (and expose varying subsets of the
GUIDed DRBG flavours) depending on whether it has a working RngLib
only, or has a working EntropySourceLib as well.






> > -----Original Message-----
> > From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Sent: Friday, November 15, 2019 5:29 AM
> > To: edk2-devel-groups-io <devel@edk2.groups.io>; Wang,
> > Jian J <jian.j.wang@intel.com>
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>;
> > Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> > <chao.b.zhang@intel.com>; Gao, Liming
> > <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> > Subject: Re: [edk2-devel] [PATCH 05/11]
> > SecurityPkg/RngLibRdSeed: add an instance of RngLib to
> > make use rdseed
> >
> > On Thu, 14 Nov 2019 at 04:39, Wang, Jian J
> > <jian.j.wang@intel.com> wrote:
> > >
> > > Mike,
> > >
> > > I figured that rdseed is only needed in cases
> > demanding highest
> > > entropy, like seeding other pseudo-RNG. It's not for
> > general purpose randomness.
> > > Then I put it in SecurityPkg. But I'm ok to put it
> > into MdePkg. I have
> > > no strong opinion for this.
> > >
> >
> > I think it is a bad idea to use the same library
> > abstraction [RngLib] for exposing
> > a) entropy sources used for seeding deterministic
> > random number generators
> > b) deterministic random number generators themselves
> > c) low entropy pseudo-RNGs based on timestamp counters,
> > etc
> >
> > given that the use cases don't usually overlap. I.e.,
> > only a DRBG implementation requires a), and exports
> > RngLib itself based on that.
> > Use cases that can tolerate c) [like IV generators for
> > block encryption] are typically disjoint from ones that
> > require b) [for key generation]. The idea that you can
> > use RngLib for all of them, and plug arbitrary
> > instantiations of it into each is misguided IMHO.
> >
> >
> >
> > > > -----Original Message-----
> > > > From: Kinney, Michael D
> > <michael.d.kinney@intel.com>
> > > > Sent: Thursday, November 14, 2019 12:25 PM
> > > > To: devel@edk2.groups.io; Wang, Jian J
> > <jian.j.wang@intel.com>;
> > > > Kinney, Michael D <michael.d.kinney@intel.com>
> > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao
> > B
> > > > <chao.b.zhang@intel.com>; Gao, Liming
> > <liming.gao@intel.com>; Ni,
> > > > Ray <ray.ni@intel.com>
> > > > Subject: RE: [edk2-devel] [PATCH 05/11]
> > SecurityPkg/RngLibRdSeed:
> > > > add an instance of RngLib to make use rdseed
> > > >
> > > > Jian,
> > > >
> > > > Why is this lib instance in the SecurityPkg?  It
> > only depends on the
> > > > MdePkg.  Can't non security feature related modules
> > that want to a
> > > > random number use this lib without using the
> > SecurityPkg?  Could
> > > > this lib instance be added to MdePkg?
> > > >
> > > > Thanks,
> > > >
> > > > Mike
> > > >
> > > > > -----Original Message-----
> > > > > From: devel@edk2.groups.io <devel@edk2.groups.io>
> > On Behalf Of
> > > > > Wang, Jian J
> > > > > Sent: Wednesday, November 13, 2019 6:18 PM
> > > > > To: devel@edk2.groups.io
> > > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang,
> > Chao B
> > > > > <chao.b.zhang@intel.com>; Kinney, Michael D
> > > > > <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>;
> > > > > Ni, Ray <ray.ni@intel.com>
> > > > > Subject: [edk2-devel] [PATCH 05/11]
> > > > > SecurityPkg/RngLibRdSeed: add an instance of
> > RngLib to make use
> > > > > rdseed
> > > > >
> > > > > This version of RngLib makes use of AsmRdSeed to
> > get
> > > > > non-deterministic random number, which can be
> > used for seeding
> > > > > other software DRNG like rand interface in
> > openssl. It can be used
> > > > > only on IA32/X64 processors which supports rdseed
> > instruction.
> > > > >
> > > > > Ref:
> > > > >
> > https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > > Cc: Liming Gao <liming.gao@intel.com>
> > > > > Cc: Ray Ni <ray.ni@intel.com>
> > > > > Signed-off-by: Jian J Wang
> > <jian.j.wang@intel.com>
> > > > > ---
> > > > >  .../RngLibRdSeed/RngLibRdSeed.inf             |
> > 37
> > > > > ++++
> > > > >  .../RngLibRdSeed/RngLibRdSeed.uni             |
> > 18 ++
> > > > >  .../RngLibRdSeed/RngRdSeed.c                  |
> > 189
> > > > > ++++++++++++++++++
> > > > >  3 files changed, 244 insertions(+)  create mode
> > 100644
> > > > >
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > > > Seed.inf
> > > > >  create mode 100644
> > > > >
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > > > Seed.uni
> > > > >  create mode 100644
> > > > >
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> > > > > d.c
> > > > >
> > > > > diff --git
> > > > >
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.inf
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.inf
> > > > > new file mode 100644
> > > > > index 0000000000..8162408775
> > > > > --- /dev/null
> > > > > +++
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.inf
> > > > > @@ -0,0 +1,37 @@
> > > > > +## @file
> > > > > +#  Instance of RNG (Random Number Generator)
> > Library.
> > > > > +#
> > > > > +#  Rng RdSeed Library that uses CPU RdSeed
> > instruction
> > > > > access to
> > > > > +provide #  non-deterministic random number which
> > can
> > > > > be used as seed
> > > > > +for other #  software deterministic RNGs.
> > > > > +#
> > > > > +#  Copyright (c) 2019, Intel Corporation. All
> > rights
> > > > > reserved.<BR> # #
> > > > > +SPDX-License-Identifier: BSD-2-Clause-Patent # #
> > ##
> > > > > +
> > > > > +[Defines]
> > > > > +  INF_VERSION                    = 0x00010029
> > > > > +  BASE_NAME                      = RngLibRdSeed
> > > > > +  MODULE_UNI_FILE                =
> > RngLibRdSeed.uni
> > > > > +  FILE_GUID                      = 8B613B2E-
> > B944-40F9-
> > > > > B979-1B60D7CAA73C
> > > > > +  MODULE_TYPE                    = BASE
> > > > > +  VERSION_STRING                 = 1.0
> > > > > +  LIBRARY_CLASS                  = RngLib
> > > > > +  CONSTRUCTOR                    =
> > > > > RngLibRdSeedConstructor
> > > > > +
> > > > > +#
> > > > > +#  VALID_ARCHITECTURES           = IA32 X64
> > > > > +#
> > > > > +
> > > > > +[Sources.Ia32, Sources.X64]
> > > > > +  RngRdSeed.c
> > > > > +
> > > > > +[Packages]
> > > > > +  MdePkg/MdePkg.dec
> > > > > +
> > > > > +[LibraryClasses]
> > > > > +  BaseLib
> > > > > +  DebugLib
> > > > > diff --git
> > > > >
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.uni
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.uni
> > > > > new file mode 100644
> > > > > index 0000000000..051a3019bc
> > > > > --- /dev/null
> > > > > +++
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.uni
> > > > > @@ -0,0 +1,18 @@
> > > > > +// /** @file
> > > > > +// Instance of RNG (Random Number Generator)
> > Library.
> > > > > +//
> > > > > +// Rng RdSeed Library that uses CPU RdSeed
> > instruction
> > > > > access to
> > > > > +provide // non-deterministic random number which
> > can
> > > > > be used as seed
> > > > > +for other // software deterministic RNGs.
> > > > > +//
> > > > > +// Copyright (c) 2019, Intel Corporation. All
> > rights
> > > > > reserved.<BR> //
> > > > > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > // //
> > > > > **/
> > > > > +
> > > > > +
> > > > > +#string STR_MODULE_ABSTRACT
> > #language en-
> > > > > US "Instance of RNG Library"
> > > > > +
> > > > > +#string STR_MODULE_DESCRIPTION
> > #language en-
> > > > > US "RngRdSeed Library that uses CPU RdSeed
> > instruction access to
> > > > > provide non-deterministic random numbers."
> > > > > +
> > > > > diff --git
> > > > >
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > eed.c
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > eed.c
> > > > > new file mode 100644
> > > > > index 0000000000..0036faa050
> > > > > --- /dev/null
> > > > > +++
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > eed.c
> > > > > @@ -0,0 +1,189 @@
> > > > > +/** @file
> > > > > +  Random number generator services that uses
> > RdSeed
> > > > > instruction access
> > > > > +  to provide non-deterministic random numbers,
> > which
> > > > > are usually used
> > > > > +  for seeding other pseudo-random number
> > generators.
> > > > > +
> > > > > +Copyright (c) 2019, Intel Corporation. All
> > rights
> > > > > reserved.<BR>
> > > > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > > > +
> > > > > +**/
> > > > > +
> > > > > +#include <Library/BaseLib.h>
> > > > > +#include <Library/DebugLib.h>
> > > > > +#include <Library/RngLib.h>
> > > > > +
> > > > > +//
> > > > > +// Bit mask used to determine if RdSeed
> > instruction is
> > > > > supported.
> > > > > +//
> > > > > +#define RDSEED_MASK                  BIT18
> > > > > +
> > > > > +//
> > > > > +// Limited retry number when valid random data
> > is
> > > > > returned.
> > > > > +// It varies between 1 and 100 according to
> > "Intel(R)
> > > > > DRGN Software
> > > > > +Implementation // Guide". Let's use the same
> > value as
> > > > > RDRAND in BaseRngLib.
> > > > > +//
> > > > > +#define RDSEED_RETRY_LIMIT           10
> > > > > +
> > > > > +/**
> > > > > +  The constructor function checks whether or not
> > > > > RDSEED instruction is
> > > > > +supported
> > > > > +  by the host hardware.
> > > > > +
> > > > > +  The constructor function checks whether or not
> > > > > RDSEED instruction is supported.
> > > > > +  It will ASSERT() if RDSEED instruction is not
> > > > > supported.
> > > > > +
> > > > > +  @retval RETURN_SUCCESS      The processor
> > supports
> > > > > RDSEED instruction.
> > > > > +  @retval RETURN_UNSUPPORTED  RDSEED instruction
> > is
> > > > > not supported.
> > > > > +
> > > > > +**/
> > > > > +RETURN_STATUS
> > > > > +EFIAPI
> > > > > +RngLibRdSeedConstructor (
> > > > > +  VOID
> > > > > +  )
> > > > > +{
> > > > > +  UINT32  RegEbx;
> > > > > +
> > > > > +  //
> > > > > +  // Determine RDSEED support by examining bit
> > 18 of
> > > > > the EBX register
> > > > > + returned by  // CPUID(EAX=7, ECX=0). BIT18 of
> > EBX
> > > > > indicates that
> > > > > + processor support RDSEED  // instruction.
> > > > > +  //
> > > > > +  AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);
> > if
> > > > > ((RegEbx &
> > > > > + RDSEED_MASK) != RDSEED_MASK) {
> > > > > +    ASSERT ((RegEbx & RDSEED_MASK) ==
> > RDSEED_MASK);
> > > > > +    return RETURN_UNSUPPORTED;
> > > > > +  }
> > > > > +
> > > > > +  return RETURN_SUCCESS;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > +  Generates a 16-bit random number.
> > > > > +
> > > > > +  if Rand is NULL, then ASSERT().
> > > > > +
> > > > > +  @param[out] Rand     Buffer pointer to store
> > the 16-
> > > > > bit random value.
> > > > > +
> > > > > +  @retval TRUE         Random number generated
> > > > > successfully.
> > > > > +  @retval FALSE        Failed to generate the
> > random
> > > > > number.
> > > > > +
> > > > > +**/
> > > > > +BOOLEAN
> > > > > +EFIAPI
> > > > > +GetRandomNumber16 (
> > > > > +  OUT     UINT16                    *Rand
> > > > > +  )
> > > > > +{
> > > > > +  UINT32  Index;
> > > > > +
> > > > > +  ASSERT (Rand != NULL);
> > > > > +
> > > > > +  //
> > > > > +  // A loop to fetch a 16 bit random value with
> > a
> > > > > retry count limit.
> > > > > +  //
> > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > Index++)
> > > > > {
> > > > > +    if (AsmRdSeed16 (Rand)) {
> > > > > +      return TRUE;
> > > > > +    }
> > > > > +  }
> > > > > +
> > > > > +  return FALSE;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > +  Generates a 32-bit random number.
> > > > > +
> > > > > +  if Rand is NULL, then ASSERT().
> > > > > +
> > > > > +  @param[out] Rand     Buffer pointer to store
> > the 32-
> > > > > bit random value.
> > > > > +
> > > > > +  @retval TRUE         Random number generated
> > > > > successfully.
> > > > > +  @retval FALSE        Failed to generate the
> > random
> > > > > number.
> > > > > +
> > > > > +**/
> > > > > +BOOLEAN
> > > > > +EFIAPI
> > > > > +GetRandomNumber32 (
> > > > > +  OUT     UINT32                    *Rand
> > > > > +  )
> > > > > +{
> > > > > +  UINT32  Index;
> > > > > +
> > > > > +  ASSERT (Rand != NULL);
> > > > > +
> > > > > +  //
> > > > > +  // A loop to fetch a 32 bit random value with
> > a
> > > > > retry count limit.
> > > > > +  //
> > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > Index++)
> > > > > {
> > > > > +    if (AsmRdSeed32 (Rand)) {
> > > > > +      return TRUE;
> > > > > +    }
> > > > > +  }
> > > > > +
> > > > > +  return FALSE;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > +  Generates a 64-bit random number.
> > > > > +
> > > > > +  if Rand is NULL, then ASSERT().
> > > > > +
> > > > > +  @param[out] Rand     Buffer pointer to store
> > the 64-
> > > > > bit random value.
> > > > > +
> > > > > +  @retval TRUE         Random number generated
> > > > > successfully.
> > > > > +  @retval FALSE        Failed to generate the
> > random
> > > > > number.
> > > > > +
> > > > > +**/
> > > > > +BOOLEAN
> > > > > +EFIAPI
> > > > > +GetRandomNumber64 (
> > > > > +  OUT     UINT64                    *Rand
> > > > > +  )
> > > > > +{
> > > > > +  UINT32  Index;
> > > > > +
> > > > > +  ASSERT (Rand != NULL);
> > > > > +
> > > > > +  //
> > > > > +  // A loop to fetch a 64 bit random value with
> > a
> > > > > retry count limit.
> > > > > +  //
> > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > Index++)
> > > > > {
> > > > > +    if (AsmRdSeed64 (Rand)) {
> > > > > +      return TRUE;
> > > > > +    }
> > > > > +  }
> > > > > +
> > > > > +  return FALSE;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > +  Generates a 128-bit random number.
> > > > > +
> > > > > +  if Rand is NULL, then ASSERT().
> > > > > +
> > > > > +  @param[out] Rand     Buffer pointer to store
> > the
> > > > > 128-bit random value.
> > > > > +
> > > > > +  @retval TRUE         Random number generated
> > > > > successfully.
> > > > > +  @retval FALSE        Failed to generate the
> > random
> > > > > number.
> > > > > +
> > > > > +**/
> > > > > +BOOLEAN
> > > > > +EFIAPI
> > > > > +GetRandomNumber128 (
> > > > > +  OUT     UINT64                    *Rand
> > > > > +  )
> > > > > +{
> > > > > +  ASSERT (Rand != NULL);
> > > > > +
> > > > > +  //
> > > > > +  // Read first 64 bits
> > > > > +  //
> > > > > +  if (!GetRandomNumber64 (Rand)) {
> > > > > +    return FALSE;
> > > > > +  }
> > > > > +
> > > > > +  //
> > > > > +  // Read second 64 bits
> > > > > +  //
> > > > > +  return GetRandomNumber64 (++Rand); }
> > > > > --
> > > > > 2.17.1.windows.2
> > > > >
> > > > >
> > > > >
> > >
> > >
> > > 
> > >

  reply	other threads:[~2019-11-15 17:35 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
2019-11-14  2:17 ` [PATCH 01/11] NetworkPkg/NetworkPkg.dsc: specify RngLib instance for build Wang, Jian J
2019-11-14  2:17 ` [PATCH 02/11] SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib instances Wang, Jian J
2019-11-14  2:17 ` [PATCH 03/11] FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib instances in dsc files Wang, Jian J
2019-11-14  2:17 ` [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction Wang, Jian J
2019-11-14  4:17   ` [edk2-devel] " Michael D Kinney
2019-11-14  4:40     ` Wang, Jian J
2019-11-14  2:17 ` [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed Wang, Jian J
2019-11-14  4:24   ` [edk2-devel] " Michael D Kinney
2019-11-14  4:38     ` Wang, Jian J
2019-11-15 13:28       ` Ard Biesheuvel
2019-11-15 17:21         ` Michael D Kinney
2019-11-15 17:35           ` Ard Biesheuvel [this message]
2019-11-16  2:17             ` Wang, Jian J
2019-11-15 22:19         ` Laszlo Ersek
2019-11-14  2:17 ` [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib Wang, Jian J
2019-11-14 11:15   ` [edk2-devel] " Laszlo Ersek
2019-11-14 14:52     ` Wang, Jian J
2019-11-14  2:17 ` [PATCH 07/11] SecurityPkg/SecurityPkg.dsc: add new RngLib instances for build Wang, Jian J
2019-11-14  2:17 ` [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files Wang, Jian J
2019-11-14 11:07   ` [edk2-devel] " Laszlo Ersek
2019-11-14 14:40     ` Wang, Jian J
2019-11-14 14:51       ` Laszlo Ersek
2019-11-14 14:55         ` Wang, Jian J
2019-11-14  2:17 ` [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: " Wang, Jian J
2019-11-14  7:41   ` [edk2-devel] " Ard Biesheuvel
2019-11-14  8:03     ` Wang, Jian J
2019-11-14  8:14       ` Ard Biesheuvel
2019-11-14  8:31         ` Wang, Jian J
2019-11-14 10:36   ` Laszlo Ersek
2019-11-14 14:26     ` Wang, Jian J
2019-11-14  2:17 ` [PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy Wang, Jian J
2019-11-14  7:42   ` Ard Biesheuvel
2019-11-14  2:17 ` [PATCH 11/11] FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib instance Wang, Jian J
2019-11-14  4:21 ` [edk2-devel] [PATCH 00/11] Use proper entropy sources Michael D Kinney
2019-11-14  5:15   ` Wang, Jian J

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAKv+Gu8bLcpefG8C=5zCcM4vJsB6HcBXzNabtr4M-UNKQUErXw@mail.gmail.com' \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox