Subject: [dtn] Benjamin Kaduk's Discuss on draft-ietf-dtn-bpsec-default-sc-08: (with DISCUSS and COMMENT)

From: Benjamin Kaduk via Datatracker <[email-masked]>
Date: Tue, 29 Jun 2021 19:48:13 -0700

Benjamin Kaduk has entered the following ballot position for
draft-ietf-dtn-bpsec-default-sc-08: Discuss

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-dtn-bpsec-default-sc/

----------------------------------------------------------------------
DISCUSS:
----------------------------------------------------------------------

Thank you for writing this document; I'm really glad that it will be
available to illuminate the particulars of BPsec usage and provide a
default option when running BPsec in relatively bland environments.
However, I think there are a few gaps between the current specification
and a strong/reliable default security option.

(D1) the construction for the HMAC input plaintext and GCM AAD seems to
be "malleable" at the security context layer.  That is, in order for the
cryptographic integrity protection mechanism to provide strong
guarantees for the application protocol's semantics, the mapping from
protocol parameters (e.g., "security target contents", "primary block")
to the actual byte string used as the IPPT/AAD inputs to HMAC/GMAC needs
to be an injective mapping (in the mathematical sense).  If injectivity
does not hold, then there is more than one possible application
semantics that could be perceived as valid upon successful validation of
the authentication tag at the recipient; this "malleability" across
different interpretations of the bytes covered by a given integrity tag
gives an opening by which an attacker can target the application
semantics.

The current construction seems
"malleable" because the scope flags are not protected in any way and
could be modified by an attacker, and the scope flags affect which
application protocol fields (and thus, semantics) are used to construct
the IPPT/AAD.  If the attacker modifies the messages to move those
encoded bytes from one location to another, the modified message could
still pass cryptographic verification but be interpreted with different
semantics than intended.  We do correctly note that the security context
identifier and the security context parameters of the security block are
not included in the input data, but the conclusion that "successful
verification implies that these parameters were unchanged from what the
security source has specified" does not seem entirely warranted without
further analysis that relies on the internal structure of the different
potential parts of the IPPT/AAD.

[side note: the IETF security community tends towards "always include as
much information in the MAC as you can without breaking operations",
which would naively be everything included with scope flags 0x7.  Always
including everything removes the malleability, since there are no gaps
to move around.  But I think I can come up with scenarios where this
flexibility would indeed be needed in BP operations, so my tentative
conclusion is that the simple "always MAC everything" approach will not
work here.]

Specifically, to the extent that we may have injectivity, we seem to be
relying on the specific encoding details of the different types of
information that could be used in constructing the IPPT and AAD.  Since
the IPPT/AAD is currently just the concatenation (in a particular order)
of any/all of a few pieces of data, we can only get injectivity if each
of those pieces of data is self-framing and *self-identifying* by its
encoded form.  (If we, for example, prefixed each self-framing part with
a type identifier for what followed, that would make the overall
encoding self-identifying for what is contained therein.)  E.g., the
primary block is going to be a CBOR array with (at least?) 8 elements,
starting with 0x0808, and is self-framing by virtue of being a CBOR
object.  But the "security target other fields" are not so clearly self
framing, as it's more of a CBOR sequence with type code, block number,
and control flags as three unsigned integers; we have to know a priori
to read three CBOR unsigned integers and treat that as a single object.
Furthermore, the "BIB other fields" (or "BCB other fields") are also
three CBOR unsigned integers, and since it's possible for (e.g.) a BIB
to be the security target of a BIB, the block type code cannot
distinguish between a security target and the BIB information.  Only the
block number could, but IIRC the block number itself is malleable to an
on-path attacker.  And this analysis only covers the currently specified
scope flags; any future additions might add new ways for injectivity to
fail.  It's much better to have a strong injective construction at the
higher layer and not rely on the internal encoding details of the
component pieces.

So, I think we need to include at least the scope flags as part of the
IPPT/AAD in order to provide injectivity.  It might be worth considering
adding additional framing and typing to make clear boundaries between
the different parts of the IPPT/AAD, but my current understanding is
that it would not be strictly necessary to do so.

(D2) There seems to be some risk associated with the current HMAC
construction, since the HMAC with a given key over a given plaintext
will be the same each time it is calculated.  In other protocol
contexts, this has led to practical attacks and HMAC forgery, by using a
side-channel to gain insight into the verifier's behavior and guessing
the correct HMAC tag for a given (attacker-selected) plaintext a byte at
a time.  With only a modest number of trials (4k on average for
HMAC-SHA-256, assuming a fully reliable side channel) this would let the
attacker extract the valid HMAC tag that the verifier produced for
comparison against the attacker's guess at the HMAC tag.  Since this is
the HMAC tag over the attacker's chosen plaintext, this lets the
attacker obtain a valid HMAC tag without knowing the HMAC key.

Now, it seems clear that in the preponderance of BP deployments there
will not be an effective side channel available!  But IMO this still
reflects a fundamental cryptographic weakness in the protocol and we
should make some effort to address it.  There are a couple potential
mitigation approaches off the top of my head, which can be combined if
desired: include a nonce as part of the HMAC input (and encourage
rejection of reused nonces), and require constant-time comparison of the
supplied and expected authentication tag (to prevent using a side
channel from reading it off byte by byte).  I suspect that there may be some
operational issues with the "unique nonce per HMAC" approach that would
make it not terribly reliable in practice, but "use a constant-time
comparison" should be fairly straightforward.

(D3) While we do provide the standard guidance against using any given
key with more than one algorithm (e.g., with HMAC-SHA-256 and
AES256-GCM), there seem to be additional considerations relevant to this
protocol that merit further discussion in the security considerations.
Specifically, we make provision for an AES-KW wrapped key to be included
along with the security payload and mandate that if present, such a key
be used.  Given that the parameter holding the wrapped key does not seem
to be bound to a given message, it seems fairly straightforward for an
in-network attacker to "slice and dice" the ciphertext and wrapped key
away from each other, and cause any wrapped key it has seen to be
attempted to be used with a given algorithm+ciphertext.  This, in turn,
would provide attacker-induced key reuse across algorithms, which is
something that we want to avoid.  While providing full protection
against key reuse with different algorithms would prove fairly
challenging and probably require significant state on the
verifier/security destination, we should at least have some discussion
of the situation, and could provide some modest mitigation techniques
such as using distinct KEKs for receiving wrapped keys that have different
intended usage.  That is, one KEK for receiving AES keys, another for
HMAC keys, etc..  Attaching context (intended algorithm, etc.) to the
KEK allows such context to be indirectly attached to the received
wrapped keys, which otherwise would come without much context for
intended usage.

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

Thanks to Christian Huitema for the multiple secdir reviews, and special
thanks to the authors for adding examples/test vectors as he
recommended, as well as the other updates.

Section 3.1

   BIB-HMAC-SHA2 supports three variants of HMAC-SHA, based on the
   supported length of the SHA-2 hash value.  These variants correspond
   to "HMAC 256/256", "HMAC 384/384", and "HMAC 512/512" as defined in
   [RFC8152] Table 7: HMAC Algorithm Values.  [...]

This is unfortunate timing, I suppose, but RFC 8152 is going to be
replaced imminently by draft-ietf-cose-rfc8152bis-algs and
draft-ietf-cose-rfc8152bis-struct, which are virtually certain to be
published as RFCs before this document.

Section 3.2

       NOTE: The security context identifier and security context
       parameters of the security block are not included in the IPPT
       because these parameters, by definition, are required to verify
       or accept the security service.  Successful verification at
       security verifiers and security acceptors implies that these
       parameters were unchanged since being specified at the security
       source.

(related to D1, but distinct...)
This seems to be only mostly true ... if some other security context was
created that also used HMAC-SHA2 it seems like the same output might be
obtained or validated across security contexts ... but this would only
cause problems if there were different semantics afforded to the
different security contexts in some way.  Any attack would also be
stymied if the honest participants were rigorous in separation of keys,
with any given key being used with only one security context.

Section 3.3.3

   Integrity scope flags that are unrecognized MUST be ignored, as
   future definitions of additional flags might not be integrated
   simultaneously into security context implementations operating at all
   nodes.

It's not entirely clear how useful a mandate to ignore unrecognized
flags will be, if the flags would change the plaintext input and thus
the value of the HMAC output.  I guess maybe the intent is just that
intermediate notes processing a bundle but not acting as security
acceptor should pass through such flags unchanged?

Section 3.3.4

                     BIB-HMAC-SHA2 Security Parameters

    +----+-----------------------+--------------------+---------------+
    | Id |          Name         | CBOR Encoding Type | Default Value |
    +----+-----------------------+--------------------+---------------+
    | 1  |      SHA Variant      |        UINT        |       6       |
    | 2  |      Wrapped Key      |    Byte String     |      NONE     |
    | 4  | Integrity Scope Flags |        UINT        |      0x7      |
    +----+-----------------------+--------------------+---------------+

The examples use a parameter Id of '3' for the Integrity Scope Flags,
not the '4' shown here.  Since the parameter Ids are just CBOR integers,
the sequential assignment with '3' would seem to make the most sense.

Section 3.7.1

      Any local flags used to generate the IPPT SHOULD be placed in the
      integrity scope flags security parameter for the BIB unless these
      flags are expected to be correctly configured at security
      verifiers and acceptors in the network.

Just to confirm: do we want "SHOULD ... unless" or "MUST ... unless"?

Section 4.2

       NOTE: The security context identifier and security context
       parameters of the security block are not included as additional
       authenticated data because these parameters, by definition, are
       those needed to verify or accept the security service.
       Therefore, it is expected that changes to these values would
       result in failures at security verifiers and security acceptors.

As for the BIB, this note seems only mostly true.

Section 4.3.2

   When not provided, implementations SHOULD assume a value of 3
   (indicating use of A256GCM), unless an alternate default is

[same comment about "SHOULD ... unless" as above]

Section 4.5

   The security provided by block ciphers is reduced as more data is
   processed with the same key.  The total number of bytes processed
   with a single key for AES-GCM is recommended to be less than 2^64, as
   described in Appendix B of [AES-GCM].

The treatment in Appendix B seems to be specific to the authentication
functionality (and seems to refer to number of *blocks*, not number of
*bytes*); section 8.3 of that document has additional guidance on
overall invocations of the authenticated encryption function, that
include smaller limits that apply to the number of invocations of the
function.

Section 4.6

      The pairing of an IV and a security key MUST be unique.  An IV
      MUST NOT be used with a security key more than one time.  If an IV

I believe that the use with the *encryption* function is the risky one.
This is good, because if IV reuse with decryption was problematic, our
use of AES-KW would induce pretty strong requirements for state-keeping
on verifiers/recipients in order to meet this requirement that could be
operationally challenging!

      As discussed in Appendix B of [AES-GCM], implementations SHOULD
      limit the number of unsuccessful verification attempts for each
      key to reduce the likelihood of guessing tag values.

This type of check would also have potential issues with state-keeping
when AES-KW is used, since an attacker could cause a large number of
keys to have been used at least once.

Section 4.8.2

      The authentication tag MUST be present in the BCB security context
      parameters field if additional authenticated data are defined for
      the BCB (either in the AAD scope flags parameter or as specified
      by local policy).  This tag MUST be 128 bits in length.

I think the authentication tag always needs to be present, not "just"
when there is AAD used.

Section 7

I see that RFC 5649 (or really, RFC 3537) is also available as a
reference for an AES-KW algorithm, and that the NIST reference indicates
that the RFCs are "essentially equivalent" to what is specified in the
NIST reference.  My understanding is that we have a mild preference for
IETF references over external references when a choice is available.

Likewise, RFC 2104 is available as an HMAC reference.

Section A.1.4

Is the final "full output bundle" supposed to include the payload block
after the BIB block?  I do not see it...

NITS

Section 3.1

   The BIB-HMAC-SHA2 security context provides a keyed hash over a set
   of plain text information.  This context uses the Secure Hash
   Algorithm 2 (SHA-2) discussed in [SHS] combined with the HMAC keyed
   hash discussed in [HMAC].

I think s/keyed hash/keyed-hash Message Authentication Code (MAC)/.

Section 3.3.3

   Bits in this field represent additional information to be included
   when generating an integrity signature over the security target.

My preference is to avoid using the word "signature" to describe a MAC,
but I recognize that there is some precedent for using "signature" in
this manner.  (I won't mention it again for this document.)

Section 3.5

   HMAC keys used with this context MUST be symmetric and MUST have a
   key length equal to the output of the HMAC.  For this reason, HMAC
   keys will be integer divisible by 8 bytes and special padding-aware
   AES key wrap algorithms are not needed.

s/HMAC Keys will be/HMAC key lengths will be/

Section 4.2

   Keys used with this context MUST be symmetric and MUST have a key
   length equal to the key length defined in the security context
   parameters or as defined by local security policy at security
   verifiers and acceptors.  For this reason, content-encrypting keys
   will be integer divisible by 8 bytes and special padding-aware AES
   key wrap algorithms are not needed.

Similarly, s/content-encrypting keys will be/content-encrypting key
lengths will be/.

Section 4.7.1

   The plain text used during encryption MUST be calculated as the
   single, definite-length CBOR byte string representing the block-type-
   specific data field of the security target excluding the CBOR byte
   string identifying byte and optional CBOR byte string length field.

I don't think I see why the CBOR byte string length field is "optional"
in this scenario.  (Likewise for decryption.)

   |             18ED             |    18   |            ED            |
   +------------------------------+---------+--------------------------+
   | C24CDEADBEEFDEADBEEFDEADBEEF |   C24C  | DEADBEEFDEADBEEFDEADBEEF |

I'm having trouble decoding the "CBOR part"s here; in particular, I
expected to see the major type 2 and CBOR "argument" with the length of
the byte string, which '4C' seems to match up with for the second
example, but not be present for the first example.  Are '18' and 'C2'
supposed to be CBOR tags?

Section 4.8.1

      The key length used by this security context MUST be considered
      when setting the AES variant security parameter for the BCB if it
      differs from the default AES variant.  Otherwise, the AES variant

The "MUST be considered" language feels odd to me (what does
"considered" mean?); the "SHOULD be added as the [parameter] if it
differs from the default" languaged used for the SHA2 output length
feels more natural to me.

Section 4.8.2

   During encryption, five inputs are prepared for input to the AES/GCM
   cipher: the decryption key, the IV, the security target cipher text

s/encryption/decryption/

Section 6.2

      In the event that a key is compromised, any security operations
      using a security context associated with that key SHOULD also be
      considered compromised.  This means that the BIB-HMAC-SHA2
      security context SHOULD NOT provide integrity when used with a
      compromised key and BCB-AES-GCM SHOULD NOT provide confidentiality
      when used with a compromised key.

I'm a little confused by the phrasing "SHOULD NOT provide
[confidentiality/integrity]", since the reality is more along the lines
of that they will not do so, factually speaking.  Perhaps the intent is
that the "SHOUL NOT be treated as providing" the indicated properties?

Section 6.4

   The AES key wrap (AES-KW) algorithm used by the security contexts in
   this document does not use an initialization vector and does not
   require any key padding.  [...]

Very pedantically, I think that AES-KW does not use a per-invocation IV
(there is a single globally constant IV used as input to the AES cipher
operation).

Section A.1.4

I suggest using lowercase hex digits consistently.

Section A.3.1.2

What do the chevrons around "300" indicate?

Section A.3.5, A.4.5

I suggest consistently using lowercase hex digits here as well.  (It
shows up when I try to diff a manually assembled bundle against the
encoded output shown here.)