The issue was that I was not including the last 8 bytes in the exchange message because I had the message exchange length set 8 bytes too short. The print outs I added for debugging looked correct because I was using the individual element's lengths, but the message I was hashing for server verification was actually missing the last 8 bytes.