Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8302225

SunJCE Provider doesn't validate key sizes when using 'constrained' transforms for AES/KW and AES/KWP

XMLWordPrintable

    • 17
    • b11

        One of my colleagues reported the following issue:

        OpenJDK's SunJCE `Provider` doesn't validate key sizes when using "constrained" (see below) transforms for AES/KW and AES/KWP which were introduced in OpenJDK 17.

        Re: Constrained. Looking at the "Standard Names" reference for Ciphers for Java 17: https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html#cipher-algorithm-names which states for AES "To use the AES cipher with only one valid key size, use the format AES_<n>, where <n> can be 128, 192 or 256".

        The following AESWrap and AESWrapPad sections have similar wording and state that AESWrap is the same as AES/KW and AESWrapPad is the same as AES/KWP. I.e. we should reasonably assume that AES_128/KW behaves the same as (e.g.) AES_128/CBC when it comes to valid key sizes.

        However this is not the case. For modes CBC, ECB etc, `Cipher.init()` will throw `InvalidKeyException` if an incorrectly sized key is passed in. For mode KW and KWP, no exception is thrown and the operation just silently uses the key that is passed in and sets its internal key size to match.

        A demo is provided (see attached `KeyWrap.java` file).

        Its method `findDuplicateOutputs()` finds key-size-constrained transformations that give the same result. So for example the first five lines:

        ```
        Secret key length 128
        128 bit KEK with AES/KWP/NoPadding -> 946628a78a4bd865a6169bdb460e05f25e793c8bed49d5fd
            AES_128/KWP/NoPadding with same 128 bit KEK gives the same result.
            AES_192/KWP/NoPadding with same 128 bit KEK gives the same result.
            AES_256/KWP/NoPadding with same 128 bit KEK gives the same result.
        ```
        shows that AES/KWP/NoPadding, AES_128/KWP/NoPadding, AES_192/KWP/NoPadding and AES_256/KWP/NoPadding all give the result when passed a 128 bit key-encrypting key.

        We know that AES/KWP/NoPadding is _supposed_ to use whatever key size is passed in, so this tells us that all 4 transforms are using a 128bit key and key size. But from the Standard Names document, we would expect the AES_192 and AES_256 variants to throw.

        The rest of the output repeats this for different secret key and key-encrypting key sizes to show the issue applies across the board.

        The poc uses AES/KWP but the results are the same as for AES/KW.

        The second method in the demo is `checkKeySizeConstraintsForAesCbc()`. This shows that for AES/CBC, trying to use an invalid key size throws in `init()`. The same applies to ECB, GCM and all the other, non-wrapping modes. Default output from this method is nothing... If it succeeds in initialising a `Cipher` with an invalid key then it will print.

              valeriep Valerie Peng
              cushon Liam Miller-Cushon
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: