I'm attempting to find a client/server authentication protocol that allows the client and server to authenticate each other when the client doesn't know the server secret but does have a sensitive key derived from the secret. 

I would like to just use PKI, but the server in this case is extremely limited in CPU and memory resources, on the order of 16MHz and 32K Ram; but it does have hardware AES support. Speed of the process is critical to the user-experience, but security is paramount.

I was thinking through it and I'd like something like this (The most secure form of each function is implicit):

**ClientID (CID)**: Unique client identifier that ties the token to the client.

**Client Token (CT)**: SHA(CID+Secret)

**Secret (S)**: A secret that the server knows. The server (or a third party that also knows the key) creates tokens through an offline commissioning process.


    Client -> Server
    CID, CNonce

    Server -> Client (Server derives expected CT with secret and CID)
    SNonce, AES(IV=CNonce, K=CT, PT=SNonce)

    Client -> Server
    AES(IV=SNonce, K=CT, PT=CNonce)


This seems to give me a few properties that I need:

 - The client can verify that the server knows the secret because it is able to encrypt SNonce with the derived token.
 - The server can verify that the client has the token because it can successfully encrypt the CNonce.
 - Replay attacks are mitigated by the nonces.
 - MITM attacks mitigated because the token is never transmitted.