Check rng return value when generating secrets and IVs in libtls
authorTobias Brunner <tobias@strongswan.org>
Mon, 25 Jun 2012 14:04:40 +0000 (16:04 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 16 Jul 2012 12:53:37 +0000 (14:53 +0200)
src/libtls/tls_peer.c
src/libtls/tls_protection.c
src/libtls/tls_server.c

index 068dd3a..65072d0 100644 (file)
@@ -709,13 +709,15 @@ static status_t send_client_hello(private_tls_peer_t *this,
 
        htoun32(&this->client_random, time(NULL));
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       if (!rng)
+       if (!rng ||
+               !rng->get_bytes(rng, sizeof(this->client_random) - 4,
+                                               this->client_random + 4))
        {
-               DBG1(DBG_TLS, "no suitable RNG found to generate client random");
+               DBG1(DBG_TLS, "failed to generate client random");
                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               DESTROY_IF(rng);
                return NEED_MORE;
        }
-       rng->get_bytes(rng, sizeof(this->client_random) - 4, this->client_random + 4);
        rng->destroy(rng);
 
        /* TLS version */
@@ -903,13 +905,13 @@ static status_t send_key_exchange_encrypt(private_tls_peer_t *this,
        chunk_t encrypted;
 
        rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
-       if (!rng)
+       if (!rng || !rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2))
        {
-               DBG1(DBG_TLS, "no suitable RNG found for TLS premaster secret");
+               DBG1(DBG_TLS, "failed to generate TLS premaster secret");
                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               DESTROY_IF(rng);
                return NEED_MORE;
        }
-       rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2);
        rng->destroy(rng);
        htoun16(premaster, TLS_1_2);
 
index 7120ca8..a92e902 100644 (file)
@@ -243,14 +243,14 @@ METHOD(tls_protection_t, build, status_t,
                                }
                                else
                                {       /* TLSv1.1 uses random IVs, prepended to record */
-                                       if (!this->rng)
+                                       iv.len = this->crypter_out->get_iv_size(this->crypter_out);
+                                       if (!this->rng ||
+                                               !this->rng->allocate_bytes(this->rng, iv.len, &iv))
                                        {
-                                               DBG1(DBG_TLS, "no RNG supported to generate TLS IV");
+                                               DBG1(DBG_TLS, "failed to generate TLS IV");
                                                free(data->ptr);
                                                return FAILED;
                                        }
-                                       iv.len = this->crypter_out->get_iv_size(this->crypter_out);
-                                       this->rng->allocate_bytes(this->rng, iv.len, &iv);
                                }
 
                                *data = chunk_cat("mmcc", *data, mac, padding,
index 8d6a933..c8fa276 100644 (file)
@@ -266,13 +266,15 @@ static status_t process_client_hello(private_tls_server_t *this,
 
        htoun32(&this->server_random, time(NULL));
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       if (!rng)
+       if (!rng ||
+               !rng->get_bytes(rng, sizeof(this->server_random) - 4,
+                                               this->server_random + 4))
        {
-               DBG1(DBG_TLS, "no suitable RNG found to generate server random");
+               DBG1(DBG_TLS, "failed to generate server random");
                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               DESTROY_IF(rng);
                return NEED_MORE;
        }
-       rng->get_bytes(rng, sizeof(this->server_random) - 4, this->server_random + 4);
        rng->destroy(rng);
 
        if (!this->tls->set_version(this->tls, version))
@@ -407,13 +409,13 @@ static status_t process_key_exchange_encrypted(private_tls_server_t *this,
        htoun16(premaster, this->client_version);
        /* pre-randomize premaster for failure cases */
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       if (!rng)
+       if (!rng || !rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2))
        {
-               DBG1(DBG_TLS, "creating RNG failed");
+               DBG1(DBG_TLS, "failed to generate premaster secret");
                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               DESTROY_IF(rng);
                return NEED_MORE;
        }
-       rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2);
        rng->destroy(rng);
 
        if (this->private &&