@@ -710,7 +710,9 @@ const char *translate_cipher_name_to_openvpn(const char *cipher_name);
* @param secret_len length of the secret
* @param output output destination
* @param output_len length of output/number of bytes to generate
+ *
+ * @return true if successful, false on any error
*/
-void ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
+bool ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
int secret_len, uint8_t *output, int output_len);
#endif /* CRYPTO_BACKEND_H_ */
@@ -987,11 +987,12 @@ memcmp_constant_time(const void *a, const void *b, size_t size)
}
/* mbedtls-2.18.0 or newer */
#ifdef HAVE_MBEDTLS_SSL_TLS_PRF
-void ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
+bool ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
int secret_len, uint8_t *output, int output_len)
{
- mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, secret, secret_len, "", seed,
- seed_len, output, output_len);
+ return mbed_ok(mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, secret,
+ secret_len, "", seed, seed_len, output,
+ output_len));
}
#else
/*
@@ -1088,9 +1089,8 @@ tls1_P_hash(const md_kt_t *md_kt,
* (1) key_block contains a full set of 4 keys.
* (2) The pre-master secret is generated by the client.
*/
-void
-ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec, int slen,
- uint8_t *out1, int olen)
+bool ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec,
+ int slen, uint8_t *out1, int olen)
{
struct gc_arena gc = gc_new();
const md_kt_t *md5 = md_kt_get("MD5");
@@ -1103,8 +1103,8 @@ ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec, int slen,
const uint8_t *S2 = &(sec[len]);
len += (slen&1); /* add for odd, make longer */
- tls1_P_hash(md5,S1,len,label,label_len,out1,olen);
- tls1_P_hash(sha1,S2,len,label,label_len,out2,olen);
+ tls1_P_hash(md5, S1, len, label, label_len, out1, olen);
+ tls1_P_hash(sha1, S2, len, label, label_len, out2, olen);
for (int i = 0; i<olen; i++)
{
@@ -1116,6 +1116,7 @@ ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec, int slen,
dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%d]: %s", olen, format_hex(out1, olen, 0, &gc));
gc_free(&gc);
+ return true;
}
#endif
#endif /* ENABLE_CRYPTO_MBEDTLS */
@@ -1128,21 +1128,41 @@ engine_load_key(const char *file, SSL_CTX *ctx)
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
-void ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
+bool ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
int secret_len, uint8_t *output, int output_len)
{
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
- ASSERT(EVP_PKEY_derive_init(pctx) == 1);
+ if(!EVP_PKEY_derive_init(pctx))
+ {
+ return false;
+ }
- ASSERT(EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_md5_sha1()) == 1);
- ASSERT(EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret, secret_len) == 1);
+ if(!EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_md5_sha1()))
+ {
+ return false;
+ }
- ASSERT(EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seed_len) == 1);
+ if(!EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret, secret_len))
+ {
+ return false;
+ }
+
+ if(!EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seed_len))
+ {
+ return false;
+ }
size_t out_len = output_len;
- ASSERT (EVP_PKEY_derive(pctx, output, &out_len) == 1);
- ASSERT (out_len == output_len);
+ if(!EVP_PKEY_derive(pctx, output, &out_len))
+ {
+ return false;
+ }
+ if (out_len != output_len)
+ {
+ return false;
+ }
+ return true;
}
#else
/*
@@ -1258,9 +1278,10 @@ err:
* (1) key_block contains a full set of 4 keys.
* (2) The pre-master secret is generated by the client.
*/
-void ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec,
+bool ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec,
int slen, uint8_t *out1, int olen)
{
+ bool ret = true;
struct gc_arena gc = gc_new();
/* For some reason our md_kt_get("MD5") fails otherwise in the unit test */
const md_kt_t *md5 = EVP_md5();
@@ -1274,8 +1295,16 @@ void ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec,
len += (slen&1); /* add for odd, make longer */
if(!tls1_P_hash(md5,S1,len,label,label_len,out1,olen))
+ {
+ ret = false;
+ goto done;
+ }
- ASSERT(tls1_P_hash(sha1,S2,len,label,label_len,out2,olen));
+ if(!tls1_P_hash(sha1,S2,len,label,label_len,out2,olen))
+ {
+ ret = false;
+ goto done;
+ }
for (int i = 0; i<olen; i++)
{
@@ -1285,8 +1314,9 @@ void ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec,
secure_memzero(out2, olen);
dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%d]: %s", olen, format_hex(out1, olen, 0, &gc));
-
+done:
gc_free(&gc);
+ return ret;
}
#endif
#endif /* ENABLE_CRYPTO_OPENSSL */
@@ -1580,7 +1580,7 @@ key_source2_print(const struct key_source2 *k)
key_source_print(&k->server, "Server");
}
-static void
+static bool
openvpn_PRF(const uint8_t *secret,
int secret_len,
const char *label,
@@ -1593,6 +1593,7 @@ openvpn_PRF(const uint8_t *secret,
uint8_t *output,
int output_len)
{
+ bool ret = true;
/* concatenate seed components */
struct buffer seed = alloc_buf(strlen(label)
@@ -1614,12 +1615,16 @@ openvpn_PRF(const uint8_t *secret,
}
/* compute PRF */
- ssl_tls1_PRF(BPTR(&seed), BLEN(&seed), secret, secret_len, output, output_len);
+ if (!ssl_tls1_PRF(BPTR(&seed), BLEN(&seed), secret, secret_len, output, output_len))
+ {
+ ret = false;
+ }
buf_clear(&seed);
free_buf(&seed);
VALGRIND_MAKE_READABLE((void *)output, output_len);
+ return ret;
}
static void
@@ -1654,8 +1659,8 @@ generate_key_expansion_tls_export(struct tls_session *session, struct key2 *key2
return true;
}
-static struct key2
-generate_key_expansion_openvpn_prf(const struct tls_session *session)
+static bool
+generate_key_expansion_openvpn_prf(const struct tls_session *session, struct key2 *key2)
{
uint8_t master[48] = { 0 };
@@ -1671,33 +1676,40 @@ generate_key_expansion_openvpn_prf(const struct tls_session *session)
key_source2_print(key_src);
/* compute master secret */
- openvpn_PRF(key_src->client.pre_master,
- sizeof(key_src->client.pre_master),
- KEY_EXPANSION_ID " master secret",
- key_src->client.random1,
- sizeof(key_src->client.random1),
- key_src->server.random1,
- sizeof(key_src->server.random1),
- NULL,
- NULL,
- master,
- sizeof(master));
+ if(!openvpn_PRF(key_src->client.pre_master,
+ sizeof(key_src->client.pre_master),
+ KEY_EXPANSION_ID " master secret",
+ key_src->client.random1,
+ sizeof(key_src->client.random1),
+ key_src->server.random1,
+ sizeof(key_src->server.random1),
+ NULL,
+ NULL,
+ master,
+ sizeof(master)))
+ {
+ return false;
+ }
- struct key2 key2;
/* compute key expansion */
- openvpn_PRF(master,
- sizeof(master),
- KEY_EXPANSION_ID " key expansion",
- key_src->client.random2,
- sizeof(key_src->client.random2),
- key_src->server.random2,
- sizeof(key_src->server.random2),
- client_sid,
- server_sid,
- (uint8_t *)key2.keys,
- sizeof(key2.keys));
+ if (!openvpn_PRF(master,
+ sizeof(master),
+ KEY_EXPANSION_ID " key expansion",
+ key_src->client.random2,
+ sizeof(key_src->client.random2),
+ key_src->server.random2,
+ sizeof(key_src->server.random2),
+ client_sid,
+ server_sid,
+ (uint8_t *)key2->keys,
+ sizeof(key2->keys)))
+ {
+ return false;
+ }
secure_memzero(&master, sizeof(master));
+
+
/*
* fixup_key only correctly sets DES parity bits if the cipher is a
* DES variant.
@@ -1712,11 +1724,11 @@ generate_key_expansion_openvpn_prf(const struct tls_session *session)
*/
for (int i = 0; i < 2; ++i)
{
- fixup_key(&key2.keys[i], &session->opt->key_type);
+ fixup_key(&key2->keys[i], &session->opt->key_type);
}
- key2.n = 2;
+ key2->n = 2;
- return key2;
+ return true;
}
/*
@@ -1748,7 +1760,11 @@ generate_key_expansion(struct key_ctx_bi *key,
}
else
{
- key2 = generate_key_expansion_openvpn_prf(session);
+ if (!generate_key_expansion_openvpn_prf(session, &key2))
+ {
+ msg(D_TLS_ERRORS, "TLS Error: PRF calcuation failed");
+ goto exit;
+ }
}
key2_print(&key2, &session->opt->key_type,
We never had handling of this failure condition. But should it happen we can now handle it. Signed-off-by: Arne Schwabe <arne@rfc2549.org> --- src/openvpn/crypto_backend.h | 4 +- src/openvpn/crypto_mbedtls.c | 17 ++++---- src/openvpn/crypto_openssl.c | 50 ++++++++++++++++++----- src/openvpn/ssl.c | 78 ++++++++++++++++++++++-------------- 4 files changed, 99 insertions(+), 50 deletions(-)