Abstracting primitives and modes of operation
It is not a good idea to try and find abstractions at places where there is no fundamental reason for them to exist. That there is some "accidental" structure in the way encryption or hash methods are build up does not say anything about future encryption or hash functions.

Besides, you may need to apply specific protections against e.g. side channel attacks. It would be a shame if your carefully build software design would be in the way of creating a more secure library.

Note that if there is no fundamental reason for specific abstractions, there may not be any advantage in creating them. E.g. you would not see too many advantages regarding code duplication.

Many algorithms have specific naming conventions and reference implementations. You should not want to shoehorn those into your design.