Add a return value to prf_t.get_bytes()
authorMartin Willi <martin@revosec.ch>
Fri, 6 Jul 2012 08:14:29 +0000 (10:14 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 16 Jul 2012 12:53:33 +0000 (14:53 +0200)
13 files changed:
src/libcharon/sa/ikev1/keymat_v1.c
src/libsimaka/simaka_crypto.c
src/libstrongswan/crypto/crypto_tester.c
src/libstrongswan/crypto/prf_plus.c
src/libstrongswan/crypto/prfs/mac_prf.c
src/libstrongswan/crypto/prfs/prf.h
src/libstrongswan/plugins/af_alg/af_alg_prf.c
src/libstrongswan/plugins/fips_prf/fips_prf.c
src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
src/libstrongswan/plugins/pkcs8/pkcs8_builder.c
src/libstrongswan/plugins/sha1/sha1_prf.c
src/libstrongswan/stamp-h1 [new file with mode: 0644]
src/libtls/tls_prf.c

index 77f0a56..2b22b14 100644 (file)
@@ -222,31 +222,38 @@ METHOD(aead_t, aead_destroy, void,
  * Expand SKEYID_e according to Appendix B in RFC 2409.
  * TODO-IKEv1: verify keys (e.g. for weak keys, see Appendix B)
  */
-static chunk_t expand_skeyid_e(chunk_t skeyid_e, size_t key_size, prf_t *prf)
+static bool expand_skeyid_e(chunk_t skeyid_e, size_t key_size, prf_t *prf,
+                                                       chunk_t *ka)
 {
        size_t block_size;
-       chunk_t seed, ka;
+       chunk_t seed;
        int i;
 
        if (skeyid_e.len >= key_size)
        {       /* no expansion required, reduce to key_size */
                skeyid_e.len = key_size;
-               return skeyid_e;
+               *ka = skeyid_e;
+               return TRUE;
        }
        block_size = prf->get_block_size(prf);
-       ka = chunk_alloc((key_size / block_size + 1) * block_size);
-       ka.len = key_size;
+       *ka = chunk_alloc((key_size / block_size + 1) * block_size);
+       ka->len = key_size;
 
        /* Ka = K1 | K2 | ..., K1 = prf(SKEYID_e, 0), K2 = prf(SKEYID_e, K1) ... */
        prf->set_key(prf, skeyid_e);
        seed = octet_0;
        for (i = 0; i < key_size; i += block_size)
        {
-               prf->get_bytes(prf, seed, ka.ptr + i);
-               seed = chunk_create(ka.ptr + i, block_size);
+               if (!prf->get_bytes(prf, seed, ka->ptr + i))
+               {
+                       chunk_clear(ka);
+                       chunk_clear(&skeyid_e);
+                       return FALSE;
+               }
+               seed = chunk_create(ka->ptr + i, block_size);
        }
        chunk_clear(&skeyid_e);
-       return ka;
+       return TRUE;
 }
 
 /**
@@ -276,7 +283,10 @@ static aead_t *create_aead(proposal_t *proposal, prf_t *prf, chunk_t skeyid_e)
                return NULL;
        }
        key_size = crypter->get_key_size(crypter);
-       ka = expand_skeyid_e(skeyid_e, crypter->get_key_size(crypter), prf);
+       if (!expand_skeyid_e(skeyid_e, crypter->get_key_size(crypter), prf, &ka))
+       {
+               return NULL;
+       }
        DBG4(DBG_IKE, "encryption key Ka %B", &ka);
        crypter->set_key(crypter, ka);
        chunk_clear(&ka);
index 0a92cb3..532655e 100644 (file)
@@ -133,7 +133,12 @@ METHOD(simaka_crypto_t, derive_keys_full, bool,
        str = chunk_alloca(this->prf->get_block_size(this->prf) * 3);
        for (i = 0; i < 3; i++)
        {
-               this->prf->get_bytes(this->prf, chunk_empty, str.ptr + str.len / 3 * i);
+               if (!this->prf->get_bytes(this->prf, chunk_empty,
+                                                                 str.ptr + str.len / 3 * i))
+               {
+                       chunk_clear(mk);
+                       return FALSE;
+               }
        }
 
        k_encr = chunk_create(str.ptr, KENCR_LEN);
@@ -166,7 +171,11 @@ METHOD(simaka_crypto_t, derive_keys_reauth, bool,
        str = chunk_alloca(this->prf->get_block_size(this->prf) * 2);
        for (i = 0; i < 2; i++)
        {
-               this->prf->get_bytes(this->prf, chunk_empty, str.ptr + str.len / 2 * i);
+               if (!this->prf->get_bytes(this->prf, chunk_empty,
+                                                                 str.ptr + str.len / 2 * i))
+               {
+                       return FALSE;
+               }
        }
        k_encr = chunk_create(str.ptr, KENCR_LEN);
        k_auth = chunk_create(str.ptr + KENCR_LEN, KAUTH_LEN);
@@ -202,7 +211,11 @@ METHOD(simaka_crypto_t, derive_keys_reauth_msk, bool,
        str = chunk_alloca(this->prf->get_block_size(this->prf) * 2);
        for (i = 0; i < 2; i++)
        {
-               this->prf->get_bytes(this->prf, chunk_empty, str.ptr + str.len / 2 * i);
+               if (!this->prf->get_bytes(this->prf, chunk_empty,
+                                                                 str.ptr + str.len / 2 * i))
+               {
+                       return FALSE;
+               }
        }
        *msk = chunk_create(str.ptr, MSK_LEN);
        DBG3(DBG_LIB, "MSK %B", msk);
index b978553..4690593 100644 (file)
@@ -797,8 +797,10 @@ static u_int bench_prf(private_crypto_tester_t *this,
                start_timing(&start);
                while (end_timing(&start) < this->bench_time)
                {
-                       prf->get_bytes(prf, buf, bytes);
-                       runs++;
+                       if (prf->get_bytes(prf, buf, bytes))
+                       {
+                               runs++;
+                       }
                }
                free(buf.ptr);
                prf->destroy(prf);
@@ -860,7 +862,10 @@ METHOD(crypto_tester_t, test_prf, bool,
                {
                        prf->set_key(prf, key);
                }
-               prf->get_bytes(prf, seed, out.ptr);
+               if (!prf->get_bytes(prf, seed, out.ptr))
+               {
+                       failed = TRUE;
+               }
                if (!memeq(vector->out, out.ptr, out.len))
                {
                        failed = TRUE;
@@ -874,8 +879,11 @@ METHOD(crypto_tester_t, test_prf, bool,
                                prf->set_key(prf, key);
                        }
                        prf->allocate_bytes(prf, chunk_create(seed.ptr, 1), NULL);
-                       prf->get_bytes(prf, chunk_create(seed.ptr + 1, 1), NULL);
-                       prf->get_bytes(prf, chunk_skip(seed, 2), out.ptr);
+                       if (!prf->get_bytes(prf, chunk_create(seed.ptr + 1, 1), NULL) ||
+                               !prf->get_bytes(prf, chunk_skip(seed, 2), out.ptr))
+                       {
+                               failed = TRUE;
+                       }
                        if (!memeq(vector->out, out.ptr, out.len))
                        {
                                failed = TRUE;
index 2e7f87d..94be1d5 100644 (file)
@@ -66,17 +66,27 @@ METHOD(prf_plus_t, get_bytes, bool,
        {
                if (this->buffer.len == this->used)
                {       /* buffer used, get next round */
-                       this->prf->get_bytes(this->prf, this->buffer, NULL);
+                       if (!this->prf->get_bytes(this->prf, this->buffer, NULL))
+                       {
+                               return FALSE;
+                       }
                        if (this->counter)
                        {
-                               this->prf->get_bytes(this->prf, this->seed, NULL);
-                               this->prf->get_bytes(this->prf, chunk_from_thing(this->counter),
-                                                                        this->buffer.ptr);
+                               if (!this->prf->get_bytes(this->prf, this->seed, NULL) ||
+                                       !this->prf->get_bytes(this->prf,
+                                                       chunk_from_thing(this->counter), this->buffer.ptr))
+                               {
+                                       return FALSE;
+                               }
                                this->counter++;
                        }
                        else
                        {
-                               this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr);
+                               if (!this->prf->get_bytes(this->prf, this->seed,
+                                                                                 this->buffer.ptr))
+                               {
+                                       return FALSE;
+                               }
                        }
                        this->used = 0;
                }
@@ -131,14 +141,22 @@ prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed)
        if (counter)
        {
                this->counter = 0x01;
-               this->prf->get_bytes(this->prf, this->seed, NULL);
-               this->prf->get_bytes(this->prf, chunk_from_thing(this->counter),
-                                                        this->buffer.ptr);
+               if (!this->prf->get_bytes(this->prf, this->seed, NULL) ||
+                       !this->prf->get_bytes(this->prf, chunk_from_thing(this->counter),
+                                                                 this->buffer.ptr))
+               {
+                       destroy(this);
+                       return NULL;
+               }
                this->counter++;
        }
        else
        {
-               this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr);
+               if (!this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr))
+               {
+                       destroy(this);
+                       return NULL;
+               }
        }
 
        return &this->public;
index 6215a4b..489797f 100644 (file)
@@ -35,10 +35,11 @@ struct private_prf_t {
        mac_t *mac;
 };
 
-METHOD(prf_t, get_bytes, void,
+METHOD(prf_t, get_bytes, bool,
        private_prf_t *this, chunk_t seed, u_int8_t *buffer)
 {
        this->mac->get_mac(this->mac, seed, buffer);
+       return TRUE;
 }
 
 METHOD(prf_t, allocate_bytes, void,
index ad15205..8b98b41 100644 (file)
@@ -71,13 +71,16 @@ extern enum_name_t *pseudo_random_function_names;
  * Generic interface for pseudo-random-functions.
  */
 struct prf_t {
+
        /**
         * Generates pseudo random bytes and writes them in the buffer.
         *
         * @param seed          a chunk containing the seed for the next bytes
         * @param buffer        pointer where the generated bytes will be written
+        * @return                      TRUE if bytes generated successfully
         */
-       void (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer);
+       __attribute__((warn_unused_result))
+       bool (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer);
 
        /**
         * Generates pseudo random bytes and allocate space for them.
index a791229..5b12adf 100644 (file)
@@ -105,10 +105,11 @@ static size_t lookup_alg(pseudo_random_function_t algo, char **name, bool *xcbc)
        return 0;
 }
 
-METHOD(prf_t, get_bytes, void,
+METHOD(prf_t, get_bytes, bool,
        private_af_alg_prf_t *this, chunk_t seed, u_int8_t *buffer)
 {
        this->ops->hash(this->ops, seed, buffer, this->block_size);
+       return TRUE;
 }
 
 METHOD(prf_t, allocate_bytes, void,
index c066636..ae5ed98 100644 (file)
@@ -48,7 +48,7 @@ struct private_fips_prf_t {
        /**
         * G function, either SHA1 or DES
         */
-       void (*g)(private_fips_prf_t *this, chunk_t c, u_int8_t res[]);
+       bool (*g)(private_fips_prf_t *this, chunk_t c, u_int8_t res[]);
 };
 
 /**
@@ -106,7 +106,7 @@ static void chunk_mod(size_t length, chunk_t chunk, u_int8_t buffer[])
  * 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
  * 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16
  */
-METHOD(prf_t, get_bytes, void,
+METHOD(prf_t, get_bytes, bool,
        private_fips_prf_t *this, chunk_t seed, u_int8_t w[])
 {
        int i;
@@ -138,6 +138,8 @@ METHOD(prf_t, get_bytes, void,
        }
 
        /* 3.3 done already, mod q not used */
+
+       return TRUE;
 }
 
 METHOD(prf_t, get_block_size, size_t,
@@ -168,7 +170,7 @@ METHOD(prf_t, set_key, void,
 /**
  * Implementation of the G() function based on SHA1
  */
-void g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[])
+static bool g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[])
 {
        u_int8_t buf[64];
 
@@ -188,7 +190,11 @@ void g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[])
 
        /* use the keyed hasher, but use an empty key to use SHA1 IV */
        this->keyed_prf->set_key(this->keyed_prf, chunk_empty);
-       this->keyed_prf->get_bytes(this->keyed_prf, c, res);
+       if (!this->keyed_prf->get_bytes(this->keyed_prf, c, res))
+       {
+               return FALSE;
+       }
+       return TRUE;
 }
 
 METHOD(prf_t, destroy, void,
index 20f2fa9..03b7fa0 100644 (file)
@@ -35,7 +35,7 @@ struct private_openssl_sha1_prf_t {
        SHA_CTX ctx;
 };
 
-METHOD(prf_t, get_bytes, void,
+METHOD(prf_t, get_bytes, bool,
        private_openssl_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes)
 {
        SHA1_Update(&this->ctx, seed.ptr, seed.len);
@@ -50,6 +50,8 @@ METHOD(prf_t, get_bytes, void,
                hash[3] = htonl(this->ctx.h3);
                hash[4] = htonl(this->ctx.h4);
        }
+
+       return TRUE;
 }
 
 METHOD(prf_t, get_block_size, size_t,
index d34a185..e9ea923 100644 (file)
@@ -126,7 +126,7 @@ static bool verify_padding(chunk_t *blob)
 /**
  * Prototype for key derivation functions.
  */
-typedef void (*kdf_t)(void *generator, chunk_t password, chunk_t salt,
+typedef bool (*kdf_t)(void *generator, chunk_t password, chunk_t salt,
                                          u_int64_t iterations, chunk_t key);
 
 /**
@@ -164,7 +164,10 @@ static private_key_t *decrypt_private_key(chunk_t blob,
        {
                chunk_t decrypted;
 
-               kdf(generator, shared->get_key(shared), salt, iterations, keymat);
+               if (!kdf(generator, shared->get_key(shared), salt, iterations, keymat))
+               {
+                       continue;
+               }
 
                crypter->set_key(crypter, key);
                crypter->decrypt(crypter, blob, iv, &decrypted);
@@ -188,27 +191,34 @@ static private_key_t *decrypt_private_key(chunk_t blob,
 /**
  * Function F of PBKDF2
  */
-static void pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed,
+static bool pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed,
                                         u_int64_t iterations)
 {
        chunk_t u;
        u_int64_t i;
 
        u = chunk_alloca(prf->get_block_size(prf));
-       prf->get_bytes(prf, seed, u.ptr);
+       if (!prf->get_bytes(prf, seed, u.ptr))
+       {
+               return FALSE;
+       }
        memcpy(block.ptr, u.ptr, block.len);
 
        for (i = 1; i < iterations; i++)
        {
-               prf->get_bytes(prf, u, u.ptr);
+               if (!prf->get_bytes(prf, u, u.ptr))
+               {
+                       return FALSE;
+               }
                memxor(block.ptr, u.ptr, block.len);
        }
+       return TRUE;
 }
 
 /**
  * PBKDF2 key derivation function
  */
-static void pbkdf2(prf_t *prf, chunk_t password, chunk_t salt,
+static bool pbkdf2(prf_t *prf, chunk_t password, chunk_t salt,
                                   u_int64_t iterations, chunk_t key)
 {
        chunk_t keymat, block, seed;
@@ -228,10 +238,15 @@ static void pbkdf2(prf_t *prf, chunk_t password, chunk_t salt,
        {
                *ni = htonl(i + 1);
                block.ptr = keymat.ptr + (i * block.len);
-               pbkdf2_f(block, prf, seed, iterations);
+               if (!pbkdf2_f(block, prf, seed, iterations))
+               {
+                       return FALSE;
+               }
        }
 
        memcpy(key.ptr, keymat.ptr, key.len);
+
+       return TRUE;
 }
 
 /**
@@ -266,7 +281,7 @@ static private_key_t *decrypt_private_key_pbes2(chunk_t blob,
 /**
  * PBKDF1 key derivation function
  */
-static void pbkdf1(hasher_t *hasher, chunk_t password, chunk_t salt,
+static bool pbkdf1(hasher_t *hasher, chunk_t password, chunk_t salt,
                                   u_int64_t iterations, chunk_t key)
 {
        chunk_t hash;
@@ -282,6 +297,8 @@ static void pbkdf1(hasher_t *hasher, chunk_t password, chunk_t salt,
        }
 
        memcpy(key.ptr, hash.ptr, key.len);
+
+       return TRUE;
 }
 
 /**
index 11f588c..f3e44ed 100644 (file)
@@ -59,7 +59,7 @@ struct private_sha1_prf_t {
  */
 extern void SHA1Update(private_sha1_hasher_t* this, u_int8_t *data, u_int32_t len);
 
-METHOD(prf_t, get_bytes, void,
+METHOD(prf_t, get_bytes, bool,
        private_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes)
 {
        u_int32_t *hash = (u_int32_t*)bytes;
@@ -71,6 +71,8 @@ METHOD(prf_t, get_bytes, void,
        hash[2] = htonl(this->hasher->state[2]);
        hash[3] = htonl(this->hasher->state[3]);
        hash[4] = htonl(this->hasher->state[4]);
+
+       return TRUE;
 }
 
 METHOD(prf_t, get_block_size, size_t,
diff --git a/src/libstrongswan/stamp-h1 b/src/libstrongswan/stamp-h1
new file mode 100644 (file)
index 0000000..f887801
--- /dev/null
@@ -0,0 +1 @@
+timestamp for src/libstrongswan/config.h
index 09f6934..bc0a8c1 100644 (file)
@@ -56,12 +56,15 @@ static bool p_hash(prf_t *prf, char *label, chunk_t seed, size_t block_size,
 
        while (TRUE)
        {
-               /* A(i) = HMAC_hash(secret, A(i-1)) */
-               prf->get_bytes(prf, a, abuf);
                a = chunk_from_thing(abuf);
-               /* HMAC_hash(secret, A(i) + seed) */
-               prf->get_bytes(prf, a, NULL);
-               prf->get_bytes(prf, seed, buf);
+               /* A(i) = HMAC_hash(secret, A(i-1))
+                * HMAC_hash(secret, A(i) + seed) */
+               if (!prf->get_bytes(prf, a, abuf) ||
+                       !prf->get_bytes(prf, a, NULL) ||
+                       !prf->get_bytes(prf, seed, buf))
+               {
+                       return FALSE;
+               }
 
                if (bytes <= block_size)
                {