summaryrefslogtreecommitdiff
path: root/src/libtls/tls_crypto.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2013-01-02 14:18:20 +0100
committerYves-Alexis Perez <corsac@debian.org>2013-01-02 14:18:20 +0100
commitc1343b3278cdf99533b7902744d15969f9d6fdc1 (patch)
treed5ed3dc5677a59260ec41cd39bb284d3e94c91b3 /src/libtls/tls_crypto.c
parentb34738ed08c2227300d554b139e2495ca5da97d6 (diff)
downloadvyos-strongswan-c1343b3278cdf99533b7902744d15969f9d6fdc1.tar.gz
vyos-strongswan-c1343b3278cdf99533b7902744d15969f9d6fdc1.zip
Imported Upstream version 5.0.1
Diffstat (limited to 'src/libtls/tls_crypto.c')
-rw-r--r--src/libtls/tls_crypto.c96
1 files changed, 66 insertions, 30 deletions
diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c
index 4d84876d0..f74984879 100644
--- a/src/libtls/tls_crypto.c
+++ b/src/libtls/tls_crypto.c
@@ -1196,12 +1196,12 @@ static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash)
return FALSE;
}
hasher = lib->crypto->create_hasher(lib->crypto, alg->hash);
- if (!hasher)
+ if (!hasher || !hasher->allocate_hash(hasher, data, hash))
{
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, alg->hash);
+ DESTROY_IF(hasher);
return FALSE;
}
- hasher->allocate_hash(hasher, data, hash);
hasher->destroy(hasher);
}
else
@@ -1210,20 +1210,20 @@ static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash)
char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
- if (!md5)
+ if (!md5 || !md5->get_hash(md5, data, buf))
{
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5);
+ DESTROY_IF(md5);
return FALSE;
}
- md5->get_hash(md5, data, buf);
md5->destroy(md5);
sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (!sha1)
+ if (!sha1 || !sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5))
{
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1);
+ DESTROY_IF(sha1);
return FALSE;
}
- sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5);
sha1->destroy(sha1);
*hash = chunk_clone(chunk_from_thing(buf));
@@ -1462,7 +1462,11 @@ METHOD(tls_crypto_t, calculate_finished, bool,
{
return FALSE;
}
- this->prf->get_bytes(this->prf, label, seed, 12, out);
+ if (!this->prf->get_bytes(this->prf, label, seed, 12, out))
+ {
+ free(seed.ptr);
+ return FALSE;
+ }
free(seed.ptr);
return TRUE;
}
@@ -1470,7 +1474,7 @@ METHOD(tls_crypto_t, calculate_finished, bool,
/**
* Derive master secret from premaster, optionally save session
*/
-static void derive_master(private_tls_crypto_t *this, chunk_t premaster,
+static bool derive_master(private_tls_crypto_t *this, chunk_t premaster,
chunk_t session, identification_t *id,
chunk_t client_random, chunk_t server_random)
{
@@ -1479,23 +1483,28 @@ static void derive_master(private_tls_crypto_t *this, chunk_t premaster,
/* derive master secret */
seed = chunk_cata("cc", client_random, server_random);
- this->prf->set_key(this->prf, premaster);
- this->prf->get_bytes(this->prf, "master secret", seed,
- sizeof(master), master);
- this->prf->set_key(this->prf, chunk_from_thing(master));
+ if (!this->prf->set_key(this->prf, premaster) ||
+ !this->prf->get_bytes(this->prf, "master secret", seed,
+ sizeof(master), master) ||
+ !this->prf->set_key(this->prf, chunk_from_thing(master)))
+ {
+ return FALSE;
+ }
+
if (this->cache && session.len)
{
this->cache->create(this->cache, session, id, chunk_from_thing(master),
this->suite);
}
memwipe(master, sizeof(master));
+ return TRUE;
}
/**
* Expand key material from master secret
*/
-static void expand_keys(private_tls_crypto_t *this,
+static bool expand_keys(private_tls_crypto_t *this,
chunk_t client_random, chunk_t server_random)
{
chunk_t seed, block, client_write, server_write;
@@ -1513,7 +1522,11 @@ static void expand_keys(private_tls_crypto_t *this,
}
seed = chunk_cata("cc", server_random, client_random);
block = chunk_alloca((mks + eks + ivs) * 2);
- this->prf->get_bytes(this->prf, "key expansion", seed, block.len, block.ptr);
+ if (!this->prf->get_bytes(this->prf, "key expansion", seed,
+ block.len, block.ptr))
+ {
+ return FALSE;
+ }
/* signer keys */
client_write = chunk_create(block.ptr, mks);
@@ -1522,13 +1535,19 @@ static void expand_keys(private_tls_crypto_t *this,
block = chunk_skip(block, mks);
if (this->tls->is_server(this->tls))
{
- this->signer_in->set_key(this->signer_in, client_write);
- this->signer_out->set_key(this->signer_out, server_write);
+ if (!this->signer_in->set_key(this->signer_in, client_write) ||
+ !this->signer_out->set_key(this->signer_out, server_write))
+ {
+ return FALSE;
+ }
}
else
{
- this->signer_out->set_key(this->signer_out, client_write);
- this->signer_in->set_key(this->signer_in, server_write);
+ if (!this->signer_out->set_key(this->signer_out, client_write) ||
+ !this->signer_in->set_key(this->signer_in, server_write))
+ {
+ return FALSE;
+ }
}
/* crypter keys, and IVs if < TLSv1.2 */
@@ -1541,13 +1560,19 @@ static void expand_keys(private_tls_crypto_t *this,
if (this->tls->is_server(this->tls))
{
- this->crypter_in->set_key(this->crypter_in, client_write);
- this->crypter_out->set_key(this->crypter_out, server_write);
+ if (!this->crypter_in->set_key(this->crypter_in, client_write) ||
+ !this->crypter_out->set_key(this->crypter_out, server_write))
+ {
+ return FALSE;
+ }
}
else
{
- this->crypter_out->set_key(this->crypter_out, client_write);
- this->crypter_in->set_key(this->crypter_in, server_write);
+ if (!this->crypter_out->set_key(this->crypter_out, client_write) ||
+ !this->crypter_in->set_key(this->crypter_in, server_write))
+ {
+ return FALSE;
+ }
}
if (ivs)
{
@@ -1574,17 +1599,22 @@ static void expand_keys(private_tls_crypto_t *this,
{
seed = chunk_cata("cc", client_random, server_random);
this->msk = chunk_alloc(64);
- this->prf->get_bytes(this->prf, this->msk_label, seed,
- this->msk.len, this->msk.ptr);
+ if (!this->prf->get_bytes(this->prf, this->msk_label, seed,
+ this->msk.len, this->msk.ptr))
+ {
+ return FALSE;
+ }
}
+ return TRUE;
}
-METHOD(tls_crypto_t, derive_secrets, void,
+METHOD(tls_crypto_t, derive_secrets, bool,
private_tls_crypto_t *this, chunk_t premaster, chunk_t session,
identification_t *id, chunk_t client_random, chunk_t server_random)
{
- derive_master(this, premaster, session, id, client_random, server_random);
- expand_keys(this, client_random, server_random);
+ return derive_master(this, premaster, session, id,
+ client_random, server_random) &&
+ expand_keys(this, client_random, server_random);
}
METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
@@ -1601,8 +1631,11 @@ METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
this->suite = select_cipher_suite(this, &this->suite, 1, KEY_ANY);
if (this->suite)
{
- this->prf->set_key(this->prf, master);
- expand_keys(this, client_random, server_random);
+ if (!this->prf->set_key(this->prf, master) ||
+ !expand_keys(this, client_random, server_random))
+ {
+ this->suite = 0;
+ }
}
chunk_clear(&master);
}
@@ -1719,11 +1752,14 @@ tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache)
switch (tls->get_purpose(tls))
{
case TLS_PURPOSE_EAP_TLS:
- case TLS_PURPOSE_EAP_PEAP:
/* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
this->msk_label = "client EAP encryption";
build_cipher_suite_list(this, FALSE);
break;
+ case TLS_PURPOSE_EAP_PEAP:
+ this->msk_label = "client EAP encryption";
+ build_cipher_suite_list(this, TRUE);
+ break;
case TLS_PURPOSE_EAP_TTLS:
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
this->msk_label = "ttls keying material";