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