<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [

<!ENTITY RFC2119 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC5246 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5246.xml">
<!ENTITY RFC6979 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.6979.xml">
<!ENTITY RFC8017 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.8017.xml">

]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- control vertical white space
     (using these PIs as follows is recommended by the RFC Editor) -->
<?rfc compact="yes" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<!-- keep one blank line between list items -->
<!-- end of list of popular I-D processing instructions -->
<rfc category="info" docName="draft-irtf-cfrg-rsa-guidance-00" ipr="trust200902"
    updates="8017">
  <!-- ***** FRONT MATTER ***** -->

  <front>
      <title abbrev="RSA Implementation Guidance">Implementation Guidance for
      the PKCS #1 RSA Cryptography Specification</title>

    <author fullname="Hubert Kario" initials="H."
            surname="Kario">
      <organization>Red Hat, Inc.</organization>

      <address>
        <postal>
          <street>Purkynova 115</street>

          <city>Brno</city>

          <region></region>

          <code>61200</code>

          <country>Czech Republic</country>
        </postal>

        <phone></phone>

        <email>hkario@redhat.com</email>
      </address>
    </author>

    <date day="04" month="March" year="2024" />

    <area>General</area>

    <workgroup>Internet Engineering Task Force</workgroup>

    <keyword>RSA</keyword>

    <abstract>
        <t>This document specifies additions and amendments to
        RFC 8017. Specifically, it provides guidance to implementers
        of the standard to protect against side-channel attacks.
        It also deprecates the RSAES-PKCS-v1_5 encryption scheme, but
        provides an alternative depadding algorithm that protects against
        side-channel attacks raising from users of vulnerable APIs.
        The purpose of this specification is to increase security of
        RSA implementations.
      </t>
    </abstract>
  </front>

  <middle>
    <section title="Introduction">
        <t>The <xref target="RFC8017">PKCS #1</xref>
        describes the RSA cryptosystem, providing guidance on implementing
        encryption schemes and signature schemes.</t>

        <t>Unfortunately, straight-forward implementation of the RSA
        encryption schemes leave it vulnerable to side-channel attacks.
        Protections against them are not documented in RFC 8017,
        and attacks are mentioned only in passing.</t>
    </section>

    <section title="Rationale">
        <t>The RSAES-PKCS-v1_5 encryption scheme is known to be problematic
        since 1998,
        when Daniel Bleichenbacher published his attack
        <xref target="Bleichenbacher98"/>.
        Side-channel attacks against public key algorithms, including RSA,
        are known to be possible since 1996 thanks to work by Paul Kocher
        <xref target="Kocher96"/>.
        </t>
        <t>
        Despite those results, side-channel attacks against RSA implementations
        have proliferated for the next 25 years.
        Including attacks against simple exponentiation implementations
        <xref target="Dhem98"/><xref target="Schindler01"/>, implementations
        that use the Chinese Remainder Theorem optimisation
        <xref target="Schindler00"/><xref target="Brumley03"/>
        <xref target="Aciicmez05"/>, and implementations that use
        either base or exponent blinding exclusively
        <xref target="Aciicmez07"/><xref target="Aciicmez08"/>
        <xref target="Schindler14"/>.
        </t>
        <t>Similarly, side-channel free handling of the errors from
        the RSAES-PKCS-v1_5 decryption operation is something that
        implementations struggle with
        <xref target="Bock18"/><xref target="Kario23"/>.
        </t>
        <t>We thus provide guidance how to implement those algorithms
        in a way that should be secure against at least the simple timing
        side channel attacks.
        </t>
    </section>

    <section title="Requirements Language">
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
      "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
      document are to be interpreted as described in <xref
      target="RFC2119">RFC 2119</xref>.</t>
    </section>

    <!-- This PI places the pagebreak correctly (before the section title) in the text output. -->

    <?rfc needLines="8" ?>

    <section title="Notation">
        <t>In this document we reuse the notation from RFC 8017, in addition,
            we define the following:</t>
        <dl>
            <dt>AL</dt>
            <dd><t>alternative message length, non-negative integer,
                0 &lt;= AL &lt;= k - 11</t></dd>

            <dt>AM</dt>
            <dd><t>alternative encoded message, an octet string</t></dd>

            <dt>bb</dt>
            <dd><t>base blinding factor, a positive integer</t></dd>

            <dt>bbInv</dt>
            <dd><t>base un-blinding factor, a positive integer,
              <figure><artwork>
  bbInv = bb^(-1) mod n
              </artwork></figure></t></dd>

            <dt>D</dt>
            <dd><t>octet string representation of d</t></dd>

            <dt>DH</dt>
            <dd><t>an octet string of a SHA-256 hash of D</t></dd>

            <dt>KDK</dt>
            <dd><t>an octet string containing a Key Derivation Key for a
                specific ciphertext C</t></dd>

            <dt>l</dt>
            <dd><t>length in octets of the message M</t></dd>

            <dt>b_i</dt>
            <dd><t>an exponent blinding factor for i-th prime,
                non-negative integer.</t></dd>
            <dt>g_i</dt>
            <dd><t>a modulus blinding factor for the i-th prime,
                non-negative integer.</t></dd>
        </dl>
    </section>

    <section title="Side channel attacks">
        <t>Cryptographic implementations may provide a lot of indirect signals
        to the attacker that includes information about the secret
        processed data. Depending on type of information, those leaks can
        be used to decrypt data or retrieve private keys.
        Most common side-channels that leak information about secret
        data are:
        <list style="numbers">
            <t>Different errors returned</t>
            <t>Different processing times of operations</t>
            <t>Different patterns of jump instructions and memory accesses</t>
            <t>Use of hardware instructions that take different amount
               time to execute depending on operands or result</t>
       </list>
       </t>
       <t>Some of those leaks may be detectable over the network, while
           others may require closer access to the attacked system.
           With closer access, the attacker may be able to measure
           power usage, electromagnetic emanations, or sounds and
           correlate them with specific bits of secret information.
       </t>
       <t>Recent research into network based side channel detection has shown
          that even very small side channels (of just few clock cycles) can
          be reliably detected over the network. The detectability depends
          on the sample size the attacker is able to collect, not on size
          of the side-channel.
       </t>
    </section>

    <section title="General recommendations">
        <t>As a general rule, all operations that process secret information
          (be it parts of the private key or parts of encrypted message)
          MUST be performed with code that doesn't have secret data dependent
          branch instructions, secret data dependent memory accesses, or
        uses non-constant time machine instructions (which ones are those
        is architecture dependant,
          but division is commonly non-constant time).
        </t>
        <t>Special care should be placed around the code that handles
        the conversion of the numerical representation to the octet string
            representation in RSA decryption operations.</t>

        <t>All operations that use private keys SHOULD additionally employ
        both base blinding and exponent blinding as protections against
            leaks inside modular exponentiation code.</t>
    </section>

    <section title="Side-channel free modular exponentiation">
        <t>The underlying modular exponentiation algorithm MUST be
           constant time with regards to the exponent in all uses of the
           private key.</t>
       <t>For private key decryption the modular exponentiation algorithm
       MUST be constant time with regards to the output of the
           exponentiation.</t>
       <t>In case the Chinese remainder theorem optimisation is used the
        modular exponentiation algorithm must also be constant time
           with regards to the used moduli.</t>
        <section title="General recommendations">
            <t>It's especially important to make sure that all values that
            are secret to the attacker are stored in memory buffers that
                have sizes determined by the public modulus.</t>
            <t>For example, the private exponents should be stored in
                memory buffers that have sizes determined by the public
                modulus value, not the numerical values of the exponents
                themselves.</t>
            <t>Similarly, the size of the output buffer for multiplication
            should always be equal to the sum of buffer sizes of multiplicands.
            The output size of the modular reduction operation should
            similarly be equal to the size of the modulus and not depend
                on bit size of the output.</t>
        </section>
        <section title="Montgomery ladder">
        <t>For the modular exponentiation algorithm to be side-channel free
            every step of the calculation MUST NOT depend on the bits of
            the exponent. In particular, use of simple square and multiply
            algorithm will leak information about bits of the exponent
            through lack of multiplication operation in individual
            exponentiation steps.</t>
        <t>The recommended workaround against it, is the use of the
            Montgomery ladder construction.</t>
        <t>While that approach ensures that both the square and multiply
        operations are performed, the fact that the results of them are
        placed in different memory locations based on bits of the secret
        exponent will provide enough information for an attacker
            to recover the bits of the exponent. To counteract it,
        the implementation should ensure that both memory locations
        are accessed and updated on every step.
        </t>
        </section>
        <section title="Montgomery reduction in multiplication">
            <t>As multiplication operations quickly make the intermediate
            values in modular exponentiation large, performing a modular
            reduction after every multiplication or squaring operation
                is a common optimisation.</t>
            <t>To further optimise the modular reduction, the Montgomery
            modular multiplication is used for performing the combined
            multiply-and-reduce operation. The last step of that operation
            is conditional on the value of the output. A side-channel
            free implementation should perfom the subtraction in all cases
            and then copy the result or the first operand of the subtraction
            based on sign of the result of the subtraction in side-channel
            free manner.
        </t>
        </section>
    </section>

    <section title="Base blinding">
        <t>As a protection against multiple attacks, it's RECOMMENDED to
            perform all operations involving the private key with the use
            of blinding <xref target="Kocher96"/>.</t>
        <t>It should be noted that for decryption operations the
            unblinding operation MUST be performed using side-channel free
            code that does not leak information about the result of this
            multiplication and reduction modulo operation.</t>
        <t>To implement base blinding, select a number bb uniformly at random
            such that it is relatively prime to n and smaller than n.</t>
        <t>Compute multiplicative inverse of bb modulo n.
            <figure><artwork>
  bbInv = bb^(-1) mod n
            </artwork></figure></t>
        <t>In the RSADP() operation, after performing step 1, multiply c
            by bb mod n. Use the result as new c for all the remaining
            operations.</t>
        <t>Before returning the value m in step 3, multiply it by bbInv mod n.
            </t>
        <t>Note: multiplication by bbInv and reduction modulo n MUST be
            performed using side-channel free code with respect to
            value m.</t>
        <t>As calculating multiplicative inverse is expensive, implementations
        MAY calculate new values of bb and bbInv by squaring them:
        <figure><artwork>
  new bb = bb^2 mod n
  new bbInv = bbInv^2 mod n
            </artwork></figure></t>
        <t>A given pair of blinding factors (bb, bbInv) MUST NOT be used for
           more than one RSADP() operation.</t>
        <t>Unless the multiplication (squaring) and reduction modulo operations
            are
           verified to be side-channel free, it's RECOMMENDED to generate
           completely new blinding parameters
            every few hundred private key operations.</t>
    </section>

    <section title="Exponent blinding">
        <t>To further protect against private key leaks, it's RECOMMENDED
            to perform the blinding of the used exponents
            <xref target="Kocher96"/>.</t>
        <t>When performing the RSADP() operation, the blinding depends on the
            form of the private key.</t>
        <t>If the key is in the first form, the pair (n, d), then the
            exponent d should be modified by adding a multiple of Euler
            phi(n): m = c^(d + b*phi(n)) mod n. Where b is a 64 bit long
            uniform random number.</t>
        <t>A new value b MUST be selected for every RSADP() operation.</t>
        <t>If the key is the second form, the quintuple (p, q, dP, dQ,
            qInv) with optional sequence of triplets (r_i, d_i, t_i), i = 3, ...,
            u, then each exponent used MUST be blinded individually.</t>
        <list style="numbers">
            <t>The m_1 = c^(dP + b_1 * phi(p)) mod p</t>
            <t>The m_2 = c^(dQ + b_2 * phi(q)) mod q</t>
            <t>If u > 3, then m_i = c^(d_i + b_i * phi(r_i)) mod (r_i)</t>
        </list>
        <t>Where b_1, b_2, ..., b_i are all uniformly selected random numbers
            at least 64 bits long (or at least 2 machine word sizes, whichever
            is greater).</t>
        <t>As Euler phi(p) for an argument p that's a prime is equal p - 1,
            it's simple to calculate in this case.</t>
        <t>Note: the selection of random b_i values, multiplication of them
            by the result of phi() function, and addition to the exponent
            MUST be performed with side-channel free code.</t>
        <t>Use of smaller blinding factor is NOT RECOMMENDED, as values shorter
           than 64 bits have been shown to still be vulnerable to side-channel
            attacks<xref target="Bauer12"/><xref target="Schindler11"/>.</t>
        <t>The b_1, b_2, ..., b_i factors MUST NOT be reused for multiple
            RSADP() operations.</t>
    </section>

    <section title="Modulus blinding">
        <t>To protect against private key leaks, it's RECOMMENDED
           to perform blinding of the used modulus values in the CRT
           implementations.</t>
        <t>When the key is in the first form, the pair (n, d), then
           the used modulus is public, thus no blinding is necessary.</t>
        <t>If the key is in the second form, the quintuple (p, q, dP, dQ, qInv)
            with the optional sequence f triplets (r_i, d_i, t_i), i = 3, ...,
            u, then each modulus used MUST be blinded individually.</t>
        <list style="numbers">
            <t>The m_1 = c^dP mod (g_1 * p)</t>
            <t>The m_2 = c^dQ mod (g_2 * q)</t>
            <t>If u > 3, then m_i = c^d_i mod (g_3 * r_i)</t>
        </list>
        <t>Where g_1, g_2, ..., g_i are all uniformely selected random number
           at least 64 bits long (or at least 2 machine word sizes, whicher
           is greater).</t>
       <t>Before step 3 of the original algorithm, reduce the returned
          value m mod n.</t>
    </section>

    <section title="Depadding">
        <t>In case of RSA-OAEP, the padding is self-verifying, thus the
            depadding operation needs to follow the standard algorithm
            to provide a safe API to users.</t>
        <t>It MUST ignore the value of the very fist octet of padding and
            process the remaining bytes as if it was equal zero.</t>
        <t>The RSAES-PKCS-v1_5 encryption scheme is considered deprecated, and
            should be
            used only to process legacy data. It MUST NOT be used as part
            of online protocols or API endpoints.</t>
        <t>For implementations that can't remove support for this padding
            mode it's RECOMMENDED to implement an implicit rejection mechanism
            that completely
            hides from the calling code whether the padding check
            failed or not.</t>
        <t>It should be noted that the algorithm MUST be implemented
            as stated, otherwise in case of heteregonous environments
            where two implementations use the same key but implement the
            implicit rejection differently, it may be possible for the
            attacker to compare behaviour between the implementations to
            guess if the padding check failed or not.</t>
        <t>The basic idea of the implicit rejection is to prepare a random
            but deterministic message to be returned in case the standard
            RSAES-PKCS-v1_5 padding checks fail. To do that, use the private
            key and the provided ciphertext to derive a static, but unknown to
            the attacker, random value. It's a combination of the method
            documented in the TLS 1.2 (RFC 5246<xref target="RFC5246"/>)
            and the deterministic (EC)DSA signatures (RFC 6979
            <xref target="RFC6979"/>).</t>
        <section title="IRPRF">
            <t>For the calculation of the random message for implicit
            rejection we define a Pseudo-Random Function (PRF) as follows:</t>
            <t>IRPRF( KDK, label, length )</t>
            <t>Input:</t>
            <t>KDK the key derivation key</t>
            <t>label a label making the output unique for a given KDK</t>
            <t>length requested length of output in octets</t>
            <t>Output: derived key, an octet string</t>
            <t>Steps:</t>
            <list style="numbers">
                <t>If KDK is not 32 octets long, or if length is larger than
                    8192 return error and stop.</t>
                <t>The returned value is created by concatenation of subsequent
                    calls to a SHA-256 HMAC function with the KDK as the
                    HMAC key and following octet string as the message:
                <figure><artwork>
  P_i = I || label || bitLength
            </artwork></figure></t>
                <t>Where the I is an iterator value encoded as two octet long
                big endian integer, label is the passed in label, and bitLength
                is the length times 8 (to represent number of bits of output)
                    encoded as two octet big endian integer. The iterator
                    is initialised to 0 on first call, and then incremented by
                    1 for every subsequent HMAC call.</t>
                <t>The HMAC is iterated until the concatenated output is
                    shorter than length</t>
                <t>The output is the length left-most octets of the
                    concatenated HMAC output</t>
            </list>
        </section>
        <section title="Implicit rejection">
            <t>For implementations that cannot remove support for the
            RSAES-PKCS-v1_5 encryption scheme
            nor provide a usage-specific API,
            it's possible to implement an implicit rejection
             algorithm as a protection measure. It should be noted that
            implementing it correctly is hard, thus it's RECOMMENDED instead
            to
             disable support for RSAES-PKCS-v1_5 padding instead.</t>
            <t>To implement implicit rejection, the
             RSAES-PKCS1-V1_5-DECRYPT from section 7.2.2 of RFC 8017 needs
             to be implemented as follows:</t>
        <list style="numbers">
            <t>Length checking: If the length of the ciphertext C is not k
                octets (or if k &lt; 11), output "decryption error" and stop.</t>
            <t>RSA decryption:
               <list style="letters">
                   <t>Convert the ciphertext C to an integer ciphertext
                  representative c:
                   <figure><artwork>
  c = OS2IP (C).
                   </artwork></figure>
                   </t>
                   <t>Apply the RSADP decryption primitive to
              the RSA private key (n, d) and the ciphertext
              representative c to produce an integer message
                   representative m:
                   <figure><artwork>
  m = RSADP ((n, d), c).
                   </artwork></figure>
                   Note: the RSADP MUST be constant-time with respect of
                   message m.<vspace/>
                   If RSADP outputs "ciphertext representative out of range"
                   (meaning that c >= n), output "decryption error" and stop.
                   </t>
                   <t>Convert the message representative m to an encoded message
                   EM of length k octets:
                   <figure><artwork>
  EM = I2OSP (m, k).
                   </artwork></figure>
                   Note: I2OSP MUST be constant-time with respect of m.
                   </t>
               </list>
           </t>
           <t>Derivation of alternative message
              <list style="numbers">
                <t>Derive the Key Derivation Key (KDK)
                <list style="letters">
                    <t>Convert the private expoent d to a string of length
                       k octets:
                      <figure><artwork>
  D = I2OSP (d, k).
                      </artwork></figure>
                    </t>
                    <t>Hash the private exponent using the SHA-256 algorithm:
                      <figure><artwork>
  DH = SHA256 (D).
                      </artwork></figure>
                      Note: This value MAY be cached between the decryption
                      operations, but MUST be considered private-key
                      equivalent.
                  </t>
                  <t>Use the DH as the SHA-256 HMAC key and the provided
                  ciphertext C as the message. If the ciphertext C is not
                  k octets long, it MUST be left padded with octets of value
                  zero.
                      <figure><artwork>
  KDK = HMAC (DH, C, SHA256).
                      </artwork></figure>
                  </t>
                  </list>
              </t>
              <t>Create the candidate lengths and the random message
              <list style="letters">
                  <t>Use the IRPRF with key KDK, "length" as six octet label
                  encoded with UTF-8, to generate 256 octet output.
                  Interpret this output as 128 two octet long big-endian
                  numbers.
                  <figure><artwork>
  CL = IRPRF (KDK, "length", 256).
                  </artwork></figure>
                 </t>
                 <t>Use the IRPRF with key KDK, "message" as a seven octet
                 label encoded with UTF-8 to generate k octet long output
                 to be used as the alternative message:
                 <figure><artwork>
  AM = IRPRF (KDK, "message", k).
                 </artwork></figure>
                 </t>
              </list>
              </t>
              <t>Select the alternative length for the alternative message.
              <vspace/>
              Note: this must be performed in side-channel free way.
              <list style="letters">
                  <t>Iterate over the 128 candidate CL lengths. For each
                  zero out high order bits so that they have the same bit
                      length as the maximum valid message size (k - 11).</t>
                  <t>Select the last length that's not larger than k - 11,
                     use 0 if none are. Save it as AL.</t>
              </list>
              </t>
              </list>
           </t>
           <t>EME-PKCS1-v1_5 decoding: Separate the encoded message EM into
          an octet string PS consisting of nonzero octets and a message
           M as
             <figure><artwork>
  EM = 0x00 || 0x02 || PS || 0x00 || M.
             </artwork></figure>
             If the first octet of EM does not have hexadecimal value 0x00,
          if the second octet of EM does not have hexadecimal value
          0x02, if there is no octet with hexadecimal value 0x00 to
          separate PS from M, or if the length of PS is less than 8
             octets, the check variable must remember if any of those checks
             failed. Irrespective of the check variable value, the code should
             also return length of message M: L. If there is no octet with
             hexadecimal value 0x00 to separate PS from M, then L should equal
             0.
             <vspace/>
             Note: All those checks MUST be performed irrespective if previous
             checks failed or not. A common technique for that is to have
             a check variable that is OR-ed with the results of subsequent
             checks.
         </t>
             <t>Decision which message to return: in case the check variable
             is set, the code should return the last AL octets of AM,
             in case the check variable is unset the code should return
             the last L octets of EM.
             <vspace/>
             Note: The decision which length to use MUST be performed in
             side-channel free manner. While the length of the returned
             message is not considered sensitive, the read memory location is.
             As such, when returning message M both EM and AM
             memory locations MUST be read.</t>
        </list>
        </section>
    </section>

    <section title="Safe API">
        <t>Performing all actions in a way that doesn't leak the status
        of the padding check includes the API provided to 3rd party code.
        In particular, if the RSA decryption implementation doesn't
        implement implicit rejection, then all three pieces of information:
        the padding check, the length of returned message, and the value
        of the message are sensitive information, useful in mounting an
        attack. As such, any API that returns an error in substantially
        different manner than a successful decryption (e.g. raising
        an exception, returning a null pointer, returning a different
        type of structure) is vulnerable to side-channel attacks.</t>
    </section>

    <section title="Non-fixes">
        <t>While there are infinite ways to implement those algorithms
        incorrectly few common ideas to work-around side-channel attacks
        are repeated. We list few of them as examples of approaches that
        don't work and thus MUST NOT be used.</t>

        <section title="Random delays">
            <t>Commonly proposed workaround for timing attacks is to add
                a random delay to procesing of encrypted data.
                For such mitigation to be effective in practice
                (raise attacker's work factor to gain meaningful safety
                margin) it would need to be in the order of at least
                few seconds if not tens of seconds. Effective sizes and
                distributions of delays have not been subject of extensive
                study.
            </t>
            <t>It should also be noted that such a delay would need to be
                applied in addition to the regular mitigation (generate random
                key, use it in case RSAES-PKCS-v1_5 padding checks).
                That is, it needs to be implemented in the calling code, not
                in the depaddng code.
            </t>
            <t>At the same time, performing a simple wait masks only the
                timing side channel. It doesn't mitigate other side-channels,
                like ones that depend on power usage or memory access pattern.
            </t>
        </section>

        <section title="Returing random value from API">
            <t>A simpler variant of the proposed implicit rejection
               algorithm, where the decryption API returns a random
               message in case the padding check fails or the decrypted
               message has unexpected length, as decribed in
               <xref target="RFC5246"/>, isn't a universal mitigation.</t>
            <t>In case of a Bleichenbacher like attack, the attacker is
               trying to differentiate two classes of ciphertexts:
               ones that decrypt to message of specific size
               and ones that have invalid padding or decrypt to a message
               of unexpected size. That translates to two kind of values
               being returned to calling code: either the same
               message always for every decryption, or a different
               message for every decryption.</t>
            <t>If that message is later used in any operation that
               is not side-channel free (key derivation, symmetric padding
               removal, message parsing), then the attacker will be able
               to observe two kinds of behaviour: consistent one
               for static messages and erratic one for randomly generated
               messages.</t>
            <t>Use of such a message as a key with block cipher modes
               that require padding, like AES-CBC with PKCS #7 padding,
               is particularly leaky as it has about 1 in 256 chance of
               successful decryption with random key.</t>
            <t>The simple implicit rejection with random message may be
               implemented safely in TLS 1.2 because both static messages
               and randomly generated messages are mixed together
               with the random nonce generated by the server, thus the
               attacker is unable to differentiate if the randomness originates
               in the nonce or in the randomisation of the message.</t>
        </section>
    </section>

    <section title="Deprecated Algorithms">
        <t>Current protocol deployments MUST NOT use
            encryption with RSAES-PKCS-v1_5 padding.
            Support for RSAES-PKCS-v1_5 SHOULD be disabled in default
            configuration of any implementation of RSA cryptosystem.
            All new protocols MUST NOT specify RSAES-PKCS-v1_5 as a valid
            encryption padding for RSA keys.</t>
    </section>

    <!-- Possibly a 'Contributors' section ... -->

    <section anchor="IANA" title="IANA Considerations">
      <t>This memo includes no request to IANA.</t>
    </section>

    <section anchor="Security" title="Security Considerations">
        <t>This whole document specifies security considerations for
        RSA implementations.
      </t>
    </section>
  </middle>

  <!--  *****BACK MATTER ***** -->

  <back>
    <!-- References split into informative and normative -->


    <references title="Normative References">

      &RFC8017;

    </references>

    <references title="Informative References">
      &RFC2119;

      &RFC5246;

      &RFC6979;

      <reference
            anchor="Bauer12"
            target="https://doi.org/10.1007/978-3-642-29912-4_7">
        <front>
            <title>Attacking Exponent Blinding in RSA without CRT</title>
            <author fullname="Sven Bauer"/>
            <date year="2012"/>
          </front>
          <seriesInfo
              name="Lecture Notes in Computer Science"
              value="vol 7275"/>
      </reference>

      <reference
          anchor="Schindler11"
          target="https://doi.org/10.1007/978-3-642-21554-4_5">
        <front>
            <title>Exponent Blinding Does Not Always Lift (Partial) Spa Resistance to Higher-Level Security</title>
            <author fullname="Werner Schindler"/>
            <author fullname="Kouichi Itoh"/>
            <date year="2011"/>
        </front>
        <seriesInfo
            name="Lecture Notes in Computer Science"
            value="vol 6715"/>
      </reference>

      <reference
          anchor="Bleichenbacher98"
          target="https://doi.org/10.1007/BFb0055716">
        <front>
          <title>Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS#1</title>
          <author fullname="Daniel Bleichenbacher"/>
        </front>
        <seriesInfo
            name="Lecture Notes in Computer Science"
            value="vol 1462"/>
      </reference>

      <!-- attacks on RSA without CRT -->
      <reference
          anchor="Kocher96"
          target="https://doi.org/10.1007/3-540-68697-5_9">
        <front>
          <title>Timing Attacks on Implementations of Diffie-Hellman, RSA, DSS, and Other Systems.</title>
          <author fullname="Paul C. Kocher"/>
          <date year="1996"/>
        </front>
        <seriesInfo
            name="Lecture Notes in Computer Science"
            value="vol 1109"/>
      </reference>

      <reference
          anchor="Dhem98"
          target="https://doi.org/10.1007/10721064_15">
       <front>
          <title>A Practical Implementation of the Timing Attack</title>
          <author fullname="Jean-François Dhem"/>
          <author fullname="François Koeune"/>
          <author fullname="Philippe-Alexandre Leroux"/>
          <author fullname="Patrick Mestré"/>
          <author fullname="Jean-Jacques Quisquater"/>
          <author fullname="Jean-Louis Willems"/>
          <date year="1998"/>
      </front>
      <seriesInfo
          name="Lecture Notes in Computer Science"
          value="vol 1820"/>
      </reference>

      <reference
          anchor="Schindler01"
          target="https://doi.org/10.1007/3-540-45325-3_22">
       <front>
           <title>Improving Divide and Conquer Attacks against Cryptosystems by Better Error Detection / Correction Strategies.</title>
           <author fullname="Werner Schindler"/>
           <author fullname="François Koeune"/>
           <author fullname="Jean-Jacques Quisquater"/>
           <date year="2001"/>
       </front>
       <seriesInfo
           name="Lecture Notes in Computer Science"
           value="vol 2260"/>
      </reference>

      <!-- attacks on RSA with CRT -->
      <reference
          anchor="Schindler00"
          target="https://doi.org/10.1007/3-540-44499-8_8">
        <front>
          <title>A Timing Attack against RSA with the Chinese Remainder Theorem</title>
          <author fullname="Werner Schindler"/>
          <date year="2000"/>
        </front>
        <seriesInfo
            name="Lecture Notes in Computer Science"
            value="vol 1965"/>
      </reference>

      <reference
          anchor="Brumley03"
          target="https://doi.org/10.1016/j.comnet.2005.01.010">
        <front>
          <title>Remote timing attacks are practical</title>
          <author fullname="David Brumley"/>
          <author fullname="Dan Boneh"/>
          <date year="2003"/>
        </front>
        <seriesInfo
            name="Computer Networks"
            value="Volume 48, Issue 5"/>
      </reference>

      <reference
          anchor="Aciicmez05"
          target="https://doi.org/10.1145/1102120.1102140">
         <front>
           <title>Improving Brumley and Boneh timing attack on unprotected SSL implementations</title>
           <author fullname="Onur Acıiçmez"/>
           <author fullname="Werner Schindler"/>
           <author fullname="Çetin K. Koç"/>
           <date year="2005"/>
        </front>
        <seriesInfo
            name="Proceedings of the 12th ACM conference on Computer and communications security"
            value="CCS '05"/>
      </reference>

      <!-- attacks against blinded implementations -->
      <reference
          anchor="Aciicmez07"
          target="https://eprint.iacr.org/2007/336">
          <front>
            <title>A Major Vulnerability in RSA Implementations due to MicroArchitectural Analysis Threat</title>
            <author fullname="Onur Acıiçmez"/>
            <author fullname="Werner Schindler"/>
            <date year="2007"/>
        </front>
        <seriesInfo
            name="Cryptology ePrint Archive"
            value="Paper 2007/336"/>
      </reference>

      <reference
          anchor="Aciicmez08"
          target="https://doi.org/10.1007/978-3-540-79263-5_16">
       <front>
          <title>A Vulnerability in RSA Implementations Due to Instruction Cache Analysis and Its Demonstration on OpenSSL</title>
          <author fullname="Onur Acıiçmez"/>
          <author fullname="Werner Schindler"/>
          <date year="2007"/>
        </front>
        <seriesInfo
            name="Lecture Notes in Computer Science"
            value="vol 4964"/>
     </reference>

     <reference
         anchor="Schindler14"
         target="https://doi.org/10.1007/s13389-014-0081-y">
       <front>
         <title>Power attacks in the presence of exponent blinding.</title>
         <author fullname="Werner Schindler"/>
         <author fullname="Andreas Wiemers"/>
         <date year="2014"/>
     </front>
     <seriesInfo
         name="Journal of Cryptographic Engineering"
         value="4"/>
     </reference>

     <!-- other -->
     <reference
         anchor="Bock18"
         target="https://www.usenix.org/conference/usenixsecurity18/presentation/bock">
       <front>
         <title>Return Of Bleichenbacher's Oracle Threat (ROBOT)</title>
         <author fullname="Hanno Böck"/>
         <author fullname="Juraj Somorovsky"/>
         <author fullname="Craig Young"/>
         <date year="2018"/>
       </front>
       <seriesInfo
           name="27th USENIX Security Symposium"
           value="USENIX Security 18"/>
      </reference>

      <reference
          anchor="Kario23"
          target="https://eprint.iacr.org/2023/1442">
        <front>
          <title>Everlasting ROBOT: the Marvin Attack</title>
          <author fullname="Hubert Kario"/>
          <date year="2023"/>
        </front>
        <seriesInfo
          name="28th European Symposium on Research in Computer Security"
          value=""/>
      </reference>

    </references>

    <section anchor="test-vectors" title="Test Vectors">
        <section title="2048 bit key">
            <t>«provide test vectors here»</t>
            <t>see also: https://github.com/tlsfuzzer/tlslite-ng/blob/master/unit_tests/test_tlslite_utils_rsakey.py#L1694 or OpenSSL 3.2.0.</t>
            <t>proposed test vectors:</t>
            <t>Otherwise valid, but with wrong first byte of plaintext</t>
            <t>Otherwise valid, but with padding type specifying signature</t>
            <t>Otherwise valid, but with PS of 7 bytes</t>
            <t>Otherwise valid, but with PS of 0 bytes</t>
            <t>Otherwise valid, but with the message separator byte missing</t>
            <t>Invalid ciphertext that decrypts to a synthehic message of
               maximum size</t>
            <t>Invalid ciphertext that decrypts to a 0-bytes long message</t>
            <t>Invalid ciphertext that needs to use the second-to-last
               synthethic length for the returned message</t>
            <t>Valid ciphertext that starts with a zero byte</t>

        </section>
        <section title="2049 bit key">
            <t>«provide test vectors here</t>
        </section>
        <section title="3072 bit key">
            <t>«provide test vectors here»</t>
        </section>
        <section title="4096 bit key">
            <t>«provide test vectors here»</t>
        </section>
    </section>

  </back>
</rfc>
