Internet-Draft | RSA Implementation Guidance | October 2023 |
Kario | Expires 11 April 2024 | [Page] |
This document specifies additions and amendments to RFC 8017. Specifically, it provides guidence to implementers of the standard to protect against side-channel attacks. It also deprecates the PKCS #1 v1.5 encryption padding, 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.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 11 April 2024.¶
Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The PKCS #1 [RFC8017] specification describes the RSA cryptosystem, providing guidance on implementing encryption schemes and signature schemes.¶
Unfortunately, typical uses of RSA encryption schemes leave it vulnerable to side-channel attacks. Protections against them are not documented there, and attacks are mentioned only in passing.¶
The PKCS #1 v1.5 padding is known to be problematic since 1998, when Daniel Bleichenbacher published his attack. Side-channel attacks against public key implementations, including RSA, are known to be possible since 1996 thanks to work by Paul Kocher. Despite those results, side-channel attacks against RSA implementations have proliferated for the next 25 years.¶
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.¶
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 RFC 2119 [RFC2119].¶
In this document we reuse the notation from RFC 8017, in addition, we define the following:¶
alternative message length, non-negative integer, 0 <= AL <= k - 11¶
alternative encoded message, an octet string¶
octet string representation of d¶
an octet string of a SHA-256 hash of D¶
an octet string containg a Key Derivation Key for a specific ciphertext C¶
length in octets of the message M¶
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:¶
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.¶
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.¶
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 if architecture dependant, but division is commonly non-constant time).¶
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.¶
All operations that use private keys SHOULD additionally employ both base blinding and exponent blinding as protections against leaks inside modular exponentiation code.¶
The underlying modular exponentiation algorithm MUST be constant time with regards to the exponent in all uses of the private key.¶
For private key decryption the modular exponentiation algorithm MUST be constant time with regards to the output of the exponentiation.¶
In case the Chinese remainder theorem optimisation is used the modular exponentiation algorithm must also be constant time with regards to the used moduli.¶
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.¶
For example, the private exponenents should be stored in memory buffers that have sizes determined by the public modulus value, not the numerical values of the exponents themselves.¶
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.¶
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.¶
The recommended workaround against it, is the use of the Montgomery ladder construction.¶
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.¶
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.¶
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.¶
As protection against multiple attacks, it's RECOMMENDED to perform all operations involving the private key with the use of blinding.¶
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.¶
«describe the base blinding use»¶
Unless the multiplication and reduction modulo operations are verified to be side-channel free, it's RECOMMENDED to generate a completely new blinding parameters every few hundred private key operations.¶
To further protect against private key leaks, it's RECOMMENDED to perform the blinding of the used exponents.¶
«describe the exponent blinding algorithm here»¶
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.¶
It MUST ignore the value of the very fist octet of padding and process the remaining bytes as if it was equal zero.¶
The PKCS #1 v1.5 padding 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.¶
For the calculation of the random message for implicit rejection we define a Pseudo-Random Function (PRF) as follows:¶
IRPRF( KDK, label, length )¶
Input:¶
KDK the key derivation key¶
label a label making the output unique for a given KDK¶
length requested length of output in octets¶
Output: derived key, an octet string¶
Steps:¶
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:¶
P_i = I || label || bitLength¶
For implementations that cannot remove support for the PKCS #1 v1.5 padding 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 is hard, thus it's RECOMMENDED instead to disable support for PKCS #1 v1.5 padding instead.¶
To implement implicit rejection, the RSAES-PKCS1-V1_5-DECRYPT from section 7.2.2 of RFC 8017 needs to be implemented as follows:¶
RSA decryption:¶
Convert the ciphertext C to an integer ciphertext representative c:¶
c = OS2IP (C).¶
Apply the RSADP decryption primitive to the RSA private key (n, d) and the ciphertext representative c to produce an integer message representative m:¶
m = RSADP ((n, d), c).¶
Note: the RSADP MUST be constant-time with respect of message m.¶
If RSADP outputs "ciphertext representative out of range" (meaning that c >= n), output "decryption error" and stop.¶
Convert the message representative m to an encoded message EM of length k octets:¶
EM = I2OSP (m, k).¶
Note: I2OSP MUST be constant-time with respect of m.¶
Derivation of alternative message¶
Derive the Key Derivation Key (KDK)¶
Convert the private expoent d to a string of length k octets:¶
D = I2OSP (d, k).¶
Hash the private exponent using the SHA-256 algorithm:¶
DH = SHA256 (D).¶
Note: This value MAY be cached between the decryption operations, but MUST be considered private-key equivalent.¶
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.¶
KDK = HMAC (DH, C, SHA256).¶
Create the candidate lengths and the random message¶
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.¶
CL = IRPRF (KDK, "length", 256).¶
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:¶
AM = IRPRF (KDK, "message", k).¶
Select the alternative length for the alternative message.¶
Note: this must be performed in side-channel free way.¶
EME-PKCS1-v1_5 decoding: Separate the encoded message EM into an octet string PS consisting of nonzero octets and a message M as¶
EM = 0x00 || 0x02 || PS || 0x00 || M.¶
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.¶
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.¶
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.¶
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.¶
Current protocols deployments MUST NOT use encryption with RSA PKCS #1 v1.5 padding. Support for RSA PKCS #1 v1.5 SHOULD be disabled in default configuration of any implementation of RSA cryptosystem. All new protocols MUST NOT specify PKCS #1 v1.5 as a valid encryption padding for RSA keys.¶
This memo includes no request to IANA.¶
This whole document specifies security considerations for RSA implementations.¶
«provide test vectors here»¶