I'm writing a wrapper for a chat program to allow for end-to-end encryption. I'm using Python and PyCrypto to accomplish this. I'd like to use a well known library to do this, but to my knowledge, none exist that do what I'm looking for.
Here's the design of the handshake protocol.
Alice and Bob have previously generated long-term RSA-2048 keys $A$ and $B$ for signing. Alice initiates an encrypted connection with Bob by creating a new session RSA-2048 key $S$. Alice signs $[S_{public}, \text{"Alice"}]$ with $A_{private}$ using PSS padding to get $Sig_A$.
$$[A_{public}, S_{public}, \text{"Alice"}, Sig_A]$$
Revision: Alice includes her identity in the signature.
Side note: The generation of a new RSA-2048 key is for forward security. I realize generating a new RSA-2048 key is inefficient, but I have no good way of using ECC or Diffie-Hellman.
Bob then verifies $Sig_A$, rejecting the connection if it fails. Bob then matches $A_{public}$ against a list of known trusted keys. Bob then generates a random 512-bit shared secret $Sec$ and encrypts it with $S_{public}$ using OAEP padding to get $EncSec$. Bob signs $[EncSec, A_{public}, S_{public}, \text{"Alice"}, \text{"Bob"}]$ with $B_{private}$ using PSS padding to get $Sig_B$, and then sends the following:
Revision: $A_{public}$, $S_{public}$, and both party's identities are included in SigB.
$$[B_{public}, EncSec, \text{"Bob"}, Sig_B]$$
Alice verifies $Sig_B$, rejecting the connection if it fails. Alice matches $B_{public}$ against her own list of trusted keys. Alice decrypts $EncSec$ with $S_{private}$ to get $Sec$.
Revision: Alice signs $[EncSec, B_{public}, \text{"Alice"}, \text{"Bob"}]$ as $Sig_C$ and sends this to Bob. Bob then verifies $Sig_C$ and rejects the connection if it fails.
At this point, the users would each get a notification showing the fingerprint of the person they are talking to, and whether or not they have been matched against a known list of trusted keys. Fingerprints are generated as $SHA256(RSAPublicKey)$ truncated to 16 hex characters, with a colon added every 4 characters. This fingerprint can be verified with some hard-to-spoof method, such as a phone call.
Alice and Bob have now verified each other's identities and shared a secret value. They both derive encryption and MAC keys like this.
$$EncKey = HMAC_{SHA256}("0", Sec)$$ $$MACKey = HMAC_{SHA256}("1", Sec)$$
Note that the "0" and "1" are strings of length 1 each, not the literal numeric values 0 and 1.
Encrypting and sending a message happens like this. (Assuming $M$ is the message, and $Rand(x)$ is a cryptographic random number generator that returns $x$ random bits)
$$IV = Rand(128)$$ $$C = AES_{CFB}(M, EncKey, IV)$$ $$MAC = HMAC_{SHA256}(IV || C, MACKey)$$
$IV || C || MAC$ is then transmitted. On the receiving end, $MAC$ is checked, and the message is rejected if it fails. Otherwise, the message is decrypted and displayed.
Are there any problems with this? (Other than the obvious "don't roll your own crypto", as I'm fairly backed into a corner here)