Skip to content

Commit

Permalink
Use some of BoringSSL APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
maskit committed Feb 17, 2020
1 parent 715566a commit 7611b58
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 223 deletions.
10 changes: 10 additions & 0 deletions include/tscore/ink_endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,14 @@ htobe32(uint32_t x)
{
return OSSwapHostToBigInt32(x);
}
inline uint32_t
le32toh(uint32_t x)
{
return OSSwapLittleToHostInt32(x);
}
inline uint32_t
htole32(uint32_t x)
{
return OSSwapHostToLittleInt32(x);
}
#endif
4 changes: 2 additions & 2 deletions iocore/net/quic/QUICPacketHeaderProtector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ QUICPacketHeaderProtector::protect(uint8_t *unprotected_packet, size_t unprotect
Debug("v_quic_pne", "Protecting a packet number of %s packet using %s", QUICDebugNames::packet_type(type),
QUICDebugNames::key_phase(phase));

const QUIC_EVP_CIPHER *aead = this->_pp_key_info.get_cipher_for_hp(phase);
const EVP_CIPHER *aead = this->_pp_key_info.get_cipher_for_hp(phase);
if (!aead) {
Debug("quic_pne", "Failed to encrypt a packet number: keys for %s is not ready", QUICDebugNames::key_phase(phase));
return false;
Expand Down Expand Up @@ -103,7 +103,7 @@ QUICPacketHeaderProtector::unprotect(uint8_t *protected_packet, size_t protected
Debug("v_quic_pne", "Unprotecting a packet number of %s packet using %s", QUICDebugNames::packet_type(type),
QUICDebugNames::key_phase(phase));

const QUIC_EVP_CIPHER *aead = this->_pp_key_info.get_cipher_for_hp(phase);
const EVP_CIPHER *aead = this->_pp_key_info.get_cipher_for_hp(phase);
if (!aead) {
Debug("quic_pne", "Failed to decrypt a packet number: keys for %s is not ready", QUICDebugNames::key_phase(phase));
return false;
Expand Down
2 changes: 1 addition & 1 deletion iocore/net/quic/QUICPacketHeaderProtector.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class QUICPacketHeaderProtector

bool _calc_sample_offset(uint8_t *sample_offset, const uint8_t *protected_packet, size_t protected_packet_len, int dcil) const;

bool _generate_mask(uint8_t *mask, const uint8_t *sample, const uint8_t *key, const QUIC_EVP_CIPHER *cipher) const;
bool _generate_mask(uint8_t *mask, const uint8_t *sample, const uint8_t *key, const EVP_CIPHER *cipher) const;

bool _unprotect(uint8_t *packet, size_t packet_len, const uint8_t *mask) const;
bool _protect(uint8_t *packet, size_t packet_len, const uint8_t *mask, int dcil) const;
Expand Down
27 changes: 15 additions & 12 deletions iocore/net/quic/QUICPacketHeaderProtector_boringssl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,29 @@

#include "QUICPacketHeaderProtector.h"

#include "openssl/chacha.h"

bool
QUICPacketHeaderProtector::_generate_mask(uint8_t *mask, const uint8_t *sample, const uint8_t *key,
const QUIC_EVP_CIPHER *cipher) const
QUICPacketHeaderProtector::_generate_mask(uint8_t *mask, const uint8_t *sample, const uint8_t *key, const EVP_CIPHER *cipher) const
{
static constexpr unsigned char FIVE_ZEROS[] = {0x00, 0x00, 0x00, 0x00, 0x00};
EVP_AEAD_CTX ctx;

if (!EVP_AEAD_CTX_init(&ctx, cipher, key, EVP_AEAD_key_length(cipher), 16, nullptr)) {
return false;
}

size_t len = 0;
if (cipher == EVP_aead_chacha20_poly1305()) {
if (!EVP_AEAD_CTX_seal(&ctx, mask, &len, EVP_MAX_BLOCK_LENGTH, sample + 4, 12, FIVE_ZEROS, sizeof(FIVE_ZEROS), sample, 4)) {
if (cipher == nullptr) {
uint32_t counter = htole32(*reinterpret_cast<const uint32_t *>(&sample[0]));
CRYPTO_chacha_20(mask, FIVE_ZEROS, sizeof(FIVE_ZEROS), key, &sample[4], counter);
} else {
int len = 0;
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (!ctx || !EVP_EncryptInit_ex(ctx, cipher, nullptr, key, sample)) {
return false;
}
} else {
if (!EVP_AEAD_CTX_seal(&ctx, mask, &len, EVP_MAX_BLOCK_LENGTH, nullptr, 0, sample, 16, nullptr, 0)) {
if (!EVP_EncryptUpdate(ctx, mask, &len, sample, 16)) {
return false;
}
if (!EVP_EncryptFinal_ex(ctx, mask + len, &len)) {
return false;
}
EVP_CIPHER_CTX_free(ctx);
}

return true;
Expand Down
3 changes: 1 addition & 2 deletions iocore/net/quic/QUICPacketHeaderProtector_openssl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
#include "QUICPacketHeaderProtector.h"

bool
QUICPacketHeaderProtector::_generate_mask(uint8_t *mask, const uint8_t *sample, const uint8_t *key,
const QUIC_EVP_CIPHER *cipher) const
QUICPacketHeaderProtector::_generate_mask(uint8_t *mask, const uint8_t *sample, const uint8_t *key, const EVP_CIPHER *cipher) const
{
static constexpr unsigned char FIVE_ZEROS[] = {0x00, 0x00, 0x00, 0x00, 0x00};
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
Expand Down
2 changes: 1 addition & 1 deletion iocore/net/quic/QUICPacketProtectionKeyInfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ QUICPacketProtectionKeyInfo::set_cipher(const EVP_CIPHER *cipher, size_t tag_len
this->_tag_len = tag_len;
}

const QUIC_EVP_CIPHER *
const EVP_CIPHER *
QUICPacketProtectionKeyInfo::get_cipher_for_hp(QUICKeyPhase phase) const
{
switch (phase) {
Expand Down
12 changes: 6 additions & 6 deletions iocore/net/quic/QUICPacketProtectionKeyInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ class QUICPacketProtectionKeyInfoProvider
virtual const size_t *decryption_iv_len(QUICKeyPhase phase) const = 0;

// Header Protection
virtual const QUIC_EVP_CIPHER *get_cipher_for_hp(QUICKeyPhase phase) const = 0;
virtual const uint8_t *encryption_key_for_hp(QUICKeyPhase phase) const = 0;
virtual size_t encryption_key_for_hp_len(QUICKeyPhase phase) const = 0;
virtual const uint8_t *decryption_key_for_hp(QUICKeyPhase phase) const = 0;
virtual size_t decryption_key_for_hp_len(QUICKeyPhase phase) const = 0;
virtual const EVP_CIPHER *get_cipher_for_hp(QUICKeyPhase phase) const = 0;
virtual const uint8_t *encryption_key_for_hp(QUICKeyPhase phase) const = 0;
virtual size_t encryption_key_for_hp_len(QUICKeyPhase phase) const = 0;
virtual const uint8_t *decryption_key_for_hp(QUICKeyPhase phase) const = 0;
virtual size_t decryption_key_for_hp_len(QUICKeyPhase phase) const = 0;
};

class QUICPacketProtectionKeyInfo : public QUICPacketProtectionKeyInfoProvider
Expand Down Expand Up @@ -109,7 +109,7 @@ class QUICPacketProtectionKeyInfo : public QUICPacketProtectionKeyInfoProvider

// Header Protection

virtual const QUIC_EVP_CIPHER *get_cipher_for_hp(QUICKeyPhase phase) const override;
virtual const EVP_CIPHER *get_cipher_for_hp(QUICKeyPhase phase) const override;
virtual void set_cipher_for_hp_initial(const EVP_CIPHER *cipher);
virtual void set_cipher_for_hp(const EVP_CIPHER *cipher);

Expand Down
79 changes: 79 additions & 0 deletions iocore/net/quic/QUICTLS.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ QUICTLS::~QUICTLS()
SSL_free(this->_ssl);
}

int
QUICTLS::handshake(QUICHandshakeMsgs *out, const QUICHandshakeMsgs *in)
{
if (this->is_handshake_finished()) {
if (in != nullptr && in->offsets[4] != 0) {
return this->_process_post_handshake_messages(out, in);
}

return 0;
}

return this->_handshake(out, in);
}

void
QUICTLS::reset()
{
Expand Down Expand Up @@ -202,6 +216,71 @@ QUICTLS::abort_handshake()
return;
}

int
QUICTLS::_handshake(QUICHandshakeMsgs *out, const QUICHandshakeMsgs *in)
{
ink_assert(this->_ssl != nullptr);
if (this->_state == HandshakeState::ABORTED) {
return 0;
}

int err = SSL_ERROR_NONE;
ERR_clear_error();
int ret = 0;

SSL_set_msg_callback(this->_ssl, QUICTLS::_msg_cb);
SSL_set_msg_callback_arg(this->_ssl, out);

// TODO: set BIO_METHOD which read from QUICHandshakeMsgs directly
BIO *rbio = BIO_new(BIO_s_mem());
// TODO: set dummy BIO_METHOD which do nothing
BIO *wbio = BIO_new(BIO_s_mem());
if (in != nullptr && in->offsets[4] != 0) {
BIO_write(rbio, in->buf, in->offsets[4]);
}
SSL_set_bio(this->_ssl, rbio, wbio);

if (this->_netvc_context == NET_VCONNECTION_IN) {
if (!this->_early_data_processed) {
if (auto ret = this->_read_early_data(); ret == 0) {
this->_early_data_processed = true;
} else if (ret < 0) {
out->error_code = static_cast<uint16_t>(QUICTransErrorCode::PROTOCOL_VIOLATION);
return 0;
} else {
// Early data is not arrived yet -- can be multiple initial packets
}
}

ret = SSL_accept(this->_ssl);
} else {
if (!this->_early_data_processed) {
if (this->_write_early_data()) {
this->_early_data_processed = true;
}
}

ret = SSL_connect(this->_ssl);
}

if (ret <= 0) {
err = SSL_get_error(this->_ssl, ret);

switch (err) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
break;
default:
char err_buf[256] = {0};
ERR_error_string_n(ERR_get_error(), err_buf, sizeof(err_buf));
Debug(tag, "Handshake: %s", err_buf);
return ret;
}
}

return 1;
}

void
QUICTLS::_update_encryption_level(QUICEncryptionLevel level)
{
Expand Down
1 change: 1 addition & 0 deletions iocore/net/quic/QUICTLS.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class QUICTLS : public QUICHandshakeProtocol
void _print_km(const char *header, const uint8_t *key_for_hp, size_t key_for_hp_len, const uint8_t *key, size_t key_len,
const uint8_t *iv, size_t iv_len, const uint8_t *secret = nullptr, size_t secret_len = 0);

static void _msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
const char *_session_file = nullptr;
const char *_keylog_file = nullptr;
SSL *_ssl = nullptr;
Expand Down
Loading

0 comments on commit 7611b58

Please sign in to comment.