The generic way to handle this sort of with HttpClient is to use a HttpMessageHandler as you might other work to do e.g. adding authorization headers, signing the message etc.
I've also re-written this using Task based syntax as it's more ideomatic HttpClient - the caller can call .Result as needed.
private await Task<System.IO.Stream> Upload(string url, string param1, Stream fileStream, byte[] fileBytes)
{
    HttpContent stringContent = new StringContent(param1);
    HttpContent fileStreamContent = new StreamContent(fileStream);
    HttpContent bytesContent = new ByteArrayContent(fileBytes);
    var handler = new HttpClientHandler();
    var md5Handler = new RequestContentMd5Handler();
    md5Handler.InnerHandler = handler;
    using (HttpClient client = new HttpClient(md5Handler))
    {
        using (MultipartFormDataContent formData = new MultipartFormDataContent())
        {
            formData.Add(stringContent, "param1", "param1");
            formData.Add(fileStreamContent, "file1", "file1");
            formData.Add(bytesContent, "file2", "file2");
            using (var response = await client.PostAsync(url, formData))
            {
                if (!response.IsSuccessStatusCode)
                {
                    return null;
                }
                return await response.Content.ReadAsStreamAsync();
            }
        }
    }
}
Also, it's generally poor practice to re-create the HttpClient on each request (see What is the overhead of creating a new HttpClient per call in a WebAPI client? etc), but I've left that here in keeping with the style of the question.
Here's the handler used...
/// <summary>
/// Handler to assign the MD5 hash value if content is present
/// </summary>
public class RequestContentMd5Handler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Content == null)
        {
            return await base.SendAsync(request, cancellationToken);
        }
        await request.Content.AssignMd5Hash();
        var response = await base.SendAsync(request, cancellationToken);
        return response;
    }
}
And the extensions methods...
    /// <summary>
    /// Compute and assign the MD5 hash of the content.
    /// </summary>
    /// <param name="httpContent"></param>
    /// <returns></returns>
    public static async Task AssignMd5Hash(this HttpContent httpContent)
    {
        var hash = await httpContent.ComputeMd5Hash();
        httpContent.Headers.ContentMD5 = hash;
    }
    /// <summary>
    /// Compute the MD5 hash of the content.
    /// </summary>
    /// <param name="httpContent"></param>
    /// <returns></returns>
    public static async Task<byte[]> ComputeMd5Hash(this HttpContent httpContent)
    {
        using (var md5 = MD5.Create())
        {
            var content = await httpContent.ReadAsStreamAsync();
            var hash = md5.ComputeHash(content);
            return hash;
        }
    }
Makes it easy to unit test the various parts.