s2n_ecdsa.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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_ecdsa.h"
  16. #include <openssl/ec.h>
  17. #include <openssl/ecdsa.h>
  18. #include <openssl/x509.h>
  19. #include "crypto/s2n_ecc_evp.h"
  20. #include "crypto/s2n_evp_signing.h"
  21. #include "crypto/s2n_hash.h"
  22. #include "crypto/s2n_openssl.h"
  23. #include "crypto/s2n_pkey.h"
  24. #include "error/s2n_errno.h"
  25. #include "stuffer/s2n_stuffer.h"
  26. #include "utils/s2n_blob.h"
  27. #include "utils/s2n_compiler.h"
  28. #include "utils/s2n_mem.h"
  29. #include "utils/s2n_random.h"
  30. #include "utils/s2n_result.h"
  31. #include "utils/s2n_safety.h"
  32. #include "utils/s2n_safety_macros.h"
  33. #define S2N_ECDSA_TYPE 0
  34. EC_KEY *s2n_unsafe_ecdsa_get_non_const(const struct s2n_ecdsa_key *ecdsa_key)
  35. {
  36. PTR_ENSURE_REF(ecdsa_key);
  37. #ifdef S2N_DIAGNOSTICS_PUSH_SUPPORTED
  38. #pragma GCC diagnostic push
  39. #pragma GCC diagnostic ignored "-Wcast-qual"
  40. #endif
  41. EC_KEY *out_ec_key = (EC_KEY *) ecdsa_key->ec_key;
  42. #ifdef S2N_DIAGNOSTICS_POP_SUPPORTED
  43. #pragma GCC diagnostic pop
  44. #endif
  45. return out_ec_key;
  46. }
  47. S2N_RESULT s2n_ecdsa_der_signature_size(const struct s2n_pkey *pkey, uint32_t *size_out)
  48. {
  49. RESULT_ENSURE_REF(pkey);
  50. RESULT_ENSURE_REF(size_out);
  51. const struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
  52. RESULT_ENSURE_REF(ecdsa_key->ec_key);
  53. const int size = ECDSA_size(ecdsa_key->ec_key);
  54. RESULT_GUARD_POSIX(size);
  55. *size_out = size;
  56. return S2N_RESULT_OK;
  57. }
  58. int s2n_ecdsa_sign_digest(const struct s2n_pkey *priv, struct s2n_blob *digest, struct s2n_blob *signature)
  59. {
  60. POSIX_ENSURE_REF(priv);
  61. POSIX_ENSURE_REF(digest);
  62. POSIX_ENSURE_REF(signature);
  63. const s2n_ecdsa_private_key *key = &priv->key.ecdsa_key;
  64. POSIX_ENSURE_REF(key->ec_key);
  65. unsigned int signature_size = signature->size;
  66. /* Safety: ECDSA_sign does not mutate the key */
  67. POSIX_GUARD_OSSL(ECDSA_sign(S2N_ECDSA_TYPE, digest->data, digest->size, signature->data, &signature_size,
  68. s2n_unsafe_ecdsa_get_non_const(key)),
  69. S2N_ERR_SIGN);
  70. POSIX_ENSURE(signature_size <= signature->size, S2N_ERR_SIZE_MISMATCH);
  71. signature->size = signature_size;
  72. return S2N_SUCCESS;
  73. }
  74. static int s2n_ecdsa_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg,
  75. struct s2n_hash_state *digest, struct s2n_blob *signature)
  76. {
  77. POSIX_ENSURE_REF(digest);
  78. sig_alg_check(sig_alg, S2N_SIGNATURE_ECDSA);
  79. uint8_t digest_length = 0;
  80. POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
  81. POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN);
  82. uint8_t digest_out[S2N_MAX_DIGEST_LEN] = { 0 };
  83. POSIX_GUARD(s2n_hash_digest(digest, digest_out, digest_length));
  84. struct s2n_blob digest_blob = { 0 };
  85. POSIX_GUARD(s2n_blob_init(&digest_blob, digest_out, digest_length));
  86. POSIX_GUARD(s2n_ecdsa_sign_digest(priv, &digest_blob, signature));
  87. POSIX_GUARD(s2n_hash_reset(digest));
  88. return S2N_SUCCESS;
  89. }
  90. static int s2n_ecdsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg,
  91. struct s2n_hash_state *digest, struct s2n_blob *signature)
  92. {
  93. sig_alg_check(sig_alg, S2N_SIGNATURE_ECDSA);
  94. const s2n_ecdsa_public_key *key = &pub->key.ecdsa_key;
  95. POSIX_ENSURE_REF(key->ec_key);
  96. uint8_t digest_length;
  97. POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
  98. POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN);
  99. uint8_t digest_out[S2N_MAX_DIGEST_LEN];
  100. POSIX_GUARD(s2n_hash_digest(digest, digest_out, digest_length));
  101. /* Safety: ECDSA_verify does not mutate the key */
  102. /* ECDSA_verify ignores the first parameter */
  103. POSIX_GUARD_OSSL(ECDSA_verify(0, digest_out, digest_length, signature->data, signature->size,
  104. s2n_unsafe_ecdsa_get_non_const(key)),
  105. S2N_ERR_VERIFY_SIGNATURE);
  106. POSIX_GUARD(s2n_hash_reset(digest));
  107. return 0;
  108. }
  109. static int s2n_ecdsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
  110. {
  111. uint8_t input[16] = { 1 };
  112. DEFER_CLEANUP(struct s2n_blob signature = { 0 }, s2n_free);
  113. DEFER_CLEANUP(struct s2n_hash_state state_in = { 0 }, s2n_hash_free);
  114. DEFER_CLEANUP(struct s2n_hash_state state_out = { 0 }, s2n_hash_free);
  115. /* s2n_hash_new only allocates memory when using high-level EVP hashes, currently restricted to FIPS mode. */
  116. POSIX_GUARD(s2n_hash_new(&state_in));
  117. POSIX_GUARD(s2n_hash_new(&state_out));
  118. POSIX_GUARD(s2n_hash_init(&state_in, S2N_HASH_SHA1));
  119. POSIX_GUARD(s2n_hash_init(&state_out, S2N_HASH_SHA1));
  120. POSIX_GUARD(s2n_hash_update(&state_in, input, sizeof(input)));
  121. POSIX_GUARD(s2n_hash_update(&state_out, input, sizeof(input)));
  122. uint32_t size = 0;
  123. POSIX_GUARD_RESULT(s2n_ecdsa_der_signature_size(priv, &size));
  124. POSIX_GUARD(s2n_alloc(&signature, size));
  125. POSIX_GUARD(s2n_ecdsa_sign(priv, S2N_SIGNATURE_ECDSA, &state_in, &signature));
  126. POSIX_GUARD(s2n_ecdsa_verify(pub, S2N_SIGNATURE_ECDSA, &state_out, &signature));
  127. return 0;
  128. }
  129. static int s2n_ecdsa_key_free(struct s2n_pkey *pkey)
  130. {
  131. POSIX_ENSURE_REF(pkey);
  132. struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
  133. if (ecdsa_key->ec_key == NULL) {
  134. return S2N_SUCCESS;
  135. }
  136. /* Safety: freeing the key owned by this object */
  137. EC_KEY_free(s2n_unsafe_ecdsa_get_non_const(ecdsa_key));
  138. ecdsa_key->ec_key = NULL;
  139. return S2N_SUCCESS;
  140. }
  141. static int s2n_ecdsa_check_key_exists(const struct s2n_pkey *pkey)
  142. {
  143. const struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
  144. POSIX_ENSURE_REF(ecdsa_key->ec_key);
  145. return 0;
  146. }
  147. int s2n_evp_pkey_to_ecdsa_private_key(s2n_ecdsa_private_key *ecdsa_key, EVP_PKEY *evp_private_key)
  148. {
  149. const EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_private_key);
  150. S2N_ERROR_IF(ec_key == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
  151. ecdsa_key->ec_key = ec_key;
  152. return 0;
  153. }
  154. int s2n_evp_pkey_to_ecdsa_public_key(s2n_ecdsa_public_key *ecdsa_key, EVP_PKEY *evp_public_key)
  155. {
  156. const EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_public_key);
  157. S2N_ERROR_IF(ec_key == NULL, S2N_ERR_DECODE_CERTIFICATE);
  158. ecdsa_key->ec_key = ec_key;
  159. return 0;
  160. }
  161. int s2n_ecdsa_pkey_init(struct s2n_pkey *pkey)
  162. {
  163. pkey->size = &s2n_ecdsa_der_signature_size;
  164. pkey->sign = &s2n_ecdsa_sign;
  165. pkey->verify = &s2n_ecdsa_verify;
  166. pkey->encrypt = NULL; /* No function for encryption */
  167. pkey->decrypt = NULL; /* No function for decryption */
  168. pkey->match = &s2n_ecdsa_keys_match;
  169. pkey->free = &s2n_ecdsa_key_free;
  170. pkey->check_key = &s2n_ecdsa_check_key_exists;
  171. POSIX_GUARD_RESULT(s2n_evp_signing_set_pkey_overrides(pkey));
  172. return 0;
  173. }
  174. int s2n_ecdsa_pkey_matches_curve(const struct s2n_ecdsa_key *ecdsa_key, const struct s2n_ecc_named_curve *curve)
  175. {
  176. POSIX_ENSURE_REF(ecdsa_key);
  177. POSIX_ENSURE_REF(ecdsa_key->ec_key);
  178. POSIX_ENSURE_REF(curve);
  179. const EC_KEY *key = ecdsa_key->ec_key;
  180. int curve_id = EC_GROUP_get_curve_name(EC_KEY_get0_group(key));
  181. POSIX_ENSURE_EQ(curve_id, curve->libcrypto_nid);
  182. return 0;
  183. }