@@ -1419,183 +1419,14 @@
return ret;
}
#else /* if defined(LIBRESSL_VERSION_NUMBER) */
-/*
- * Generate the hash required by for the \c tls1_PRF function.
- *
- * We cannot use our normal hmac_* function as they do not work
- * in a FIPS environment (no MD5 allowed, which we need). Instead
- * we need to directly use the EVP_MD_* API with the special
- * EVP_MD_CTX_FLAG_NON_FIPS_ALLOW flag.
- *
- * The function below is adapted from OpenSSL 1.0.2t
- *
- * @param md_kt Message digest to use
- * @param sec Secret to base the hash on
- * @param sec_len Length of the secret
- * @param seed Seed to hash
- * @param seed_len Length of the seed
- * @param out Output buffer
- * @param olen Length of the output buffer
- */
-static
-bool
-tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
- int sec_len, const void *seed, int seed_len,
- unsigned char *out, int olen)
-{
- int chunk;
- size_t j;
- EVP_MD_CTX *ctx, *ctx_tmp, *ctx_init;
- EVP_PKEY *mac_key;
- unsigned char A1[EVP_MAX_MD_SIZE];
- size_t A1_len = EVP_MAX_MD_SIZE;
- int ret = false;
-
- chunk = EVP_MD_size(md);
- OPENSSL_assert(chunk >= 0);
-
- ctx = md_ctx_new();
- ctx_tmp = md_ctx_new();
- ctx_init = md_ctx_new();
- EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
- if (!mac_key)
- {
- goto err;
- }
- if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
- {
- goto err;
- }
- if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
- {
- goto err;
- }
- if (!EVP_DigestSignUpdate(ctx, seed, seed_len))
- {
- goto err;
- }
- if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
- {
- goto err;
- }
-
- for (;; )
- {
- /* Reinit mac contexts */
- if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
- {
- goto err;
- }
- if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
- {
- goto err;
- }
- if (olen > chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
- {
- goto err;
- }
- if (!EVP_DigestSignUpdate(ctx, seed, seed_len))
- {
- goto err;
- }
-
- if (olen > chunk)
- {
- j = olen;
- if (!EVP_DigestSignFinal(ctx, out, &j))
- {
- goto err;
- }
- out += j;
- olen -= j;
- /* calc the next A1 value */
- if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
- {
- goto err;
- }
- }
- else
- {
- A1_len = EVP_MAX_MD_SIZE;
- /* last one */
- if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
- {
- goto err;
- }
- memcpy(out, A1, olen);
- break;
- }
- }
- ret = true;
-err:
- EVP_PKEY_free(mac_key);
- EVP_MD_CTX_free(ctx);
- EVP_MD_CTX_free(ctx_tmp);
- EVP_MD_CTX_free(ctx_init);
- OPENSSL_cleanse(A1, sizeof(A1));
- return ret;
-}
-
-/*
- * Use the TLS PRF function for generating data channel keys.
- * This code is based on the OpenSSL library.
- *
- * TLS generates keys as such:
- *
- * master_secret[48] = PRF(pre_master_secret[48], "master secret",
- * ClientHello.random[32] + ServerHello.random[32])
- *
- * key_block[] = PRF(SecurityParameters.master_secret[48],
- * "key expansion",
- * SecurityParameters.server_random[32] +
- * SecurityParameters.client_random[32]);
- *
- * Notes:
- *
- * (1) key_block contains a full set of 4 keys.
- * (2) The pre-master secret is generated by the client.
- */
+/* LibreSSL does not expose a TLS 1.0/1.1 PRF via the same APIs as
+ * OpenSSL does. As result LibreSSL will only be able to support
+ * peers that support TLS EKM like when running with OpenSSL 3.x FIPS */
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_get("MD5") fails otherwise in the unit test */
- const EVP_MD *md5 = EVP_md5();
- const EVP_MD *sha1 = EVP_sha1();
-
- uint8_t *out2 = (uint8_t *)gc_malloc(olen, false, &gc);
-
- int len = slen/2;
- const uint8_t *S1 = sec;
- const uint8_t *S2 = &(sec[len]);
- len += (slen&1); /* add for odd, make longer */
-
- if (!tls1_P_hash(md5, S1, len, label, label_len, out1, olen))
- {
- ret = false;
- goto done;
- }
-
- if (!tls1_P_hash(sha1, S2, len, label, label_len, out2, olen))
- {
- ret = false;
- goto done;
- }
-
- for (int i = 0; i < olen; i++)
- {
- out1[i] ^= out2[i];
- }
-
- 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;
+ return false;
}
#endif /* if LIBRESSL_VERSION_NUMBER */
#endif /* ENABLE_CRYPTO_OPENSSL */
Attention is currently required from: flichtenheld. Hello flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/560?usp=email to review the following change. Change subject: Remove custom TLS 1.0 PRF implementation only used by LibreSSL ...................................................................... Remove custom TLS 1.0 PRF implementation only used by LibreSSL After the removal of the OpenSSL 1.0.2 support, LibreSSL is the only library that still needs the custom implementation. Since our LibreSSL support is always best effort, we can afford to limit LibreSSL support in this way. Change-Id: I5bfa3630ad4dff2807705658bc877c4a429a39ce Signed-off-by: Arne Schwabe <arne@rfc2549.org> --- M src/openvpn/crypto_openssl.c 1 file changed, 4 insertions(+), 173 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/60/560/1