xref: /aosp_15_r20/external/tink/cc/internal/rsa_util.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16 #ifndef TINK_INTERNAL_RSA_UTIL_H_
17 #define TINK_INTERNAL_RSA_UTIL_H_
18 
19 #include <stddef.h>
20 
21 #include <string>
22 
23 #include "absl/strings/string_view.h"
24 #include "openssl/bn.h"
25 #include "openssl/rsa.h"
26 #include "tink/internal/ssl_unique_ptr.h"
27 #include "tink/subtle/common_enums.h"
28 #include "tink/util/secret_data.h"
29 #include "tink/util/status.h"
30 #include "tink/util/statusor.h"
31 
32 namespace crypto {
33 namespace tink {
34 namespace internal {
35 
36 struct RsaPublicKey {
37   // Modulus.
38   // Unsigned big integer in bigendian representation.
39   std::string n;
40   // Public exponent.
41   // Unsigned big integer in bigendian representation.
42   std::string e;
43 };
44 
45 // Parameters of RSA SSA (Signature Schemes with Appendix) using  PSS
46 // (Probabilistic Signature Scheme) encoding (see
47 // https://tools.ietf.org/html/rfc8017#section-8.1).
48 struct RsaSsaPssParams {
49   // Hash function used in computing hash of the signing message
50   // (see https://tools.ietf.org/html/rfc8017#section-9.1.1).
51   subtle::HashType sig_hash;
52   // Hash function used in MGF1 (a mask generation function based on a
53   // hash function) (see https://tools.ietf.org/html/rfc8017#appendix-B.2.1).
54   subtle::HashType mgf1_hash;
55   // Salt length (see https://tools.ietf.org/html/rfc8017#section-9.1.1)
56   int salt_length;
57 };
58 
59 // Parameters of RSA SSA (Signature Schemes with Appendix) using PKCS1
60 // (Probabilistic Signature Scheme) encoding (see
61 // https://tools.ietf.org/html/rfc8017#section-8.2).
62 struct RsaSsaPkcs1Params {
63   // Hash function used in computing hash of the signing message
64   // (see https://tools.ietf.org/html/rfc8017#section-9.2).
65   subtle::HashType hash_type;
66 };
67 
68 // RSA private key representation.
69 struct RsaPrivateKey {
70   // Modulus.
71   std::string n;
72   // Public exponent.
73   std::string e;
74   // Private exponent.
75   // Unsigned big integer in bigendian representation.
76   util::SecretData d;
77 
78   // The prime factor p of n.
79   // Unsigned big integer in bigendian representation.
80   util::SecretData p;
81   // The prime factor q of n.
82   // Unsigned big integer in bigendian representation.
83   util::SecretData q;
84   // d mod (p - 1).
85   util::SecretData dp;
86   // d mod (q - 1).
87   // Unsigned big integer in bigendian representation.
88   util::SecretData dq;
89   // Chinese Remainder Theorem coefficient q^(-1) mod p.
90   // Unsigned big integer in bigendian representation.
91   util::SecretData crt;
92 };
93 
94 // Validates whether 'modulus_size' is at least 2048-bit.
95 // To reach 128-bit security strength, RSA's modulus must be at least
96 // 3072-bit while 2048-bit RSA key only has 112-bit security. Nevertheless,
97 // a 2048-bit RSA key is considered safe by NIST until 2030 (see
98 // https://www.keylength.com/en/4/).
99 crypto::tink::util::Status ValidateRsaModulusSize(size_t modulus_size);
100 
101 // Validates whether `exponent` is a valid bignum, is odd, greater than 65536
102 // and smaller than 32 bits. The primes p and q are chosen such that (p-1)(q-1)
103 // is relatively prime to the public exponent. Therefore, the public exponent
104 // must be odd. Furthermore, choosing a public exponent which is not greater
105 // than 65536 can lead to weak instantiations of RSA. A public exponent which is
106 // odd and greater than 65536 conforms to the requirements set by NIST FIPS
107 // 186-4 (Appendix B.3.1).
108 crypto::tink::util::Status ValidateRsaPublicExponent(const BIGNUM *exponent);
109 
110 // Validates whether `exponent` is a valid bignum, is odd, greater than 65536
111 // and smaller than 32 bits.
112 crypto::tink::util::Status ValidateRsaPublicExponent(
113     absl::string_view exponent);
114 
115 // Creates a new RSA key pair and populates `private_key` and `public_key`.
116 crypto::tink::util::Status NewRsaKeyPair(int modulus_size_in_bits,
117                                          const BIGNUM *e,
118                                          RsaPrivateKey *private_key,
119                                          RsaPublicKey *public_key);
120 
121 // Returns `key`'s private and public exponents (d and e) and mosulus
122 // (n) writing a copy of them into `rsa`.
123 crypto::tink::util::Status GetRsaModAndExponents(const RsaPrivateKey &key,
124                                                  RSA *rsa);
125 
126 // Returns `key`'s prime factors (p and q) writing a copy of them into `rsa`.
127 crypto::tink::util::Status GetRsaPrimeFactors(const RsaPrivateKey &key,
128                                               RSA *rsa);
129 
130 // Returns `key`'s CRT parameters (dp and dq) writing a copy of them into `rsa`.
131 crypto::tink::util::Status GetRsaCrtParams(const RsaPrivateKey &key, RSA *rsa);
132 
133 // Creates a OpenSSL/BoringSSL RSA key from `private_key`.
134 crypto::tink::util::StatusOr<internal::SslUniquePtr<RSA>> RsaPrivateKeyToRsa(
135     const RsaPrivateKey &private_key);
136 
137 // Creates a OpenSSL/BoringSSL RSA key from an `public_key`.
138 crypto::tink::util::StatusOr<internal::SslUniquePtr<RSA>> RsaPublicKeyToRsa(
139     const RsaPublicKey &public_key);
140 
141 // Performs some basic checks on the given RSA public key `key` as in [1] when
142 // OpenSSL is used as a backend. This is needed because with OpenSSL calls to
143 // RSA_check_key with RSA keys that have only the modulus and public exponent
144 // populated don't work [2]. When BoringSSL is used, it uses BoringSSL's
145 // RSA_check_key.
146 //
147 // [1] https://github.com/google/boringssl/blob/master/crypto/fipsmodule/rsa/rsa_impl.c#L76
148 // [2] https://www.openssl.org/docs/man1.1.1/man3/RSA_check_key.html
149 crypto::tink::util::Status RsaCheckPublicKey(const RSA *key);
150 
151 }  // namespace internal
152 }  // namespace tink
153 }  // namespace crypto
154 
155 #endif  // TINK_INTERNAL_RSA_UTIL_H_
156