Skip to content

Commit

Permalink
Merge branch 'main' into openbsd-aarch64
Browse files Browse the repository at this point in the history
  • Loading branch information
justsmth authored Nov 11, 2024
2 parents f0917e1 + c9d48a6 commit 38d3bf3
Show file tree
Hide file tree
Showing 25 changed files with 419 additions and 112 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,10 @@ if(GCC OR CLANG)
endif()
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings")

if(GCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "8")
if((GCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "8") OR
(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS "13"))
# GCC 8.x added a warning called -Wcast-function-type to the -Wextra umbrella.
# Also suppress for all clang versions supporting this warning.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-cast-function-type")
endif()

Expand Down
2 changes: 1 addition & 1 deletion crypto/bytestring/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out,
// error, it calls |CBB_cleanup| on |cbb|.
//
// This function may be used to help implement legacy i2d ASN.1 functions.
int CBB_finish_i2d(CBB *cbb, uint8_t **outp);
OPENSSL_EXPORT int CBB_finish_i2d(CBB *cbb, uint8_t **outp);


// Unicode utilities.
Expand Down
9 changes: 0 additions & 9 deletions crypto/fipsmodule/cipher/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,6 @@ ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key,
block128_f *out_block, const uint8_t *key,
size_t key_bytes);

// AES_cfb1_encrypt calls |CRYPTO_cfb128_1_encrypt| using the block
// |AES_encrypt|.
void AES_cfb1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
const AES_KEY *key, uint8_t *ivec, int *num, int enc);

// AES_cfb8_encrypt calls |CRYPTO_cfb128_8_encrypt| using the block
// |AES_encrypt|.
void AES_cfb8_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const AES_KEY *key, uint8_t *ivec, int *num, int enc);

// EXPERIMENTAL functions for use in the TLS Transfer function. See
// |SSL_to_bytes| for more details.
Expand Down
14 changes: 14 additions & 0 deletions crypto/fipsmodule/curve25519/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ void ED25519_keypair_from_seed(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN],
ED25519_PUBLIC_KEY_LEN);
}

static void ed25519_keypair_pct(uint8_t public_key[ED25519_PUBLIC_KEY_LEN],
uint8_t private_key[ED25519_PRIVATE_KEY_LEN]) {
#if defined(AWSLC_FIPS)
uint8_t msg[16] = {16};
uint8_t out_sig[ED25519_SIGNATURE_LEN];
if (ED25519_sign_no_self_test(out_sig, msg, 16, private_key) != 1 ||
ED25519_verify_no_self_test(msg, 16, out_sig, public_key) != 1) {
BORINGSSL_FIPS_abort();
}
#endif
}

void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN],
uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN]) {
boringssl_ensure_eddsa_self_test();
Expand All @@ -118,6 +130,8 @@ void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN],
ED25519_keypair_from_seed(out_public_key, out_private_key, seed);
OPENSSL_cleanse(seed, ED25519_SEED_LEN);

ed25519_keypair_pct(out_public_key, out_private_key);

FIPS_service_indicator_update_state();
}

Expand Down
48 changes: 38 additions & 10 deletions crypto/fipsmodule/ml_kem/ml_kem_ref/kem.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "params.h"
#include "kem.h"
#include "indcpa.h"
#include "verify.h"
#include "reduce.h"
#include "symmetric.h"
#include "./params.h"
#include "./kem.h"
#include "./indcpa.h"
#include "./verify.h"
#include "./reduce.h"
#include "./symmetric.h"
#include "../../../internal.h"

#include "openssl/rand.h"

#if defined(AWSLC_FIPS)
// FIPS 203. Pair-wise Consistency Test (PCT) required per [FIPS 140-3 IG](https://csrc.nist.gov/csrc/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf):
// The PCT consists of applying the encapsulation key to encapsulate a shared
// secret leading to ciphertext, and then applying decapsulation key to
// retrieve the same shared secret. Returns 0 if the PCT passes, 1 otherwise.
static int keygen_pct(ml_kem_params *params, const uint8_t *ek, const uint8_t *dk) {
uint8_t ct[KYBER_CIPHERTEXTBYTES_MAX];
uint8_t ss_enc[KYBER_SSBYTES];
uint8_t ss_dec[KYBER_SSBYTES];

crypto_kem_enc(params, ct, ss_enc, ek);
crypto_kem_dec(params, ss_dec, ct, dk);

return verify(ss_enc, ss_dec, KYBER_SSBYTES);
}
#endif

/*************************************************
* Name: crypto_kem_keypair_derand
*
Expand All @@ -22,7 +41,7 @@
* - uint8_t *coins: pointer to input randomness
* (an already allocated array filled with 2*KYBER_SYMBYTES random bytes)
**
* Returns 0 (success)
* Returns 0 on success, aborts on failure.
**************************************************/
int crypto_kem_keypair_derand(ml_kem_params *params,
uint8_t *pk,
Expand All @@ -34,6 +53,13 @@ int crypto_kem_keypair_derand(ml_kem_params *params,
hash_h(sk+params->secret_key_bytes-2*KYBER_SYMBYTES, pk, params->public_key_bytes);
/* Value z for pseudo-random output on reject */
memcpy(sk+params->secret_key_bytes-KYBER_SYMBYTES, coins+KYBER_SYMBYTES, KYBER_SYMBYTES);

#if defined(AWSLC_FIPS)
// Abort in case of PCT failure.
if (keygen_pct(params, pk, sk)) {
BORINGSSL_FIPS_abort();
}
#endif
return 0;
}

Expand All @@ -48,19 +74,21 @@ int crypto_kem_keypair_derand(ml_kem_params *params,
* - uint8_t *sk: pointer to output private key
* (an already allocated array of KYBER_SECRETKEYBYTES bytes)
*
* Returns 0 (success)
* Returns 0 on success, aborts on failure.
**************************************************/
int crypto_kem_keypair(ml_kem_params *params,
uint8_t *pk,
uint8_t *sk)
{
uint8_t coins[2*KYBER_SYMBYTES];
RAND_bytes(coins, 2*KYBER_SYMBYTES);
crypto_kem_keypair_derand(params, pk, sk, coins);
int res = crypto_kem_keypair_derand(params, pk, sk, coins);
assert(res == 0);

// FIPS 203. Section 3.3 Destruction of intermediate values.
OPENSSL_cleanse(coins, sizeof(coins));
return 0;

return res;
}

// Converts a centered representative |in| which is an integer in
Expand Down
4 changes: 2 additions & 2 deletions crypto/fipsmodule/service_indicator/service_indicator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5245,7 +5245,7 @@ TEST(ServiceIndicatorTest, ED25519SigGenVerify) {
// Since this is running in FIPS mode it should end in FIPS
// Update this when the AWS-LC version number is modified
TEST(ServiceIndicatorTest, AWSLCVersionString) {
ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 1.37.0");
ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 1.38.0");
}

#else
Expand Down Expand Up @@ -5288,6 +5288,6 @@ TEST(ServiceIndicatorTest, BasicTest) {
// Since this is not running in FIPS mode it shouldn't end in FIPS
// Update this when the AWS-LC version number is modified
TEST(ServiceIndicatorTest, AWSLCVersionString) {
ASSERT_STREQ(awslc_version_string(), "AWS-LC 1.37.0");
ASSERT_STREQ(awslc_version_string(), "AWS-LC 1.38.0");
}
#endif // AWSLC_FIPS
2 changes: 1 addition & 1 deletion crypto/rand_extra/windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static void init_processprng(void) {
if (hmod == NULL) {
abort();
}
g_processprng_fn = (ProcessPrngFunction)GetProcAddress(hmod, "ProcessPrng");
g_processprng_fn = (ProcessPrngFunction)(void(*)(void))GetProcAddress(hmod, "ProcessPrng");
if (g_processprng_fn == NULL) {
abort();
}
Expand Down
3 changes: 3 additions & 0 deletions crypto/x509/x509_att.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
}

int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr) {
if (attr == NULL) {
return 0;
}
return (int)sk_ASN1_TYPE_num(attr->set);
}

Expand Down
18 changes: 18 additions & 0 deletions include/openssl/aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,24 @@ OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out,
size_t len, const AES_KEY *key,
uint8_t *ivec, int *num);

// AES_cfb1_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
// bytes from |in| to |out|. The |num| parameter must be set to zero on the
// first call. This function may be called in-place with |in| equal to |out|,
// but otherwise the buffers may not partially overlap. A partial overlap may
// overwrite input data before it is read.
OPENSSL_EXPORT void AES_cfb1_encrypt(const uint8_t *in, uint8_t *out,
size_t bits, const AES_KEY *key,
uint8_t *ivec, int *num, int enc);

// AES_cfb8_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
// bytes from |in| to |out|. The |num| parameter must be set to zero on the
// first call. This function may be called in-place with |in| equal to |out|,
// but otherwise the buffers may not partially overlap. A partial overlap may
// overwrite input data before it is read.
OPENSSL_EXPORT void AES_cfb8_encrypt(const uint8_t *in, uint8_t *out,
size_t len, const AES_KEY *key,
uint8_t *ivec, int *num, int enc);

// AES_cfb128_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
// bytes from |in| to |out|. The |num| parameter must be set to zero on the
// first call. This function may be called in-place with |in| equal to |out|,
Expand Down
2 changes: 1 addition & 1 deletion include/openssl/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ extern "C" {
// ServiceIndicatorTest.AWSLCVersionString
// Note: there are two versions of this test. Only one test is compiled
// depending on FIPS mode.
#define AWSLC_VERSION_NUMBER_STRING "1.37.0"
#define AWSLC_VERSION_NUMBER_STRING "1.38.0"

#if defined(BORINGSSL_SHARED_LIBRARY)

Expand Down
21 changes: 13 additions & 8 deletions include/openssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2703,6 +2703,17 @@ OPENSSL_EXPORT uint16_t SSL_get_group_id(const SSL *ssl);
// the given TLS group ID, or NULL if the group is unknown.
OPENSSL_EXPORT const char *SSL_get_group_name(uint16_t group_id);

// SSL_get_peer_tmp_key sets |*out_key| to the temporary key provided by the
// peer that was during the key exchange. If |ssl| is the server, the client's
// temporary key is returned; if |ssl| is the client, the server's temporary key
// is returned. It returns 1 on success and 0 if otherwise.
OPENSSL_EXPORT int SSL_get_peer_tmp_key(SSL *ssl, EVP_PKEY **out_key);

// SSL_get_server_tmp_key is a backwards compatible alias to
// |SSL_get_peer_tmp_key| in OpenSSL. Note that this means the client's
// temporary key is being set to |*out_key| instead, if |ssl| is the server.
OPENSSL_EXPORT int SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key);

// *** EXPERIMENTAL — DO NOT USE WITHOUT CHECKING ***
//
// |SSL_to_bytes| and |SSL_from_bytes| are developed to support SSL transfer
Expand Down Expand Up @@ -5361,15 +5372,14 @@ OPENSSL_EXPORT int SSL_want(const SSL *ssl);

// SSL_get_finished writes up to |count| bytes of the Finished message sent by
// |ssl| to |buf|. It returns the total untruncated length or zero if none has
// been sent yet. At TLS 1.3 and later, it returns zero.
// been sent yet.
//
// Use |SSL_get_tls_unique| instead.
OPENSSL_EXPORT size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count);

// SSL_get_peer_finished writes up to |count| bytes of the Finished message
// received from |ssl|'s peer to |buf|. It returns the total untruncated length
// or zero if none has been received yet. At TLS 1.3 and later, it returns
// zero.
// or zero if none has been received yet.
//
// Use |SSL_get_tls_unique| instead.
OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *ssl, void *buf,
Expand Down Expand Up @@ -5828,11 +5838,6 @@ DEFINE_STACK_OF(SSL_COMP)
// AWS-LC does not support the use of FFDH cipher suites in libssl. The
// following functions are only provided as no-ops for easier compatibility.

// SSL_get_server_tmp_key returns zero. This was deprecated as part of the
// removal of |EVP_PKEY_DH|.
OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_get_server_tmp_key(
SSL *ssl, EVP_PKEY **out_key);

// SSL_CTX_set_tmp_dh returns 1.
//
// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. nginx defines -Werror and
Expand Down
3 changes: 2 additions & 1 deletion include/openssl/x509.h
Original file line number Diff line number Diff line change
Expand Up @@ -2272,7 +2272,8 @@ OPENSSL_EXPORT int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
OPENSSL_EXPORT void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
int attrtype, void *unused);

// X509_ATTRIBUTE_count returns the number of values in |attr|.
// X509_ATTRIBUTE_count returns the number of values in |attr| or 0 if |attr|
// is NULL.
OPENSSL_EXPORT int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr);

// X509_ATTRIBUTE_get0_object returns the type of |attr|.
Expand Down
5 changes: 4 additions & 1 deletion ssl/extensions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2312,6 +2312,7 @@ static bool ext_key_share_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,

bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
Array<uint8_t> *out_secret,
Array<uint8_t> *out_peer_key,
uint8_t *out_alert, CBS *contents) {
CBS peer_key;
uint16_t group_id;
Expand All @@ -2333,7 +2334,9 @@ bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
key_share = hs->key_shares[1].get();
}

if (!key_share->Finish(out_secret, out_alert, peer_key)) {
if (!key_share->Finish(out_secret, out_alert, peer_key) ||
// Save peer's public key for observation with |SSL_get_peer_tmp_key|.
!out_peer_key->CopyFrom(peer_key)) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return false;
}
Expand Down
9 changes: 5 additions & 4 deletions ssl/handshake_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) {

// Save the group and peer public key for later.
hs->new_session->group_id = group_id;
if (!hs->peer_key.CopyFrom(point)) {
if (!ssl->s3->peer_key.CopyFrom(point)) {
return ssl_hs_error;
}
} else if (!(alg_k & SSL_kPSK)) {
Expand Down Expand Up @@ -1508,16 +1508,17 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) {
bssl::UniquePtr<SSLKeyShare> key_share =
SSLKeyShare::Create(hs->new_session->group_id);
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!key_share || !key_share->Accept(&child, &pms, &alert, hs->peer_key)) {
if (!key_share ||
!key_share->Accept(&child, &pms, &alert, ssl->s3->peer_key)) {
ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
if (!CBB_flush(&body)) {
return ssl_hs_error;
}

// The peer key can now be discarded.
hs->peer_key.Reset();
// The peer key could be discarded, but we preserve it since OpenSSL
// allows the user to observe it with |SSL_get_peer_tmp_key|.
} else if (alg_k & SSL_kPSK) {
// For plain PSK, other_secret is a block of 0s with the same length as
// the pre-shared key.
Expand Down
4 changes: 3 additions & 1 deletion ssl/handshake_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1532,7 +1532,9 @@ static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) {

// Compute the premaster.
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!hs->key_shares[0]->Finish(&premaster_secret, &alert, peer_key)) {
if (!hs->key_shares[0]->Finish(&premaster_secret, &alert, peer_key) ||
// Save peer's public key for observation with |SSL_get_peer_tmp_key|.
!ssl->s3->peer_key.CopyFrom(peer_key)) {
ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
Expand Down
16 changes: 12 additions & 4 deletions ssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,11 @@ Span<const uint16_t> PQGroups();
// false.
bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid);

// ssl_nid_to_group_id looks up the group corresponding to |group_id|. On
// success, it sets |*out_nid| to the group's nid and returns true. Otherwise,
// it returns false.
bool ssl_group_id_to_nid(uint16_t *out_nid, int group_id);

// ssl_name_to_group_id looks up the group corresponding to the |name| string of
// length |len|. On success, it sets |*out_group_id| to the group ID and returns
// true. Otherwise, it returns false.
Expand Down Expand Up @@ -2061,9 +2066,6 @@ struct SSL_HANDSHAKE {
// supports with delegated credentials.
Array<uint16_t> peer_delegated_credential_sigalgs;

// peer_key is the peer's ECDH key for a TLS 1.2 client.
Array<uint8_t> peer_key;

// extension_permutation is the permutation to apply to ClientHello
// extensions. It maps indices into the |kExtensions| table into other
// indices.
Expand Down Expand Up @@ -2336,6 +2338,7 @@ bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id);

bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
Array<uint8_t> *out_secret,
Array<uint8_t> *out_peer_key,
uint8_t *out_alert, CBS *contents);
bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
Span<const uint8_t> *out_peer_key,
Expand Down Expand Up @@ -2861,7 +2864,7 @@ enum ssl_ech_status_t {
#define SSL3_SEND_ALERT_SIZE 2
#define TLS_SEQ_NUM_SIZE 8
#define SSL3_CHANNEL_ID_SIZE 64
#define PREV_FINISHED_MAX_SIZE 12
#define PREV_FINISHED_MAX_SIZE EVP_MAX_MD_SIZE

struct SSL3_STATE {
static constexpr bool kAllowUniquePtr = true;
Expand Down Expand Up @@ -3033,6 +3036,11 @@ struct SSL3_STATE {
// one.
UniquePtr<SSL_HANDSHAKE> hs;

// peer_key is the peer's ECDH key for both TLS 1.2/1.3. This is only used
// for observing with |SSL_get_peer_tmp_key| and is not serialized as part of
// the SSL Transfer feature.
Array<uint8_t> peer_key;

uint8_t write_traffic_secret[SSL_MAX_MD_SIZE] = {0};
uint8_t read_traffic_secret[SSL_MAX_MD_SIZE] = {0};
uint8_t exporter_secret[SSL_MAX_MD_SIZE] = {0};
Expand Down
Loading

0 comments on commit 38d3bf3

Please sign in to comment.