RSA.h 5.9 KB

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