Forum | Documentation | Website | Blog

Skip to content
Snippets Groups Projects
  1. Feb 11, 2022
  2. Feb 04, 2022
  3. Jan 30, 2022
  4. Jan 28, 2022
  5. Jan 18, 2022
  6. Jan 08, 2022
    • Andrew Zaborowski's avatar
      keys: X.509 public key issuer lookup without AKID · 7d30198e
      Andrew Zaborowski authored
      There are non-root X.509 v3 certificates in use out there that contain
      no Authority Key Identifier extension (RFC5280 section 4.2.1.1).  For
      trust verification purposes the kernel asymmetric key type keeps two
      struct asymmetric_key_id instances that the key can be looked up by,
      and another two to look up the key's issuer.  The x509 public key type
      and the PKCS7 type generate them from the SKID and AKID extensions in
      the certificate.  In effect current code has no way to look up the
      issuer certificate for verification without the AKID.
      
      To remedy this, add a third asymmetric_key_id blob to the arrays in
      both asymmetric_key_id's (for certficate subject) and in the
      public_keys_signature's auth_ids (for issuer lookup), using just raw
      subject and issuer DNs from the certificate.  Adapt
      asymmetric_key_ids() and its callers to use the third ID for lookups
      when none of the other two are available.  Attempt to keep the logic
      intact when they are, to minimise behaviour changes.  Adapt the
      restrict functions' NULL-checks to include that ID too.  Do not modify
      the lookup logic in pkcs7_verify.c, the AKID extensions are still
      required there.
      
      Internally use a new "dn:" prefix to the search specifier string
      generated for the key lookup in find_asymmetric_key().  This tells
      asymmetric_key_match_preparse to only match the data against the raw
      DN in the third ID and shouldn't conflict with search specifiers
      already in use.
      
      In effect implement what (2) in the struct asymmetric_key_id comment
      (include/keys/asymmetric-type.h) is probably talking about already, so
      do not modify that comment.  It is also how "openssl verify" looks up
      issuer certificates without the AKID available.  Lookups by the raw
      DN are unambiguous only provided that the CAs respect the condition in
      RFC5280 4.2.1.1 that the AKID may only be omitted if the CA uses
      a single signing key.
      
      The following is an example of two things that this change enables.
      A self-signed ceritficate is generated following the example from
      https://letsencrypt.org/docs/certificates-for-localhost/
      
      , and can be
      looked up by an identifier and verified against itself by linking to a
      restricted keyring -- both things not possible before due to the missing
      AKID extension:
      
      $ openssl req -x509 -out localhost.crt -outform DER -keyout localhost.key \
        -newkey rsa:2048 -nodes -sha256 \
        -subj '/CN=localhost' -extensions EXT -config <( \
         echo -e "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\n" \
                "subjectAltName=DNS:localhost\nkeyUsage=digitalSignature\n" \
      	  "extendedKeyUsage=serverAuth")
      $ keyring=`keyctl newring test @u`
      $ trusted=`keyctl padd asymmetric trusted $keyring < localhost.crt`; \
        echo $trusted
      39726322
      $ keyctl search $keyring asymmetric dn:3112301006035504030c096c6f63616c686f7374
      39726322
      $ keyctl restrict_keyring $keyring asymmetric key_or_keyring:$trusted
      $ keyctl padd asymmetric verified $keyring < localhost.crt
      
      Signed-off-by: default avatarAndrew Zaborowski <andrew.zaborowski@intel.com>
      Reviewed-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
      Acked-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
      Acked-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
      7d30198e
  7. Jan 06, 2022
  8. Dec 31, 2021
  9. Dec 13, 2021
  10. Dec 11, 2021
  11. Nov 26, 2021
    • Stephan Müller's avatar
      crypto: des - disallow des3 in FIPS mode · 330507fb
      Stephan Müller authored
      
      On Dec 31 2023 NIST sunsets TDES for FIPS use. To prevent FIPS
      validations to be completed in the future to be affected by the TDES
      sunsetting, disallow TDES already now. Otherwise a FIPS validation would
      need to be "touched again" end 2023 to handle TDES accordingly.
      
      Signed-off-by: default avatarStephan Mueller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      330507fb
    • Stephan Müller's avatar
      crypto: dh - limit key size to 2048 in FIPS mode · 1e146c39
      Stephan Müller authored
      
      FIPS disallows DH with keys < 2048 bits. Thus, the kernel should
      consider the enforcement of this limit.
      
      Signed-off-by: default avatarStephan Mueller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      1e146c39
    • Stephan Müller's avatar
      crypto: rsa - limit key size to 2048 in FIPS mode · 1ce1bacc
      Stephan Müller authored
      
      FIPS disallows RSA with keys < 2048 bits. Thus, the kernel should
      consider the enforcement of this limit.
      
      Signed-off-by: default avatarStephan Mueller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      1ce1bacc
    • Stephan Müller's avatar
      crypto: jitter - consider 32 LSB for APT · 552d03a2
      Stephan Müller authored
      
      The APT compares the current time stamp with a pre-set value. The
      current code only considered the 4 LSB only. Yet, after reviews by
      mathematicians of the user space Jitter RNG version >= 3.1.0, it was
      concluded that the APT can be calculated on the 32 LSB of the time
      delta. Thi change is applied to the kernel.
      
      This fixes a bug where an AMD EPYC fails this test as its RDTSC value
      contains zeros in the LSB. The most appropriate fix would have been to
      apply a GCD calculation and divide the time stamp by the GCD. Yet, this
      is a significant code change that will be considered for a future
      update. Note, tests showed that constantly the GCD always was 32 on
      these systems, i.e. the 5 LSB were always zero (thus failing the APT
      since it only considered the 4 LSB for its calculation).
      
      Signed-off-by: default avatarStephan Mueller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      552d03a2
    • Stephan Müller's avatar
      crypto: kdf - add SP800-108 counter key derivation function · 026a733e
      Stephan Müller authored
      
      SP800-108 defines three KDFs - this patch provides the counter KDF
      implementation.
      
      The KDF is implemented as a service function where the caller has to
      maintain the hash / HMAC state. Apart from this hash/HMAC state, no
      additional state is required to be maintained by either the caller or
      the KDF implementation.
      
      The key for the KDF is set with the crypto_kdf108_setkey function which
      is intended to be invoked before the caller requests a key derivation
      operation via crypto_kdf108_ctr_generate.
      
      SP800-108 allows the use of either a HMAC or a hash as crypto primitive
      for the KDF. When a HMAC primtive is intended to be used,
      crypto_kdf108_setkey must be used to set the HMAC key. Otherwise, for a
      hash crypto primitve crypto_kdf108_ctr_generate can be used immediately
      after allocating the hash handle.
      
      Signed-off-by: default avatarStephan Mueller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      026a733e
    • Nicolai Stange's avatar
      crypto: drbg - reseed 'nopr' drbgs periodically from get_random_bytes() · 8ea5ee00
      Nicolai Stange authored
      
      In contrast to the fully prediction resistant 'pr' DRBGs, the 'nopr'
      variants get seeded once at boot and reseeded only rarely thereafter,
      namely only after 2^20 requests have been served each. AFAICT, this
      reseeding based on the number of requests served is primarily motivated
      by information theoretic considerations, c.f. NIST SP800-90Ar1,
      sec. 8.6.8 ("Reseeding").
      
      However, given the relatively large seed lifetime of 2^20 requests, the
      'nopr' DRBGs can hardly be considered to provide any prediction resistance
      whatsoever, i.e. to protect against threats like side channel leaks of the
      internal DRBG state (think e.g. leaked VM snapshots). This is expected and
      completely in line with the 'nopr' naming, but as e.g. the
      "drbg_nopr_hmac_sha512" implementation is potentially being used for
      providing the "stdrng" and thus, the crypto_default_rng serving the
      in-kernel crypto, it would certainly be desirable to achieve at least the
      same level of prediction resistance as get_random_bytes() does.
      
      Note that the chacha20 rngs underlying get_random_bytes() get reseeded
      every CRNG_RESEED_INTERVAL == 5min: the secondary, per-NUMA node rngs from
      the primary one and the primary rng in turn from the entropy pool, provided
      sufficient entropy is available.
      
      The 'nopr' DRBGs do draw randomness from get_random_bytes() for their
      initial seed already, so making them to reseed themselves periodically from
      get_random_bytes() in order to let them benefit from the latter's
      prediction resistance is not such a big change conceptually.
      
      In principle, it would have been also possible to make the 'nopr' DRBGs to
      periodically invoke a full reseeding operation, i.e. to also consider the
      jitterentropy source (if enabled) in addition to get_random_bytes() for the
      seed value. However, get_random_bytes() is relatively lightweight as
      compared to the jitterentropy generation process and thus, even though the
      'nopr' reseeding is supposed to get invoked infrequently, it's IMO still
      worthwhile to avoid occasional latency spikes for drbg_generate() and
      stick to get_random_bytes() only. As an additional remark, note that
      drawing randomness from the non-SP800-90B-conforming get_random_bytes()
      only won't adversely affect SP800-90A conformance either: the very same is
      being done during boot via drbg_seed_from_random() already once
      rng_is_initialized() flips to true and it follows that if the DRBG
      implementation does conform to SP800-90A now, it will continue to do so.
      
      Make the 'nopr' DRBGs to reseed themselves periodically from
      get_random_bytes() every CRNG_RESEED_INTERVAL == 5min.
      
      More specifically, introduce a new member ->last_seed_time to struct
      drbg_state for recording in units of jiffies when the last seeding
      operation had taken place. Make __drbg_seed() maintain it and let
      drbg_generate() invoke a reseed from get_random_bytes() via
      drbg_seed_from_random() if more than 5min have passed by since the last
      seeding operation. Be careful to not to reseed if in testing mode though,
      or otherwise the drbg related tests in crypto/testmgr.c would fail to
      reproduce the expected output.
      
      In order to keep the formatting clean in drbg_generate() wrap the logic
      for deciding whether or not a reseed is due in a new helper,
      drbg_nopr_reseed_interval_elapsed().
      
      Signed-off-by: default avatarNicolai Stange <nstange@suse.de>
      Reviewed-by: default avatarStephan Müller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      8ea5ee00
    • Nicolai Stange's avatar
      crypto: drbg - make drbg_prepare_hrng() handle jent instantiation errors · 559edd47
      Nicolai Stange authored
      
      Now that drbg_prepare_hrng() doesn't do anything but to instantiate a
      jitterentropy crypto_rng instance, it looks a little odd to have the
      related error handling at its only caller, drbg_instantiate().
      
      Move the handling of jitterentropy allocation failures from
      drbg_instantiate() close to the allocation itself in drbg_prepare_hrng().
      
      There is no change in behaviour.
      
      Signed-off-by: default avatarNicolai Stange <nstange@suse.de>
      Reviewed-by: default avatarStephan Müller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      559edd47
    • Nicolai Stange's avatar
      crypto: drbg - make reseeding from get_random_bytes() synchronous · 074bcd40
      Nicolai Stange authored
      get_random_bytes() usually hasn't full entropy available by the time DRBG
      instances are first getting seeded from it during boot. Thus, the DRBG
      implementation registers random_ready_callbacks which would in turn
      schedule some work for reseeding the DRBGs once get_random_bytes() has
      sufficient entropy available.
      
      For reference, the relevant history around handling DRBG (re)seeding in
      the context of a not yet fully seeded get_random_bytes() is:
      
        commit 16b369a9 ("random: Blocking API for accessing
                              nonblocking_pool")
        commit 4c787990 ("crypto: drbg - add async seeding operation")
      
        commit 205a525c ("random: Add callback API for random pool
                              readiness")
        commit 57225e67 ("crypto: drbg - Use callback API for random
                              readiness")
        commit c2719503 ("random: Remove kernel blocking API")
      
      However, some time later, the initialization state of get_random_bytes()
      has been made queryable via rng_is_initialized() introduced with commit
      9a47249d
      
       ("random: Make crng state queryable"). This primitive now
      allows for streamlining the DRBG reseeding from get_random_bytes() by
      replacing that aforementioned asynchronous work scheduling from
      random_ready_callbacks with some simpler, synchronous code in
      drbg_generate() next to the related logic already present therein. Apart
      from improving overall code readability, this change will also enable DRBG
      users to rely on wait_for_random_bytes() for ensuring that the initial
      seeding has completed, if desired.
      
      The previous patches already laid the grounds by making drbg_seed() to
      record at each DRBG instance whether it was being seeded at a time when
      rng_is_initialized() still had been false as indicated by
      ->seeded == DRBG_SEED_STATE_PARTIAL.
      
      All that remains to be done now is to make drbg_generate() check for this
      condition, determine whether rng_is_initialized() has flipped to true in
      the meanwhile and invoke a reseed from get_random_bytes() if so.
      
      Make this move:
      - rename the former drbg_async_seed() work handler, i.e. the one in charge
        of reseeding a DRBG instance from get_random_bytes(), to
        "drbg_seed_from_random()",
      - change its signature as appropriate, i.e. make it take a struct
        drbg_state rather than a work_struct and change its return type from
        "void" to "int" in order to allow for passing error information from
        e.g. its __drbg_seed() invocation onwards to callers,
      - make drbg_generate() invoke this drbg_seed_from_random() once it
        encounters a DRBG instance with ->seeded == DRBG_SEED_STATE_PARTIAL by
        the time rng_is_initialized() has flipped to true and
      - prune everything related to the former, random_ready_callback based
        mechanism.
      
      As drbg_seed_from_random() is now getting invoked from drbg_generate() with
      the ->drbg_mutex being held, it must not attempt to recursively grab it
      once again. Remove the corresponding mutex operations from what is now
      drbg_seed_from_random(). Furthermore, as drbg_seed_from_random() can now
      report errors directly to its caller, there's no need for it to temporarily
      switch the DRBG's ->seeded state to DRBG_SEED_STATE_UNSEEDED so that a
      failure of the subsequently invoked __drbg_seed() will get signaled to
      drbg_generate(). Don't do it then.
      
      Signed-off-by: default avatarNicolai Stange <nstange@suse.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      074bcd40
    • Nicolai Stange's avatar
      crypto: drbg - move dynamic ->reseed_threshold adjustments to __drbg_seed() · 262d83a4
      Nicolai Stange authored
      Since commit 42ea507f
      
       ("crypto: drbg - reseed often if seedsource is
      degraded"), the maximum seed lifetime represented by ->reseed_threshold
      gets temporarily lowered if the get_random_bytes() source cannot provide
      sufficient entropy yet, as is common during boot, and restored back to
      the original value again once that has changed.
      
      More specifically, if the add_random_ready_callback() invoked from
      drbg_prepare_hrng() in the course of DRBG instantiation does not return
      -EALREADY, that is, if get_random_bytes() has not been fully initialized
      at this point yet, drbg_prepare_hrng() will lower ->reseed_threshold
      to a value of 50. The drbg_async_seed() scheduled from said
      random_ready_callback will eventually restore the original value.
      
      A future patch will replace the random_ready_callback based notification
      mechanism and thus, there will be no add_random_ready_callback() return
      value anymore which could get compared to -EALREADY.
      
      However, there's __drbg_seed() which gets invoked in the course of both,
      the DRBG instantiation as well as the eventual reseeding from
      get_random_bytes() in aforementioned drbg_async_seed(), if any. Moreover,
      it knows about the get_random_bytes() initialization state by the time the
      seed data had been obtained from it: the new_seed_state argument introduced
      with the previous patch would get set to DRBG_SEED_STATE_PARTIAL in case
      get_random_bytes() had not been fully initialized yet and to
      DRBG_SEED_STATE_FULL otherwise. Thus, __drbg_seed() provides a convenient
      alternative for managing that ->reseed_threshold lowering and restoring at
      a central place.
      
      Move all ->reseed_threshold adjustment code from drbg_prepare_hrng() and
      drbg_async_seed() respectively to __drbg_seed(). Make __drbg_seed()
      lower the ->reseed_threshold to 50 in case its new_seed_state argument
      equals DRBG_SEED_STATE_PARTIAL and let it restore the original value
      otherwise.
      
      There is no change in behaviour.
      
      Signed-off-by: default avatarNicolai Stange <nstange@suse.de>
      Reviewed-by: default avatarStephan Müller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      262d83a4
    • Nicolai Stange's avatar
      crypto: drbg - track whether DRBG was seeded with !rng_is_initialized() · 2bcd2544
      Nicolai Stange authored
      
      Currently, the DRBG implementation schedules asynchronous works from
      random_ready_callbacks for reseeding the DRBG instances with output from
      get_random_bytes() once the latter has sufficient entropy available.
      
      However, as the get_random_bytes() initialization state can get queried by
      means of rng_is_initialized() now, there is no real need for this
      asynchronous reseeding logic anymore and it's better to keep things simple
      by doing it synchronously when needed instead, i.e. from drbg_generate()
      once rng_is_initialized() has flipped to true.
      
      Of course, for this to work, drbg_generate() would need some means by which
      it can tell whether or not rng_is_initialized() has flipped to true since
      the last seeding from get_random_bytes(). Or equivalently, whether or not
      the last seed from get_random_bytes() has happened when
      rng_is_initialized() was still evaluating to false.
      
      As it currently stands, enum drbg_seed_state allows for the representation
      of two different DRBG seeding states: DRBG_SEED_STATE_UNSEEDED and
      DRBG_SEED_STATE_FULL. The former makes drbg_generate() to invoke a full
      reseeding operation involving both, the rather expensive jitterentropy as
      well as the get_random_bytes() randomness sources. The DRBG_SEED_STATE_FULL
      state on the other hand implies that no reseeding at all is required for a
      !->pr DRBG variant.
      
      Introduce the new DRBG_SEED_STATE_PARTIAL state to enum drbg_seed_state for
      representing the condition that a DRBG was being seeded when
      rng_is_initialized() had still been false. In particular, this new state
      implies that
      - the given DRBG instance has been fully seeded from the jitterentropy
        source (if enabled)
      - and drbg_generate() is supposed to reseed from get_random_bytes()
        *only* once rng_is_initialized() turns to true.
      
      Up to now, the __drbg_seed() helper used to set the given DRBG instance's
      ->seeded state to constant DRBG_SEED_STATE_FULL. Introduce a new argument
      allowing for the specification of the to be written ->seeded value instead.
      Make the first of its two callers, drbg_seed(), determine the appropriate
      value based on rng_is_initialized(). The remaining caller,
      drbg_async_seed(), is known to get invoked only once rng_is_initialized()
      is true, hence let it pass constant DRBG_SEED_STATE_FULL for the new
      argument to __drbg_seed().
      
      There is no change in behaviour, except for that the pr_devel() in
      drbg_generate() would now report "unseeded" for ->pr DRBG instances which
      had last been seeded when rng_is_initialized() was still evaluating to
      false.
      
      Signed-off-by: default avatarNicolai Stange <nstange@suse.de>
      Reviewed-by: default avatarStephan Müller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      2bcd2544
    • Nicolai Stange's avatar
      crypto: drbg - prepare for more fine-grained tracking of seeding state · ce8ce31b
      Nicolai Stange authored
      
      There are two different randomness sources the DRBGs are getting seeded
      from, namely the jitterentropy source (if enabled) and get_random_bytes().
      At initial DRBG seeding time during boot, the latter might not have
      collected sufficient entropy for seeding itself yet and thus, the DRBG
      implementation schedules a reseed work from a random_ready_callback once
      that has happened. This is particularly important for the !->pr DRBG
      instances, for which (almost) no further reseeds are getting triggered
      during their lifetime.
      
      Because collecting data from the jitterentropy source is a rather expensive
      operation, the aforementioned asynchronously scheduled reseed work
      restricts itself to get_random_bytes() only. That is, it in some sense
      amends the initial DRBG seed derived from jitterentropy output at full
      (estimated) entropy with fresh randomness obtained from get_random_bytes()
      once that has been seeded with sufficient entropy itself.
      
      With the advent of rng_is_initialized(), there is no real need for doing
      the reseed operation from an asynchronously scheduled work anymore and a
      subsequent patch will make it synchronous by moving it next to related
      logic already present in drbg_generate().
      
      However, for tracking whether a full reseed including the jitterentropy
      source is required or a "partial" reseed involving only get_random_bytes()
      would be sufficient already, the boolean struct drbg_state's ->seeded
      member must become a tristate value.
      
      Prepare for this by introducing the new enum drbg_seed_state and change
      struct drbg_state's ->seeded member's type from bool to that type.
      
      For facilitating review, enum drbg_seed_state is made to only contain
      two members corresponding to the former ->seeded values of false and true
      resp. at this point: DRBG_SEED_STATE_UNSEEDED and DRBG_SEED_STATE_FULL. A
      third one for tracking the intermediate state of "seeded from jitterentropy
      only" will be introduced with a subsequent patch.
      
      There is no change in behaviour at this point.
      
      Signed-off-by: default avatarNicolai Stange <nstange@suse.de>
      Reviewed-by: default avatarStephan Müller <smueller@chronox.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      ce8ce31b
  12. Nov 19, 2021
    • Lei He's avatar
      crypto: testmgr - Fix wrong test case of RSA · a9887010
      Lei He authored
      
      According to the BER encoding rules, integer value should be encoded
      as two's complement, and if the highest bit of a positive integer
      is 1, should add a leading zero-octet.
      
      The kernel's built-in RSA algorithm cannot recognize negative numbers
      when parsing keys, so it can pass this test case.
      
      Export the key to file and run the following command to verify the
      fix result:
      
        openssl asn1parse -inform DER -in /path/to/key/file
      
      Signed-off-by: default avatarLei He <helei.sig11@bytedance.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      a9887010