how many port pairs in a call/conference?

grm at ZURICH.IBM.COM grm at ZURICH.IBM.COM
Wed Jun 24 05:58:37 EDT 1998


        Hello,

        While debugging our ASN.1/PER encoder, I noticed a problem with
        the way ICV is calculated in H.225.0.

        Briefly, the PER encodings change when a SEQUENCE type is further
        extended, even if the new extension additions are not included in
        the SEQUENCE value.

        The issue prevents interoperability between software using H.225.0
        version 2 and software using any version, it should be solved before
        any version 2 devices are released.

                                                Pekka Pessi


-------------- next part --------------
h2250-integrityCheckValue-problem.txt   Pekka Pessi <pessi at research.nokia.com>
$Revision: 1.1 $                                         Nokia Research Center
                                                                     June 1998


                        Comments on H.225.0 (1998):
               Problems When Calculating integrityCheckValue


   The current H.225.0 algorithm for calculating the ICV does not work well
   with the PER extension mechanism.  In order to interwork, each H.323
   device needs a separate PER encoding function for each version of H.225.0
   ASN.1 definitions.

Algorithm for Calculating integityCheckValue

   According to the H.225.0 v2, integrityCheckValue is defined and
   calculated as follows:

ICV ::= SEQUENCE
{
  algorithmOID OBJECT IDENTIFIER, -- the algorithm used to compute the signature
  icv          BIT STRING         -- the computed cryptographic integrity check
                                  -- value or signature
}

   integrityCheckValue - provides improved message integrity/message
        authentication of the RAS messages. The cryptographically based
        integrity check value is computed by the sender applying a
        negotiated integrity algorithm and the secret key upon the entire
        message. Prior to integrityCheckValue computation this field shall
        be ignored and shall be empty. After computation, the sender puts
        the computed integrity check value in the integrityCheckValue field
        and transmits the message.

   The above algorithm (AFAIK I have understood it correctly) assumes that
   the sender and receiver can encode the PDU exactly in the same way. It is
   a reasonable assumption, as PER produces only one possible (canonical)
   encoding for given PDU.  However, there is a serious problem: the
   canonical representation changes if the ASN.1 SEQUENCE type is extended
   later.

PER Encoding of an Extended ASN.1 SEQUENCE

   In the PER encoding of extensions to SEQUENCE types, the encoder first
   encodes the number of extensions as a normally small non-negative
   integer, then a bit field with one bit for each extension followed by the
   extensions itself (bit is one if the extension is present, zero if
   not). The encoding of each extension is preceded by the length of their
   encoding in octets.

   Now, if the sender A uses following ASN.1 definition for a SEQUENCE

      Foo ::= SEQUENCE
      {
           bar                 INTEGER (0..127),
           ...,
           baz                 INTEGER (0..255) OPTIONAL,
           integrityCheckValue ICV OPTIONAL
      }

   When encoding this, the length of extension bitfield is 2.  However,
   recipient B is using extended version of Foo like this:

      Foo ::= SEQUENCE
      {
           bar                 INTEGER (0..127),
           ...,
           baz                 INTEGER (0..255) OPTIONAL,
           integrityCheckValue ICV OPTIONAL,
           importantExtension  SomeType OPTIONAL
      }

   B decodes the Foo, removes ICV and encodes the packet again.  In the
   resulting encoding, the length of extension bitfield is 3, and the ICV
   that B regenerates is different that A generated and sent to B. B is not
   able to interwork with systems using earlier version of the ASN.1 spec.

ASN.1 Compilers Don't Grok Unknown Extensions

   There are also problems because the way some ASN.1 compilers behave.
   Using our previous example, when A receives Foo with the
   importantExtension field from B, A has somehow to include the value when
   it is re-encoding Foo in order to calculate the ICV. However, it may be
   very hard to present an value of an unknown extension to the ASN.1
   encoding functions. As a possible solution the ICV calculation could be
   included in the ASN.1 decoding process.

Problems with Non-OPTIONAL Extensions

   Another problem with some ASN.1 compilers is inclusion of non-OPTIONAL
   extensions. Let us assume that software C uses following ASN.1 definition
   for Foo:

      Foo ::= SEQUENCE
      {
           bar                 INTEGER (0..127),
           ...,
           baz                 INTEGER (0..255) OPTIONAL,
           integrityCheckValue ICV OPTIONAL,
           importantExtension  SomeType OPTIONAL,
           criticalExtension   OtherType
      }

   There are two kinds of problems with an extension like criticalExtension.
   First, the encoder may try to ensure that all encoded PDUs conform to the
   specification and signal an error when a PDU without criticalExtension is
   encoded. Another problem is that the intermediate representation produced
   by the ASN.1 compiler may not provide means for application to express
   that criticalExtension is not present. (In other words, the produced
   structure usually contains a flag telling whether an optional field is
   present or not. Such flags are not included when the field is not
   optional.)

   The presense or absence of the OPTIONAL flag in an extension does not
   change the PER encoding of the SEQUENCE. In order to avoid previously
   mentioned problems, application may use a version of ASN.1 notation that
   has extra OPTIONAL keyword after each extension.

Solution 1: Clarification to the PER Encoding Process

   The text in PER document (X.691, 1994) is somewhat ambiguous how many
   bits should be included in the extension present bitfield of SEQUENCE. To
   quote verbatim: "Let the number of extension additions in the type being
   encoded be "n", then a bit-field with "n" bits shall be produced for
   addition to the field-list." (Is the "type being encoded" the abstract
   syntax or an actual value like { bar 1, baz 2 }?)  However, the 0 bits at
   the end of extension present bitfield can be left out without changing
   the resulting semantics: the corresponding extensions are not present. As
   a result, the PER encoding does not change after a new extension is added
   to the ASN.1 specification.

   This solution, while leaving H.225.0 v2 protocol as it is, requires
   however changes to some existing ASN.1 compilers, and in a pessimal case,
   to the X.691 standard text, too.

Solution 2: Hack

   The receiving application does not decode and the re-encode the PDU, but
   rather removes the ICV from the encoded PDU. In practice, this requires that
   application can identify PER-encoded fields within the PDU and it can
   regenerate them, i.e.  it has effectively the same functionality as a PER
   encoder/decoder.

Solution 3: Calculating ICV Differently

   The following algorithm for generating and checking the ICV makes it
   possible to avoid all the previously mentioned problems. The problems are
   avoided by breaking the protocol layering, the application changes directly
   the PER-encoded PDU:

   integrityCheckValue - provides improved message integrity/message
        authentication of the RAS messages. The cryptographically based
        integrity check value is computed by the sender applying a
        negotiated integrity algorithm and the secret key upon the entire
        message. Prior to integrityCheckValue computation an ICV with a
        previously agreed magic value (or key when using MDC) will be
        inserted to this field. The magic value will contain same
        algorithmOID and exactly as many bits in the icv BIT STRING as the
        computed value. After computation, the sender replaces the magic
        value with the computed integrity check value and transmits
        message. The receiver decodes message, replaces the received
        integrity value with the magic value, calculates the ICV and
        compares it with the received value.

   NOTE: The sender or receiver can encode the ICV separately and replace
        it directly within the encoded PDU, when the magic ICV and computed
        ICV have exactly the same length.  When replacing ICV value within
        an encoded PDU, re-encoding the whole PDU can be avoided.

   NOTE: The above algorithm does not require directly changing the
        PER-encoded PDU. Like the current algorithm, ICV can be replaced
        with a new value above presentation layer then PDU will be
        re-encoded. It makes it easy, however: as the magic value is a very
        unique octet-aligned bit pattern (random data of 64 bits or more,
        probably), it should be easy to spot and replace it from the encoded
        PDU.

   NOTE: It is not advisable to use magic value as the key to MAC
        algorithm.

   Example code:

      int icv_replace(
           u_char *msg, size_t len,
           u_char const *icv, u_char const *magic, size_t ilen)
      {
        u_char *m, *mim;
        size_t i, j, ilen_in_octets, ilen_in_full_octets;

        ilen_in_octets = (ilen + 7) >> 3;
        ilen_in_full_octets = ilen >> 3;

        /* find magic value from message */
        for (m = msg, mim = NULL; m - msg < len - ilen_in_octets; m++) {
          /* NOTE: the magic value/icv may not be integral number of octets */
          for (i = 0; i < ilen_in_full_octets; i++) {
            if (m[i] != magic[i])
              break;
          }
          if (i == ilen_in_full_octets) {
            if (mim)
              return -2; /* failure: two or more magic values found */
            mim = m;
          }
        }

        if (mim == NULL) {
          return -1; /* failure: no magic value found */

        /* replace magic value with icv */
        for (i = 0; i < ilen_in_octets; i++) {
          mim[i] ^= magic[i] ^ icv[i];
        }

        return 0; /* success */
      }

Solution 4:

   Fourth alternative is to treat encoded RasMessage as octet string.  IVC
   can be calculated over that octet string and appended to the PDU on
   separate layer.  E.g., RAS PDU could be defined as follows:

      RasMessage ::= CHOICE {
--8<----8<----8<----8<----8<----8<----8<----8<----8<----8<--
         -- all previous RasMessage CHOICEs are here
--8<----8<----8<----8<----8<----8<----8<----8<----8<----8<--
         authenticatedRasMessage SEQUENCE {
            plainRasMessage OCTET STRING,
            ivc             IVC,
            ...
         }
      }


More information about the sg16-avd mailing list