> It's still not clear to me why the EVP functions provide a significant advantage
In case of EVP_... your code is not hardcoding the hash type. You can provide the hash by its name in the config file without any code changes in the app. When using hash contexts directly, you're stuck with what you implement.
That's what I figured when I implemented it. In my application I'm fine hardcoding the hash type because if we have to change hashes away from SHA-2 we have to update all of the equipment in the field anyway, so we might as well update the software at the same time.
E: It also helps that the code with the hardcoded hash type is much easier to understand than the equivalent EVP code.
In case of EVP_... your code is not hardcoding the hash type. You can provide the hash by its name in the config file without any code changes in the app. When using hash contexts directly, you're stuck with what you implement.