-
Notifications
You must be signed in to change notification settings - Fork 722
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use libcrypto signing methods in compliance with FIPS 140-3 (#3142)
- Loading branch information
Showing
16 changed files
with
544 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
#include "error/s2n_errno.h" | ||
|
||
#include "crypto/s2n_evp.h" | ||
#include "crypto/s2n_evp_signing.h" | ||
#include "crypto/s2n_pkey.h" | ||
#include "crypto/s2n_rsa_pss.h" | ||
|
||
#include "utils/s2n_safety.h" | ||
|
||
/* | ||
* FIPS 140-3 requires that we don't pass raw digest bytes to the libcrypto signing methods. | ||
* In order to do that, we need to use signing methods that both calculate the digest and | ||
* perform the signature. | ||
*/ | ||
|
||
static S2N_RESULT s2n_evp_md_ctx_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) | ||
{ | ||
#ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX | ||
EVP_MD_CTX_set_pkey_ctx(ctx, pctx); | ||
return S2N_RESULT_OK; | ||
#else | ||
RESULT_BAIL(S2N_ERR_UNIMPLEMENTED); | ||
#endif | ||
} | ||
|
||
static S2N_RESULT s2n_evp_pkey_set_rsa_pss_saltlen(EVP_PKEY_CTX *pctx) | ||
{ | ||
#if RSA_PSS_SIGNING_SUPPORTED | ||
RESULT_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, RSA_PSS_SALTLEN_DIGEST), S2N_ERR_PKEY_CTX_INIT); | ||
return S2N_RESULT_OK; | ||
#else | ||
RESULT_BAIL(S2N_ERR_UNIMPLEMENTED); | ||
#endif | ||
} | ||
|
||
bool s2n_evp_signing_supported() | ||
{ | ||
#ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX | ||
/* We can only use EVP signing if the hash state has an EVP_MD_CTX | ||
* that we can pass to the EVP signing methods. | ||
*/ | ||
return s2n_hash_evp_fully_supported(); | ||
#else | ||
return false; | ||
#endif | ||
} | ||
|
||
/* If using EVP signing, override the sign and verify pkey methods. | ||
* The EVP methods can handle all pkey types / signature algorithms. | ||
*/ | ||
S2N_RESULT s2n_evp_signing_set_pkey_overrides(struct s2n_pkey *pkey) | ||
{ | ||
if (s2n_evp_signing_supported()) { | ||
RESULT_ENSURE_REF(pkey); | ||
pkey->sign = &s2n_evp_sign; | ||
pkey->verify = &s2n_evp_verify; | ||
} | ||
return S2N_RESULT_OK; | ||
} | ||
|
||
static S2N_RESULT s2n_evp_signing_validate_hash_alg(s2n_signature_algorithm sig_alg, s2n_hash_algorithm hash_alg) | ||
{ | ||
switch(hash_alg) { | ||
case S2N_HASH_NONE: | ||
case S2N_HASH_MD5: | ||
/* MD5 alone is never supported */ | ||
RESULT_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); | ||
break; | ||
case S2N_HASH_MD5_SHA1: | ||
/* Only RSA supports MD5+SHA1. | ||
* This should not be a problem, as we only allow MD5+SHA1 when | ||
* falling back to TLS1.0 or 1.1, which only support RSA. | ||
*/ | ||
RESULT_ENSURE(sig_alg == S2N_SIGNATURE_RSA, S2N_ERR_HASH_INVALID_ALGORITHM); | ||
break; | ||
default: | ||
break; | ||
} | ||
/* Hash algorithm must be recognized and supported by EVP_MD */ | ||
RESULT_ENSURE(s2n_hash_alg_to_evp_md(hash_alg) != NULL, S2N_ERR_HASH_INVALID_ALGORITHM); | ||
return S2N_RESULT_OK; | ||
} | ||
|
||
int s2n_evp_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg, | ||
struct s2n_hash_state *hash_state, struct s2n_blob *signature) | ||
{ | ||
POSIX_ENSURE_REF(priv); | ||
POSIX_ENSURE_REF(hash_state); | ||
POSIX_ENSURE_REF(signature); | ||
POSIX_ENSURE(s2n_evp_signing_supported(), S2N_ERR_HASH_NOT_READY); | ||
POSIX_GUARD_RESULT(s2n_evp_signing_validate_hash_alg(sig_alg, hash_state->alg)); | ||
|
||
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(priv->pkey, NULL); | ||
POSIX_ENSURE_REF(pctx); | ||
POSIX_GUARD_OSSL(EVP_PKEY_sign_init(pctx), S2N_ERR_PKEY_CTX_INIT); | ||
POSIX_GUARD_OSSL(S2N_EVP_PKEY_CTX_set_signature_md(pctx, s2n_hash_alg_to_evp_md(hash_state->alg)), S2N_ERR_PKEY_CTX_INIT); | ||
|
||
if (sig_alg == S2N_SIGNATURE_RSA_PSS_RSAE || sig_alg == S2N_SIGNATURE_RSA_PSS_PSS) { | ||
POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_PKEY_CTX_INIT); | ||
POSIX_GUARD_RESULT(s2n_evp_pkey_set_rsa_pss_saltlen(pctx)); | ||
} | ||
|
||
EVP_MD_CTX *ctx = hash_state->digest.high_level.evp.ctx; | ||
POSIX_ENSURE_REF(ctx); | ||
POSIX_GUARD_RESULT(s2n_evp_md_ctx_set_pkey_ctx(ctx, pctx)); | ||
|
||
size_t signature_size = signature->size; | ||
POSIX_GUARD_OSSL(EVP_DigestSignFinal(ctx, signature->data, &signature_size), S2N_ERR_SIGN); | ||
POSIX_ENSURE(signature_size <= signature->size, S2N_ERR_SIZE_MISMATCH); | ||
signature->size = signature_size; | ||
return S2N_SUCCESS; | ||
} | ||
|
||
int s2n_evp_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg, | ||
struct s2n_hash_state *hash_state, struct s2n_blob *signature) | ||
{ | ||
POSIX_ENSURE_REF(pub); | ||
POSIX_ENSURE_REF(hash_state); | ||
POSIX_ENSURE_REF(signature); | ||
POSIX_ENSURE(s2n_evp_signing_supported(), S2N_ERR_HASH_NOT_READY); | ||
POSIX_GUARD_RESULT(s2n_evp_signing_validate_hash_alg(sig_alg, hash_state->alg)); | ||
|
||
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pub->pkey, NULL); | ||
POSIX_ENSURE_REF(pctx); | ||
POSIX_GUARD_OSSL(EVP_PKEY_verify_init(pctx), S2N_ERR_PKEY_CTX_INIT); | ||
POSIX_GUARD_OSSL(S2N_EVP_PKEY_CTX_set_signature_md(pctx, s2n_hash_alg_to_evp_md(hash_state->alg)), S2N_ERR_PKEY_CTX_INIT); | ||
|
||
if (sig_alg == S2N_SIGNATURE_RSA_PSS_RSAE || sig_alg == S2N_SIGNATURE_RSA_PSS_PSS) { | ||
POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_PKEY_CTX_INIT); | ||
} | ||
|
||
EVP_MD_CTX *ctx = hash_state->digest.high_level.evp.ctx; | ||
POSIX_ENSURE_REF(ctx); | ||
POSIX_GUARD_RESULT(s2n_evp_md_ctx_set_pkey_ctx(ctx, pctx)); | ||
|
||
POSIX_GUARD_OSSL(EVP_DigestVerifyFinal(ctx, signature->data, signature->size), S2N_ERR_VERIFY_SIGNATURE); | ||
return S2N_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "api/s2n.h" | ||
|
||
#include "crypto/s2n_hash.h" | ||
#include "crypto/s2n_signature.h" | ||
#include "utils/s2n_blob.h" | ||
|
||
bool s2n_evp_signing_supported(); | ||
S2N_RESULT s2n_evp_signing_set_pkey_overrides(struct s2n_pkey *pkey); | ||
int s2n_evp_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg, | ||
struct s2n_hash_state *digest, struct s2n_blob *signature); | ||
int s2n_evp_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg, | ||
struct s2n_hash_state *digest, struct s2n_blob *signature); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
#include <openssl/evp.h> | ||
int main() { | ||
EVP_MD_CTX_set_pkey_ctx(NULL, NULL); | ||
return 0; | ||
} |
Oops, something went wrong.