s2n_rsa_pss.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #include "crypto/s2n_rsa_pss.h"
  16. #include <openssl/evp.h>
  17. #include <openssl/rsa.h>
  18. #include <stdint.h>
  19. #include "crypto/s2n_evp_signing.h"
  20. #include "crypto/s2n_hash.h"
  21. #include "crypto/s2n_openssl.h"
  22. #include "crypto/s2n_pkey.h"
  23. #include "crypto/s2n_rsa.h"
  24. #include "crypto/s2n_rsa_signing.h"
  25. #include "error/s2n_errno.h"
  26. #include "stuffer/s2n_stuffer.h"
  27. #include "utils/s2n_blob.h"
  28. #include "utils/s2n_random.h"
  29. #include "utils/s2n_safety.h"
  30. /* Checks whether PSS Certs is supported */
  31. int s2n_is_rsa_pss_certs_supported()
  32. {
  33. return RSA_PSS_CERTS_SUPPORTED;
  34. }
  35. #if RSA_PSS_CERTS_SUPPORTED
  36. static S2N_RESULT s2n_rsa_pss_size(const struct s2n_pkey *key, uint32_t *size_out)
  37. {
  38. RESULT_ENSURE_REF(key);
  39. RESULT_ENSURE_REF(size_out);
  40. /* For more info, see: https://www.openssl.org/docs/man1.1.0/man3/EVP_PKEY_size.html */
  41. const int size = EVP_PKEY_size(key->pkey);
  42. RESULT_GUARD_POSIX(size);
  43. *size_out = size;
  44. return S2N_RESULT_OK;
  45. }
  46. static int s2n_rsa_is_private_key(const RSA *rsa_key)
  47. {
  48. const BIGNUM *d = NULL;
  49. RSA_get0_key(rsa_key, NULL, NULL, &d);
  50. if (d != NULL) {
  51. return 1;
  52. }
  53. return 0;
  54. }
  55. int s2n_rsa_pss_key_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg,
  56. struct s2n_hash_state *digest, struct s2n_blob *signature_out)
  57. {
  58. POSIX_ENSURE_REF(priv);
  59. sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
  60. /* Not Possible to Sign with Public Key */
  61. const RSA *key = priv->key.rsa_key.rsa;
  62. POSIX_ENSURE(s2n_rsa_is_private_key(key), S2N_ERR_KEY_MISMATCH);
  63. return s2n_rsa_pss_sign(priv, digest, signature_out);
  64. }
  65. int s2n_rsa_pss_key_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg,
  66. struct s2n_hash_state *digest, struct s2n_blob *signature_in)
  67. {
  68. POSIX_ENSURE_REF(pub);
  69. sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
  70. /* Using Private Key to Verify means the public/private keys were likely swapped, and likely indicates a bug. */
  71. const RSA *key = pub->key.rsa_key.rsa;
  72. POSIX_ENSURE(!s2n_rsa_is_private_key(key), S2N_ERR_KEY_MISMATCH);
  73. return s2n_rsa_pss_verify(pub, digest, signature_in);
  74. }
  75. static int s2n_rsa_pss_validate_sign_verify_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
  76. {
  77. /* Generate a random blob to sign and verify */
  78. s2n_stack_blob(random_data, RSA_PSS_SIGN_VERIFY_RANDOM_BLOB_SIZE, RSA_PSS_SIGN_VERIFY_RANDOM_BLOB_SIZE);
  79. POSIX_GUARD_RESULT(s2n_get_private_random_data(&random_data));
  80. /* Sign/Verify API's only accept Hashes, so hash our Random Data */
  81. DEFER_CLEANUP(struct s2n_hash_state sign_hash = { 0 }, s2n_hash_free);
  82. DEFER_CLEANUP(struct s2n_hash_state verify_hash = { 0 }, s2n_hash_free);
  83. POSIX_GUARD(s2n_hash_new(&sign_hash));
  84. POSIX_GUARD(s2n_hash_new(&verify_hash));
  85. POSIX_GUARD(s2n_hash_init(&sign_hash, S2N_HASH_SHA256));
  86. POSIX_GUARD(s2n_hash_init(&verify_hash, S2N_HASH_SHA256));
  87. POSIX_GUARD(s2n_hash_update(&sign_hash, random_data.data, random_data.size));
  88. POSIX_GUARD(s2n_hash_update(&verify_hash, random_data.data, random_data.size));
  89. /* Sign and Verify the Hash of the Random Blob */
  90. s2n_stack_blob(signature_data, RSA_PSS_SIGN_VERIFY_SIGNATURE_SIZE, RSA_PSS_SIGN_VERIFY_SIGNATURE_SIZE);
  91. POSIX_GUARD(s2n_rsa_pss_key_sign(priv, S2N_SIGNATURE_RSA_PSS_PSS, &sign_hash, &signature_data));
  92. POSIX_GUARD(s2n_rsa_pss_key_verify(pub, S2N_SIGNATURE_RSA_PSS_PSS, &verify_hash, &signature_data));
  93. return 0;
  94. }
  95. static int s2n_rsa_validate_params_equal(const RSA *pub, const RSA *priv)
  96. {
  97. const BIGNUM *pub_val_e = NULL;
  98. const BIGNUM *pub_val_n = NULL;
  99. RSA_get0_key(pub, &pub_val_n, &pub_val_e, NULL);
  100. const BIGNUM *priv_val_e = NULL;
  101. const BIGNUM *priv_val_n = NULL;
  102. RSA_get0_key(priv, &priv_val_n, &priv_val_e, NULL);
  103. if (pub_val_e == NULL || priv_val_e == NULL) {
  104. POSIX_BAIL(S2N_ERR_KEY_CHECK);
  105. }
  106. if (pub_val_n == NULL || priv_val_n == NULL) {
  107. POSIX_BAIL(S2N_ERR_KEY_CHECK);
  108. }
  109. S2N_ERROR_IF(BN_cmp(pub_val_e, priv_val_e) != 0, S2N_ERR_KEY_MISMATCH);
  110. S2N_ERROR_IF(BN_cmp(pub_val_n, priv_val_n) != 0, S2N_ERR_KEY_MISMATCH);
  111. return 0;
  112. }
  113. static int s2n_rsa_validate_params_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
  114. {
  115. POSIX_ENSURE_REF(pub);
  116. POSIX_ENSURE_REF(priv);
  117. /* OpenSSL Documentation Links:
  118. * - https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_get1_RSA.html
  119. * - https://www.openssl.org/docs/manmaster/man3/RSA_get0_key.html
  120. */
  121. const RSA *pub_rsa_key = pub->key.rsa_key.rsa;
  122. const RSA *priv_rsa_key = priv->key.rsa_key.rsa;
  123. POSIX_ENSURE_REF(pub_rsa_key);
  124. POSIX_ENSURE_REF(priv_rsa_key);
  125. POSIX_GUARD(s2n_rsa_validate_params_equal(pub_rsa_key, priv_rsa_key));
  126. return 0;
  127. }
  128. static int s2n_rsa_pss_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
  129. {
  130. POSIX_ENSURE_REF(pub);
  131. POSIX_ENSURE_REF(pub->pkey);
  132. POSIX_ENSURE_REF(priv);
  133. POSIX_ENSURE_REF(priv->pkey);
  134. POSIX_GUARD(s2n_rsa_validate_params_match(pub, priv));
  135. /* Validate that verify(sign(message)) for a random message is verified correctly */
  136. POSIX_GUARD(s2n_rsa_pss_validate_sign_verify_match(pub, priv));
  137. return 0;
  138. }
  139. static int s2n_rsa_pss_key_free(struct s2n_pkey *pkey)
  140. {
  141. POSIX_ENSURE_REF(pkey);
  142. struct s2n_rsa_key *rsa_key = &pkey->key.rsa_key;
  143. if (rsa_key->rsa == NULL) {
  144. return S2N_SUCCESS;
  145. }
  146. /* Safety: freeing the key owned by this object */
  147. RSA_free(s2n_unsafe_rsa_get_non_const(rsa_key));
  148. rsa_key->rsa = NULL;
  149. return S2N_SUCCESS;
  150. }
  151. int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey)
  152. {
  153. const RSA *pub_rsa_key = EVP_PKEY_get1_RSA(pkey);
  154. POSIX_ENSURE_REF(pub_rsa_key);
  155. S2N_ERROR_IF(s2n_rsa_is_private_key(pub_rsa_key), S2N_ERR_KEY_MISMATCH);
  156. rsa_key->rsa = pub_rsa_key;
  157. return 0;
  158. }
  159. int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey)
  160. {
  161. const RSA *priv_rsa_key = EVP_PKEY_get1_RSA(pkey);
  162. POSIX_ENSURE_REF(priv_rsa_key);
  163. /* Documentation: https://www.openssl.org/docs/man1.1.1/man3/RSA_check_key.html */
  164. S2N_ERROR_IF(!s2n_rsa_is_private_key(priv_rsa_key), S2N_ERR_KEY_MISMATCH);
  165. /* Check that the mandatory properties of a RSA Private Key are valid.
  166. * - Documentation: https://www.openssl.org/docs/man1.1.1/man3/RSA_check_key.html
  167. */
  168. POSIX_GUARD_OSSL(RSA_check_key(priv_rsa_key), S2N_ERR_KEY_CHECK);
  169. rsa_key->rsa = priv_rsa_key;
  170. return 0;
  171. }
  172. int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey)
  173. {
  174. POSIX_GUARD(s2n_rsa_pkey_init(pkey));
  175. pkey->size = &s2n_rsa_pss_size;
  176. pkey->sign = &s2n_rsa_pss_key_sign;
  177. pkey->verify = &s2n_rsa_pss_key_verify;
  178. /* RSA PSS only supports Sign and Verify.
  179. * RSA PSS should never be used for Key Exchange. ECDHE should be used instead since it provides Forward Secrecy. */
  180. pkey->encrypt = NULL; /* No function for encryption */
  181. pkey->decrypt = NULL; /* No function for decryption */
  182. pkey->match = &s2n_rsa_pss_keys_match;
  183. pkey->free = &s2n_rsa_pss_key_free;
  184. POSIX_GUARD_RESULT(s2n_evp_signing_set_pkey_overrides(pkey));
  185. return 0;
  186. }
  187. #else
  188. int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_pss_key, EVP_PKEY *pkey)
  189. {
  190. POSIX_BAIL(S2N_ERR_RSA_PSS_NOT_SUPPORTED);
  191. }
  192. int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_pss_key, EVP_PKEY *pkey)
  193. {
  194. POSIX_BAIL(S2N_ERR_RSA_PSS_NOT_SUPPORTED);
  195. }
  196. int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey)
  197. {
  198. POSIX_BAIL(S2N_ERR_RSA_PSS_NOT_SUPPORTED);
  199. }
  200. #endif