You should use the factory pattern to manufacture specific converters for each Enum type as you encounter it:
public class CustomEnumConverter : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert) => typeToConvert.IsEnum; // Add anything additional here such as typeToConvert.IsEnumWithDescription() to check for description attributes.
    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) =>
        (JsonConverter)Activator.CreateInstance(typeof(CustomConverter<>).MakeGenericType(typeToConvert))!;
    class CustomConverter<T> : JsonConverter<T> where T : struct, Enum
    {
        public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
            reader.GetString()!.GetEnumValue<T>()!;
        public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) =>
            writer.WriteStringValue(value.GetDescription<T>());
    }
}
A factory converter can be applied directly to properties as well as long as the factory can return a converter for the property's type, so there is no need to make the inner converter public:
public class Model
{
    [JsonConverter(typeof(CustomEnumConverter))]
    public SomeEnum? SomeEnum { get; set; }
}
In fact, the built-in JsonStringEnumConverter is also implemented via the factory pattern.
Demo fiddle here.