Unfortunately you have stretched my C expertise past its limit there

What is actually wrong with the existing (ST) code assuming the buffers are explicitly 4-aligned?
Just because you do 16 stores, does not mean you have to do exactly 16 loads, too.
I think it
does.
AIUI, if a RAM buffer, accessed as uint32, is not 4-aligned, and given that in many/most cases the 32F4
requires a 32 bit reg to be written (and sometimes read, too, AFAIK, especially status registers where a read clears a bit so you need to read all 32 in one go) via a
32 bit variable, a 16 word move from RAM to a 32 bit reg will perform
64 RAM reads and 16 register writes, or the opposite (16 reg reads and 64 RAM writes). Nobody is likely to notice because the RAM access is zero wait state (7ns cycle time) but it will be slower by 336ns (48x7).
FWIW the code shows the stupidity of ST code because dma=0 always (on USB FS; only USB HS uses DMA)

I see I removed that test from one of the two functions...