Add SSL_get_ivs.

This function allows one to extract the current IVs from an SSL
connection. This is needed for the CBC cipher suites with implicit IVs
because, for those, the IV can't be extracted from the handshake key
material.

Change-Id: I247a1d0813b7a434b3cfc88db86d2fe8754344b6
Reviewed-on: https://boringssl-review.googlesource.com/6433
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
Adam Langley
2015-11-03 18:36:10 -08:00
parent a97b737fb0
commit c2d3280f0f
10 changed files with 100 additions and 2 deletions
+9
View File
@@ -156,3 +156,12 @@ int EVP_AEAD_CTX_get_rc4_state(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_key)
return ctx->aead->get_rc4_state(ctx, out_key);
}
int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
size_t *out_len) {
if (ctx->aead->get_iv == NULL) {
return 0;
}
return ctx->aead->get_iv(ctx, out_iv, out_len);
}
+8 -2
View File
@@ -1203,6 +1203,7 @@ static const EVP_AEAD aead_aes_128_gcm = {
aead_aes_gcm_seal,
aead_aes_gcm_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_gcm = {
@@ -1216,6 +1217,7 @@ static const EVP_AEAD aead_aes_256_gcm = {
aead_aes_gcm_seal,
aead_aes_gcm_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_aes_128_gcm(void) { return &aead_aes_128_gcm; }
@@ -1462,7 +1464,8 @@ static const EVP_AEAD aead_aes_128_key_wrap = {
aead_aes_key_wrap_cleanup,
aead_aes_key_wrap_seal,
aead_aes_key_wrap_open,
NULL, /* get_rc4_state */
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_key_wrap = {
@@ -1475,7 +1478,8 @@ static const EVP_AEAD aead_aes_256_key_wrap = {
aead_aes_key_wrap_cleanup,
aead_aes_key_wrap_seal,
aead_aes_key_wrap_open,
NULL, /* get_rc4_state */
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_aes_128_key_wrap(void) { return &aead_aes_128_key_wrap; }
@@ -1726,6 +1730,7 @@ static const EVP_AEAD aead_aes_128_ctr_hmac_sha256 = {
aead_aes_ctr_hmac_sha256_seal,
aead_aes_ctr_hmac_sha256_open,
NULL /* get_rc4_state */,
NULL /* get_iv */,
};
static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = {
@@ -1740,6 +1745,7 @@ static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = {
aead_aes_ctr_hmac_sha256_seal,
aead_aes_ctr_hmac_sha256_open,
NULL /* get_rc4_state */,
NULL /* get_iv */,
};
const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) {
+2
View File
@@ -240,6 +240,7 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
aead_chacha20_poly1305_seal,
aead_chacha20_poly1305_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
@@ -296,6 +297,7 @@ static const EVP_AEAD aead_chacha20_poly1305_old = {
aead_chacha20_poly1305_old_seal,
aead_chacha20_poly1305_old_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void) {
+1
View File
@@ -392,6 +392,7 @@ static const EVP_AEAD aead_rc4_md5_tls = {
aead_rc4_md5_tls_seal,
aead_rc4_md5_tls_open,
aead_rc4_md5_tls_get_rc4_state,
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
+19
View File
@@ -307,6 +307,19 @@ static int aead_ssl3_get_rc4_state(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_
return 1;
}
static int aead_ssl3_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
size_t *out_iv_len) {
AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
const size_t iv_len = EVP_CIPHER_CTX_iv_length(&ssl3_ctx->cipher_ctx);
if (iv_len <= 1) {
return 0;
}
*out_iv = ssl3_ctx->cipher_ctx.iv;
*out_iv_len = iv_len;
return 1;
}
static int aead_rc4_md5_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len,
enum evp_aead_direction_t dir) {
@@ -358,6 +371,7 @@ static const EVP_AEAD aead_rc4_md5_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
aead_ssl3_get_rc4_state,
NULL, /* get_iv */
};
static const EVP_AEAD aead_rc4_sha1_ssl3 = {
@@ -371,6 +385,7 @@ static const EVP_AEAD aead_rc4_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
aead_ssl3_get_rc4_state,
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = {
@@ -384,6 +399,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
NULL, /* get_rc4_state */
aead_ssl3_get_iv,
};
static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = {
@@ -397,6 +413,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
NULL, /* get_rc4_state */
aead_ssl3_get_iv,
};
static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = {
@@ -410,6 +427,7 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
NULL, /* get_rc4_state */
aead_ssl3_get_iv,
};
static const EVP_AEAD aead_null_sha1_ssl3 = {
@@ -423,6 +441,7 @@ static const EVP_AEAD aead_null_sha1_ssl3 = {
aead_ssl3_seal,
aead_ssl3_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void) { return &aead_rc4_md5_ssl3; }
+24
View File
@@ -444,6 +444,19 @@ static int aead_rc4_sha1_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
return 1;
}
static int aead_tls_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
size_t *out_iv_len) {
const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state;
const size_t iv_len = EVP_CIPHER_CTX_iv_length(&tls_ctx->cipher_ctx);
if (iv_len <= 1) {
return 0;
}
*out_iv = tls_ctx->cipher_ctx.iv;
*out_iv_len = iv_len;
return 1;
}
static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len,
enum evp_aead_direction_t dir) {
@@ -462,6 +475,7 @@ static const EVP_AEAD aead_rc4_sha1_tls = {
aead_tls_seal,
aead_tls_open,
aead_rc4_sha1_tls_get_rc4_state, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
@@ -475,6 +489,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = {
@@ -488,6 +503,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
aead_tls_get_iv, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha256_tls = {
@@ -501,6 +517,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha256_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_cbc_sha1_tls = {
@@ -514,6 +531,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = {
@@ -527,6 +545,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
aead_tls_get_iv, /* get_iv */
};
static const EVP_AEAD aead_aes_256_cbc_sha256_tls = {
@@ -540,6 +559,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha256_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_256_cbc_sha384_tls = {
@@ -553,6 +573,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha384_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = {
@@ -566,6 +587,7 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = {
@@ -579,6 +601,7 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
aead_tls_get_iv, /* get_iv */
};
static const EVP_AEAD aead_null_sha1_tls = {
@@ -592,6 +615,7 @@ static const EVP_AEAD aead_null_sha1_tls = {
aead_tls_seal,
aead_tls_open,
NULL, /* get_rc4_state */
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_rc4_sha1_tls(void) { return &aead_rc4_sha1_tls; }
+3
View File
@@ -96,6 +96,9 @@ struct evp_aead_st {
size_t ad_len);
int (*get_rc4_state)(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_key);
int (*get_iv)(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
size_t *out_len);
};
+7
View File
@@ -330,6 +330,13 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
OPENSSL_EXPORT int EVP_AEAD_CTX_get_rc4_state(const EVP_AEAD_CTX *ctx,
const RC4_KEY **out_key);
/* EVP_AEAD_CTX_get_iv sets |*out_len| to the length of the IV for |ctx| and
* sets |*out_iv| to point to that many bytes of the current IV. This is only
* meaningful for AEADs with implicit IVs (i.e. CBC mode in SSLv3 and TLS 1.0).
*
* It returns one on success or zero on error. */
OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx,
const uint8_t **out_iv, size_t *out_len);
#if defined(__cplusplus)
} /* extern C */
+10
View File
@@ -2613,6 +2613,16 @@ OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp,
OPENSSL_EXPORT int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
const RC4_KEY **write_key);
/* SSL_get_ivs sets |*out_iv_len| to the length of the IVs for the ciphers
* underlying |ssl| and sets |*out_read_iv| and |*out_write_iv| to point to the
* current IVs for the read and write directions. This is only meaningful for
* connections with implicit IVs (i.e. CBC mode with SSLv3 or TLS 1.0).
*
* It returns one on success or zero on error. */
OPENSSL_EXPORT int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
const uint8_t **out_write_iv,
size_t *out_iv_len);
/* SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and
* SSL_SESSION structures so that a test can ensure that outside code agrees on
* these values. */
+17
View File
@@ -2636,6 +2636,23 @@ int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
}
int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
const uint8_t **out_write_iv, size_t *out_iv_len) {
if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
return 0;
}
size_t write_iv_len;
if (!EVP_AEAD_CTX_get_iv(&ssl->aead_read_ctx->ctx, out_read_iv, out_iv_len) ||
!EVP_AEAD_CTX_get_iv(&ssl->aead_write_ctx->ctx, out_write_iv,
&write_iv_len) ||
*out_iv_len != write_iv_len) {
return 0;
}
return 1;
}
int SSL_clear(SSL *ssl) {
if (ssl->method == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_METHOD_SPECIFIED);