RSA.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Span.h>
  9. #include <LibCrypto/BigInt/UnsignedBigInteger.h>
  10. #include <LibCrypto/NumberTheory/ModularFunctions.h>
  11. #include <LibCrypto/PK/Code/EMSA_PSS.h>
  12. #include <LibCrypto/PK/PK.h>
  13. namespace Crypto::PK {
  14. template<typename Integer = UnsignedBigInteger>
  15. class RSAPublicKey {
  16. public:
  17. RSAPublicKey(Integer n, Integer e)
  18. : m_modulus(move(n))
  19. , m_public_exponent(move(e))
  20. , m_length(m_modulus.trimmed_length() * sizeof(u32))
  21. {
  22. }
  23. RSAPublicKey()
  24. : m_modulus(0)
  25. , m_public_exponent(0)
  26. {
  27. }
  28. Integer const& modulus() const { return m_modulus; }
  29. Integer const& public_exponent() const { return m_public_exponent; }
  30. size_t length() const { return m_length; }
  31. void set_length(size_t length) { m_length = length; }
  32. void set(Integer n, Integer e)
  33. {
  34. m_modulus = move(n);
  35. m_public_exponent = move(e);
  36. m_length = (m_modulus.trimmed_length() * sizeof(u32));
  37. }
  38. private:
  39. Integer m_modulus;
  40. Integer m_public_exponent;
  41. size_t m_length { 0 };
  42. };
  43. template<typename Integer = UnsignedBigInteger>
  44. class RSAPrivateKey {
  45. public:
  46. RSAPrivateKey(Integer n, Integer d, Integer e)
  47. : m_modulus(move(n))
  48. , m_private_exponent(move(d))
  49. , m_public_exponent(move(e))
  50. , m_length(m_modulus.trimmed_length() * sizeof(u32))
  51. {
  52. }
  53. RSAPrivateKey() = default;
  54. Integer const& modulus() const { return m_modulus; }
  55. Integer const& private_exponent() const { return m_private_exponent; }
  56. Integer const& public_exponent() const { return m_public_exponent; }
  57. size_t length() const { return m_length; }
  58. void set_length(size_t length) { m_length = length; }
  59. void set(Integer n, Integer d, Integer e)
  60. {
  61. m_modulus = move(n);
  62. m_private_exponent = move(d);
  63. m_public_exponent = move(e);
  64. m_length = m_modulus.trimmed_length() * sizeof(u32);
  65. }
  66. private:
  67. Integer m_modulus;
  68. Integer m_private_exponent;
  69. Integer m_public_exponent;
  70. size_t m_length { 0 };
  71. };
  72. template<typename PubKey, typename PrivKey>
  73. struct RSAKeyPair {
  74. PubKey public_key;
  75. PrivKey private_key;
  76. };
  77. using IntegerType = UnsignedBigInteger;
  78. class RSA : public PKSystem<RSAPrivateKey<IntegerType>, RSAPublicKey<IntegerType>> {
  79. template<typename T>
  80. friend class RSA_EMSA_PSS;
  81. public:
  82. using KeyPairType = RSAKeyPair<PublicKeyType, PrivateKeyType>;
  83. static KeyPairType parse_rsa_key(ReadonlyBytes der);
  84. static KeyPairType generate_key_pair(size_t bits = 256)
  85. {
  86. IntegerType e { 65537 }; // :P
  87. IntegerType p, q;
  88. IntegerType lambda;
  89. do {
  90. p = NumberTheory::random_big_prime(bits / 2);
  91. q = NumberTheory::random_big_prime(bits / 2);
  92. lambda = NumberTheory::LCM(p.minus(1), q.minus(1));
  93. dbgln("checking combination p={}, q={}, lambda={}", p, q, lambda.length());
  94. } while (!(NumberTheory::GCD(e, lambda) == 1));
  95. auto n = p.multiplied_by(q);
  96. auto d = NumberTheory::ModularInverse(e, lambda);
  97. dbgln("Your keys are Pub(n={}, e={}) and Priv(n={}, d={})", n, e, n, d);
  98. RSAKeyPair<PublicKeyType, PrivateKeyType> keys {
  99. { n, e },
  100. { n, d, e }
  101. };
  102. keys.public_key.set_length(bits / 2 / 8);
  103. keys.private_key.set_length(bits / 2 / 8);
  104. return keys;
  105. }
  106. RSA(IntegerType n, IntegerType d, IntegerType e)
  107. {
  108. m_public_key.set(n, e);
  109. m_private_key.set(n, d, e);
  110. }
  111. RSA(PublicKeyType& pubkey, PrivateKeyType& privkey)
  112. : PKSystem<RSAPrivateKey<IntegerType>, RSAPublicKey<IntegerType>>(pubkey, privkey)
  113. {
  114. }
  115. RSA(ByteBuffer const& publicKeyPEM, ByteBuffer const& privateKeyPEM)
  116. {
  117. import_public_key(publicKeyPEM);
  118. import_private_key(privateKeyPEM);
  119. }
  120. RSA(StringView privKeyPEM)
  121. {
  122. import_private_key(privKeyPEM.bytes());
  123. m_public_key.set(m_private_key.modulus(), m_private_key.public_exponent());
  124. }
  125. // create our own keys
  126. RSA()
  127. {
  128. auto pair = generate_key_pair();
  129. m_public_key = pair.public_key;
  130. m_private_key = pair.private_key;
  131. }
  132. virtual void encrypt(ReadonlyBytes in, Bytes& out) override;
  133. virtual void decrypt(ReadonlyBytes in, Bytes& out) override;
  134. virtual void sign(ReadonlyBytes in, Bytes& out) override;
  135. virtual void verify(ReadonlyBytes in, Bytes& out) override;
  136. #ifndef KERNEL
  137. virtual ByteString class_name() const override
  138. {
  139. return "RSA";
  140. }
  141. #endif
  142. virtual size_t output_size() const override
  143. {
  144. return m_public_key.length();
  145. }
  146. void import_public_key(ReadonlyBytes, bool pem = true);
  147. void import_private_key(ReadonlyBytes, bool pem = true);
  148. PrivateKeyType const& private_key() const { return m_private_key; }
  149. PublicKeyType const& public_key() const { return m_public_key; }
  150. };
  151. template<typename HashFunction>
  152. class RSA_EMSA_PSS {
  153. public:
  154. RSA_EMSA_PSS(RSA& rsa)
  155. : m_rsa(rsa)
  156. {
  157. }
  158. void sign(ReadonlyBytes in, Bytes& out);
  159. VerificationConsistency verify(ReadonlyBytes in);
  160. private:
  161. EMSA_PSS<HashFunction, HashFunction::DigestSize> m_emsa_pss;
  162. RSA m_rsa;
  163. };
  164. class RSA_PKCS1_EME : public RSA {
  165. public:
  166. // forward all constructions to RSA
  167. template<typename... Args>
  168. RSA_PKCS1_EME(Args... args)
  169. : RSA(args...)
  170. {
  171. }
  172. ~RSA_PKCS1_EME() = default;
  173. virtual void encrypt(ReadonlyBytes in, Bytes& out) override;
  174. virtual void decrypt(ReadonlyBytes in, Bytes& out) override;
  175. virtual void sign(ReadonlyBytes, Bytes&) override;
  176. virtual void verify(ReadonlyBytes, Bytes&) override;
  177. #ifndef KERNEL
  178. virtual ByteString class_name() const override
  179. {
  180. return "RSA_PKCS1-EME";
  181. }
  182. #endif
  183. virtual size_t output_size() const override
  184. {
  185. return m_public_key.length();
  186. }
  187. };
  188. }