s2n_rsa_signing.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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_signing.h"
  16. #include <openssl/evp.h>
  17. #include <openssl/rsa.h>
  18. #include "crypto/s2n_hash.h"
  19. #include "crypto/s2n_pkey.h"
  20. #include "crypto/s2n_rsa_pss.h"
  21. #include "error/s2n_errno.h"
  22. #include "stuffer/s2n_stuffer.h"
  23. #include "utils/s2n_blob.h"
  24. #include "utils/s2n_safety.h"
  25. static int s2n_hash_alg_to_NID[] = {
  26. [S2N_HASH_MD5_SHA1] = NID_md5_sha1,
  27. [S2N_HASH_SHA1] = NID_sha1,
  28. [S2N_HASH_SHA224] = NID_sha224,
  29. [S2N_HASH_SHA256] = NID_sha256,
  30. [S2N_HASH_SHA384] = NID_sha384,
  31. [S2N_HASH_SHA512] = NID_sha512
  32. };
  33. int s2n_hash_NID_type(s2n_hash_algorithm alg, int *out)
  34. {
  35. switch (alg) {
  36. case S2N_HASH_MD5_SHA1:
  37. case S2N_HASH_SHA1:
  38. case S2N_HASH_SHA224:
  39. case S2N_HASH_SHA256:
  40. case S2N_HASH_SHA384:
  41. case S2N_HASH_SHA512:
  42. *out = s2n_hash_alg_to_NID[alg];
  43. break;
  44. default:
  45. POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
  46. }
  47. return 0;
  48. }
  49. int s2n_rsa_pkcs1v15_sign_digest(const struct s2n_pkey *priv, s2n_hash_algorithm hash_alg,
  50. struct s2n_blob *digest, struct s2n_blob *signature)
  51. {
  52. POSIX_ENSURE_REF(priv);
  53. POSIX_ENSURE_REF(digest);
  54. POSIX_ENSURE_REF(signature);
  55. int NID_type = 0;
  56. POSIX_GUARD(s2n_hash_NID_type(hash_alg, &NID_type));
  57. const s2n_rsa_private_key *rsa_key = &priv->key.rsa_key;
  58. unsigned int signature_size = signature->size;
  59. /* Safety: RSA_sign does not mutate the key */
  60. POSIX_GUARD_OSSL(RSA_sign(NID_type, digest->data, digest->size, signature->data, &signature_size,
  61. s2n_unsafe_rsa_get_non_const(rsa_key)),
  62. S2N_ERR_SIGN);
  63. POSIX_ENSURE(signature_size <= signature->size, S2N_ERR_SIZE_MISMATCH);
  64. signature->size = signature_size;
  65. return S2N_SUCCESS;
  66. }
  67. int s2n_rsa_pkcs1v15_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature)
  68. {
  69. POSIX_ENSURE_REF(digest);
  70. uint8_t digest_length = 0;
  71. POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
  72. POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN);
  73. uint8_t digest_out[S2N_MAX_DIGEST_LEN] = { 0 };
  74. POSIX_GUARD(s2n_hash_digest(digest, digest_out, digest_length));
  75. struct s2n_blob digest_blob = { 0 };
  76. POSIX_GUARD(s2n_blob_init(&digest_blob, digest_out, digest_length));
  77. POSIX_GUARD(s2n_rsa_pkcs1v15_sign_digest(priv, digest->alg, &digest_blob, signature));
  78. return S2N_SUCCESS;
  79. }
  80. int s2n_rsa_pkcs1v15_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature)
  81. {
  82. uint8_t digest_length;
  83. int digest_NID_type;
  84. POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
  85. POSIX_GUARD(s2n_hash_NID_type(digest->alg, &digest_NID_type));
  86. POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN);
  87. const s2n_rsa_public_key *rsa_key = &pub->key.rsa_key;
  88. uint8_t digest_out[S2N_MAX_DIGEST_LEN];
  89. POSIX_GUARD(s2n_hash_digest(digest, digest_out, digest_length));
  90. /* Safety: RSA_verify does not mutate the key */
  91. POSIX_GUARD_OSSL(RSA_verify(digest_NID_type, digest_out, digest_length, signature->data, signature->size,
  92. s2n_unsafe_rsa_get_non_const(rsa_key)),
  93. S2N_ERR_VERIFY_SIGNATURE);
  94. return 0;
  95. }
  96. /* this function returns whether RSA PSS signing is supported */
  97. int s2n_is_rsa_pss_signing_supported()
  98. {
  99. return RSA_PSS_SIGNING_SUPPORTED;
  100. }
  101. #if RSA_PSS_SIGNING_SUPPORTED
  102. static int s2n_evp_pkey_ctx_set_rsa_signature_digest(EVP_PKEY_CTX *ctx, const EVP_MD *digest_alg)
  103. {
  104. POSIX_GUARD_OSSL(S2N_EVP_PKEY_CTX_set_signature_md(ctx, digest_alg), S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
  105. POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, (EVP_MD *) (uintptr_t) digest_alg), S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
  106. return 0;
  107. }
  108. static void s2n_evp_pkey_ctx_free(EVP_PKEY_CTX **ctx)
  109. {
  110. EVP_PKEY_CTX_free(*ctx);
  111. }
  112. int s2n_rsa_pss_sign_digest(const struct s2n_pkey *priv, s2n_hash_algorithm hash_alg,
  113. struct s2n_blob *digest_in, struct s2n_blob *signature_out)
  114. {
  115. POSIX_ENSURE_REF(priv);
  116. POSIX_ENSURE_REF(digest_in);
  117. POSIX_ENSURE_REF(signature_out);
  118. const EVP_MD *digest_alg = s2n_hash_alg_to_evp_md(hash_alg);
  119. POSIX_ENSURE_REF(digest_alg);
  120. /* For more info see: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_sign.html */
  121. DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(priv->pkey, NULL), s2n_evp_pkey_ctx_free);
  122. POSIX_ENSURE_REF(ctx);
  123. size_t signature_len = signature_out->size;
  124. POSIX_GUARD_OSSL(EVP_PKEY_sign_init(ctx), S2N_ERR_SIGN);
  125. POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_SIGN);
  126. POSIX_GUARD(s2n_evp_pkey_ctx_set_rsa_signature_digest(ctx, digest_alg));
  127. POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST), S2N_ERR_SIGN);
  128. /* Calling EVP_PKEY_sign() with NULL will only update the signature_len parameter so users can validate sizes. */
  129. POSIX_GUARD_OSSL(EVP_PKEY_sign(ctx, NULL, &signature_len, digest_in->data, digest_in->size), S2N_ERR_SIGN);
  130. POSIX_ENSURE(signature_len <= signature_out->size, S2N_ERR_SIZE_MISMATCH);
  131. /* Actually sign the digest */
  132. POSIX_GUARD_OSSL(EVP_PKEY_sign(ctx, signature_out->data, &signature_len, digest_in->data, digest_in->size), S2N_ERR_SIGN);
  133. signature_out->size = signature_len;
  134. return S2N_SUCCESS;
  135. }
  136. int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out)
  137. {
  138. POSIX_ENSURE_REF(digest);
  139. uint8_t digest_length = 0;
  140. uint8_t digest_data[S2N_MAX_DIGEST_LEN] = { 0 };
  141. POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
  142. POSIX_GUARD(s2n_hash_digest(digest, digest_data, digest_length));
  143. struct s2n_blob digest_blob = { 0 };
  144. POSIX_GUARD(s2n_blob_init(&digest_blob, digest_data, digest_length));
  145. POSIX_GUARD(s2n_rsa_pss_sign_digest(priv, digest->alg, &digest_blob, signature_out));
  146. return S2N_SUCCESS;
  147. }
  148. int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in)
  149. {
  150. POSIX_ENSURE_REF(pub);
  151. uint8_t digest_length;
  152. uint8_t digest_data[S2N_MAX_DIGEST_LEN];
  153. POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
  154. POSIX_GUARD(s2n_hash_digest(digest, digest_data, digest_length));
  155. const EVP_MD *digest_alg = s2n_hash_alg_to_evp_md(digest->alg);
  156. POSIX_ENSURE_REF(digest_alg);
  157. /* For more info see: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_verify.html */
  158. DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pub->pkey, NULL), s2n_evp_pkey_ctx_free);
  159. POSIX_ENSURE_REF(ctx);
  160. POSIX_GUARD_OSSL(EVP_PKEY_verify_init(ctx), S2N_ERR_VERIFY_SIGNATURE);
  161. POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_VERIFY_SIGNATURE);
  162. POSIX_GUARD(s2n_evp_pkey_ctx_set_rsa_signature_digest(ctx, digest_alg));
  163. POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST), S2N_ERR_VERIFY_SIGNATURE);
  164. POSIX_GUARD_OSSL(EVP_PKEY_verify(ctx, signature_in->data, signature_in->size,
  165. digest_data, digest_length),
  166. S2N_ERR_VERIFY_SIGNATURE);
  167. return S2N_SUCCESS;
  168. }
  169. #else
  170. int s2n_rsa_pss_sign_digest(const struct s2n_pkey *priv, s2n_hash_algorithm hash_alg,
  171. struct s2n_blob *digest_in, struct s2n_blob *signature_out)
  172. {
  173. POSIX_BAIL(S2N_ERR_RSA_PSS_NOT_SUPPORTED);
  174. }
  175. int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out)
  176. {
  177. POSIX_BAIL(S2N_ERR_RSA_PSS_NOT_SUPPORTED);
  178. }
  179. int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in)
  180. {
  181. POSIX_BAIL(S2N_ERR_RSA_PSS_NOT_SUPPORTED);
  182. }
  183. #endif