scclib
Stable Cloud Computing C++ Library
rsa.h
Go to the documentation of this file.
1 /*
2 BSD 3-Clause License
3 
4 Copyright (c) 2022, Stable Cloud Computing, Inc.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9 1. Redistributions of source code must retain the above copyright notice, this
10  list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright notice,
13  this list of conditions and the following disclaimer in the documentation
14  and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #ifndef _SCC_CRYPTO_RSA_H
32 #define _SCC_CRYPTO_RSA_H
33 
34 #include <string>
35 #include <vector>
36 #include <memory>
37 #include <crypto/bignum.h>
38 #include <crypto/hash.h>
39 
40 namespace scc::crypto {
41 
60 class RsaPrivateKey;
61 
69 {
70  friend class PkcsSignature;
71  friend class PssSignature;
72  friend class RsaOaepEncrypt;
73  friend class RsaPrivateKey;
74 
75 protected:
76  scc::crypto::Bignum m_n; // modulus
77  scc::crypto::Bignum m_e; // public exponent
78 
79 private:
80 
81  void move(RsaPublicKey& other)
82  {
83  m_n = std::move(other.m_n);
84  m_e = std::move(other.m_e);
85  }
86 
87  void copy(const RsaPublicKey& other)
88  {
89  m_n = other.m_n;
90  m_e = other.m_e;
91  }
92 
93 public:
94  RsaPublicKey();
95  virtual ~RsaPublicKey();
96 
98  {
99  move(other);
100  }
101  RsaPublicKey& operator=(RsaPublicKey&& other)
102  {
103  move(other);
104  return *this;
105  }
106 
107  RsaPublicKey(const RsaPublicKey& other) : RsaPublicKey()
108  {
109  copy(other);
110  }
111  RsaPublicKey& operator=(const RsaPublicKey& other)
112  {
113  copy(other);
114  return *this;
115  }
116 
117  bool operator==(const RsaPublicKey& o) const
118  {
119  return m_n == o.m_n && m_e == o.m_e;
120  }
121 
122  bool operator!=(const RsaPublicKey& o) const
123  {
124  return m_n != o.m_n || m_e != o.m_e;
125  }
126 
127  void get(scc::crypto::Bignum& n, scc::crypto::Bignum& e) const
128  {
129  n = m_n;
130  e = m_e;
131  }
132 
133  void set(const scc::crypto::Bignum& n, const scc::crypto::Bignum& e)
134  {
135  m_n = n;
136  m_e = e;
137  }
138 
140  void clear();
141 
143  std::string dump() const;
144 
146  std::string str(unsigned = 8) const;
147 
149  int width() const;
150 
152  int width_bytes() const
153  {
154  return ((width()+7)&~7)/8;
155  }
156 };
157 
185 {
186  friend class PssSignature;
187  friend class PkcsSignature;
188  friend class RsaOaepDecrypt;
189 
190  scc::crypto::Bignum m_d; // private exponent
191  scc::crypto::Bignum m_p; // prime 1
192  scc::crypto::Bignum m_q; // prime 2
193  scc::crypto::Bignum m_ep; // exponent 1
194  scc::crypto::Bignum m_eq; // exponent 2
195  scc::crypto::Bignum m_qinv; // inverse coefficient
196 
197  void move(RsaPrivateKey& other)
198  {
199  m_n = std::move(other.m_n);
200  m_e = std::move(other.m_e);
201  m_d = std::move(other.m_d);
202  m_p = std::move(other.m_p);
203  m_q = std::move(other.m_q);
204  m_ep = std::move(other.m_ep);
205  m_eq = std::move(other.m_eq);
206  m_qinv = std::move(other.m_qinv);
207  }
208 
209  void copy(const RsaPrivateKey& other)
210  {
211  m_n = other.m_n;
212  m_e = other.m_e;
213  m_d = other.m_d;
214  m_p = other.m_p;
215  m_q = other.m_q;
216  m_ep = other.m_ep;
217  m_eq = other.m_eq;
218  m_qinv = other.m_qinv;
219  }
220 
221 public:
222  RsaPrivateKey();
223  virtual ~RsaPrivateKey();
224 
226  {
227  move(other);
228  }
229  RsaPrivateKey& operator=(RsaPrivateKey&& other)
230  {
231  move(other);
232  return *this;
233  }
234 
235  RsaPrivateKey(const RsaPrivateKey& other) : RsaPrivateKey()
236  {
237  copy(other);
238  }
239  RsaPrivateKey& operator=(const RsaPrivateKey& other)
240  {
241  copy(other);
242  return *this;
243  }
244 
245  bool operator==(const RsaPrivateKey& o) const
246  {
247  return m_n == o.m_n && m_e == o.m_e && m_d == o.m_d && m_p == o.m_p && m_q == o.m_q && m_ep == o.m_ep && m_eq == o.m_eq && m_qinv == o.m_qinv;
248  }
249 
250  bool operator!=(const RsaPrivateKey& o) const
251  {
252  return m_n != o.m_n || m_e != o.m_e || m_d != o.m_d || m_p != o.m_p || m_q != o.m_q || m_ep != o.m_ep || m_eq != o.m_eq || m_qinv != o.m_qinv;
253  }
254 
256  void clear();
257 
259  std::string dump() const;
260 
262  std::string str(unsigned = 8) const;
263 
272  void generate(int);
273 
276  bool validate(const RsaPublicKey&) const;
277 
280  bool validate() const
281  {
282  return validate(pub_key());
283  }
284 
288  {
289  n = m_n;
290  e = m_e;
291  d = m_d;
292  p = m_p;
293  q = m_q;
294  ep = m_ep;
295  eq = m_eq;
296  qinv = m_qinv;
297  }
298 
299  void set(const scc::crypto::Bignum& n, const scc::crypto::Bignum& e,
302  {
303  m_n = n;
304  m_e = e;
305  m_d = d;
306  m_p = p;
307  m_q = q;
308  m_ep = ep;
309  m_eq = eq;
310  m_qinv = qinv;
311  }
312 
315  {
316  RsaPublicKey pub;
317  pub.set(m_n, m_e);
318  return pub;
319  }
320 };
321 
322 struct RsaOaepEncryptCtx;
323 
329 {
330  std::unique_ptr<RsaOaepEncryptCtx> m_ctx;
331 
332 public:
338  virtual ~RsaOaepEncrypt();
343  int max_msg_size() const;
348  int cipher_size() const;
349 
361  void encrypt(const void*, int, void*, int, const void* = nullptr, int = 0);
362 };
363 
364 struct RsaOaepDecryptCtx;
365 
373 {
374  std::unique_ptr<RsaOaepDecryptCtx> m_ctx;
375 
376 public:
383  virtual ~RsaOaepDecrypt();
388  int max_msg_size() const;
393  int cipher_size() const;
394 
405  int decrypt(void*, int, const void*, int, const void* = nullptr, int = 0);
406 };
407 
416 {
417 public:
418  enum class HashType
419  {
420  md5,
421  sha1,
422  sha224,
423  sha256,
424  sha384,
425  sha512,
426  };
429  static int size(const RsaPublicKey& k)
430  {
431  return k.width_bytes();
432  }
433 
450  static void sign(const void*, int, void*, int, const RsaPrivateKey&, PssSignature::HashType, int = 0);
451  static void sign(const void* loc, int len, std::vector<char>& sig, const RsaPrivateKey& key, PssSignature::HashType hash, int salt_len = 0)
452  {
453  sig.resize(size(key));
454  sign(loc, len, sig.data(), sig.size(), key, hash, salt_len);
455  }
456 
468  static bool verify(const void*, int, const void*, int, const RsaPublicKey&, PssSignature::HashType);
469  static bool verify(const void* loc, int len, const std::vector<char>& sig, const RsaPublicKey& key, PssSignature::HashType hash)
470  {
471  return verify(loc, len, sig.data(), sig.size(), key, hash);
472  }
473 };
474 
483 {
484 public:
485  enum class HashType
486  {
487  md5,
488  sha1,
489  sha224,
490  sha256,
491  sha384,
492  sha512,
493  };
494 
497  static int size(const RsaPublicKey& k)
498  {
499  return k.width_bytes();
500  }
501 
514  static void sign(const void*, int, void*, int, const RsaPrivateKey&, PkcsSignature::HashType);
515  static void sign(const void* loc, int len, std::vector<char>& sig, const RsaPrivateKey& key, PkcsSignature::HashType hash)
516  {
517  sig.resize(size(key));
518  sign(loc, len, sig.data(), sig.size(), key, hash);
519  }
520  static void sign(const void* loc, int len, std::vector<uint8_t>& sig, const RsaPrivateKey& key, PkcsSignature::HashType hash)
521  {
522  sig.resize(size(key));
523  sign(loc, len, sig.data(), sig.size(), key, hash);
524  }
525 
537  static bool verify(const void*, int, const void*, int, const RsaPublicKey&, PkcsSignature::HashType);
538  static bool verify(const void* loc, int len, const std::vector<char>& sig, const RsaPublicKey& key, PkcsSignature::HashType hash)
539  {
540  return verify(loc, len, sig.data(), sig.size(), key, hash);
541  }
542 };
543 
547 } // namespace
548 
549 #endif
Big number arithmetic.
Big number.
Definition: bignum.h:59
Algorithm
Hash type.
Definition: hash.h:92
PKCS #1 version 1.5 digital signature.
Definition: rsa.h:483
static void sign(const void *, int, void *, int, const RsaPrivateKey &, PkcsSignature::HashType)
Sign the signature using a private key.
static int size(const RsaPublicKey &k)
Size of signature in bytes.
Definition: rsa.h:497
static bool verify(const void *, int, const void *, int, const RsaPublicKey &, PkcsSignature::HashType)
Verify the signature using a public key.
RSASSA-PSS https://tools.ietf.org/html/rfc8017#section-8.1 Notes on use in x.509: https://tools....
Definition: rsa.h:416
static bool verify(const void *, int, const void *, int, const RsaPublicKey &, PssSignature::HashType)
Verify the signature using a public key.
static int size(const RsaPublicKey &k)
Size of signature in bytes.
Definition: rsa.h:429
static void sign(const void *, int, void *, int, const RsaPrivateKey &, PssSignature::HashType, int=0)
Sign the signature using a private key.
RSA OAEP decryption.
Definition: rsa.h:373
int decrypt(void *, int, const void *, int, const void *=nullptr, int=0)
Decrypt a message.
int cipher_size() const
Cipher text length in bytes.
int max_msg_size() const
The maximum allowable plain text message length in bytes.
RsaOaepDecrypt(RsaPrivateKey &, Hash::Algorithm=Hash::sha1_type)
Construct an RSA decryptor.
RSA OAEP encryption.
Definition: rsa.h:329
int cipher_size() const
Cipher text size in bytes.
RsaOaepEncrypt(RsaPublicKey &, Hash::Algorithm=Hash::sha1_type)
Construct an RSA encryptor.
int max_msg_size() const
The maximum allowable plain text size in bytes.
void encrypt(const void *, int, void *, int, const void *=nullptr, int=0)
Encrypt a message.
RSA Private Key.
Definition: rsa.h:185
bool validate(const RsaPublicKey &) const
Validate a public key with the private key.
std::string dump() const
Dump a string with full values.
void clear()
Clear and erase all data.
bool validate() const
Validate with my public key.
Definition: rsa.h:280
std::string str(unsigned=8) const
Output with formatted values.
void generate(int)
Generate a private key.
RsaPublicKey pub_key() const
Export the public key.
Definition: rsa.h:314
RSA Public Key.
Definition: rsa.h:69
int width() const
Bit width of the key.
std::string dump() const
Output with full values.
int width_bytes() const
Width in bytes of this key.
Definition: rsa.h:152
std::string str(unsigned=8) const
Output with formatted values.
void clear()
Clear and erase all data.
One-way hashing and message digests.