From 2ae2d6dcdff21bb4b40b4127e878980dada29a96 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 10 Dec 2014 21:01:22 -0800 Subject: [PATCH] 1. Fixed bug with GenerateKey() that didn't take into account secret padding. 2. Fixed bug in DoPacket() that didn't increment the peer's packet sequence. 3. Fixed bug in Decrypt() where the AesCbcDecrypt case dropped through into error. 4. Refactoring the accept state machine. 5. Separating client and server block and MAC sizes. 6. Added client MAC checking. 7. Fixed bug where algorithm picking preferred server order over client. 8. Fixed bug where the algorithm list matching was checking out of bounds. --- src/internal.c | 125 ++++++++++++++++++++++++++++++++------------- src/ssh.c | 40 ++++++++++----- wolfssh/error.h | 3 +- wolfssh/internal.h | 37 ++++++++------ 4 files changed, 139 insertions(+), 66 deletions(-) diff --git a/src/internal.c b/src/internal.c index 64762d5..465f90f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -127,6 +127,9 @@ const char* GetErrorString(int err) case WS_DECRYPT_E: return "decrypt error"; + case WS_MAC_E: + return "verify mac error"; + default: return "Unknown error code"; } @@ -181,7 +184,7 @@ uint8_t NameToId(const char* name, uint32_t nameSz) const char* IdToName(uint8_t id) { - const char* name = NULL; + const char* name = "unknown"; uint32_t i; for (i = 0; i < (sizeof(NameIdMap)/sizeof(NameIdPair)); i++) { @@ -430,7 +433,7 @@ static int GetInputData(WOLFSSH* ssh, uint32_t size) maxLength = ssh->inputBuffer.bufferSz - usedLength; inSz = (int)(size - usedLength); /* from last partial read */ - WLOG(WS_LOG_DEBUG, "GID: size = %d", size); + WLOG(WS_LOG_DEBUG, "GID: size = %u", size); WLOG(WS_LOG_DEBUG, "GID: usedLength = %d", usedLength); WLOG(WS_LOG_DEBUG, "GID: maxLength = %d", maxLength); WLOG(WS_LOG_DEBUG, "GID: inSz = %d", inSz); @@ -571,7 +574,7 @@ static uint8_t MatchIdLists(const uint8_t* left, uint32_t leftSz, if (left != NULL && leftSz > 0 && right != NULL && rightSz > 0) { for (i = 0; i < leftSz; i++) { - for (j = 0; i < rightSz; j++) { + for (j = 0; j < rightSz; j++) { if (left[i] == right[j]) { WLOG(WS_LOG_DEBUG, "MID: matched %s", IdToName(left[i])); return left[i]; @@ -602,7 +605,7 @@ static INLINE uint8_t MacSzForId(uint8_t id) case ID_HMAC_SHA1: return SHA_DIGEST_SIZE; case ID_HMAC_SHA1_96: - return (96/8); /* 96 bits */ + return SHA1_96_SZ; default: return 0; } @@ -613,9 +616,8 @@ static INLINE uint8_t KeySzForId(uint8_t id) { switch (id) { case ID_HMAC_SHA1: - return SHA_DIGEST_SIZE; case ID_HMAC_SHA1_96: - return (96/8); /* 96 bits */ + return SHA_DIGEST_SIZE; case ID_AES128_CBC: case ID_AES128_CTR: return AES_BLOCK_SIZE; @@ -653,7 +655,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: KEX Algorithms"); listSz = 2; DoNameList(list, &listSz, buf, len, &begin); - algoId = MatchIdLists(cannedKexAlgo, cannedKexAlgoSz, list, listSz); + algoId = MatchIdLists(list, listSz, cannedKexAlgo, cannedKexAlgoSz); if (algoId == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate KEX Algo"); return WS_INVALID_ALGO_ID; @@ -665,7 +667,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: Server Host Key Algorithms"); listSz = 1; DoNameList(list, &listSz, buf, len, &begin); - algoId = MatchIdLists(cannedKeyAlgo, cannedKeyAlgoSz, list, listSz); + algoId = MatchIdLists(list, listSz, cannedKeyAlgo, cannedKeyAlgoSz); if (algoId == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate Server Host Key Algo"); return WS_INVALID_ALGO_ID; @@ -677,7 +679,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Client to Server"); listSz = 3; DoNameList(list, &listSz, buf, len, &begin); - algoId = MatchIdLists(cannedEncAlgo, cannedEncAlgoSz, list, listSz); + algoId = MatchIdLists(list, listSz, cannedEncAlgo, cannedEncAlgoSz); if (algoId == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo C2S"); return WS_INVALID_ALGO_ID; @@ -687,7 +689,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Server to Client"); listSz = 3; DoNameList(list, &listSz, buf, len, &begin); - if (MatchIdLists(&algoId, 1, list, listSz) == ID_UNKNOWN) { + if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo S2C"); return WS_INVALID_ALGO_ID; } @@ -701,7 +703,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: MAC Algorithms - Client to Server"); listSz = 2; DoNameList(list, &listSz, buf, len, &begin); - algoId = MatchIdLists(cannedMacAlgo, cannedMacAlgoSz, list, listSz); + algoId = MatchIdLists(list, listSz, cannedMacAlgo, cannedMacAlgoSz); if (algoId == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo C2S"); return WS_INVALID_ALGO_ID; @@ -711,7 +713,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: MAC Algorithms - Server to Client"); listSz = 2; DoNameList(list, &listSz, buf, len, &begin); - if (MatchIdLists(&algoId, 1, list, listSz) == ID_UNKNOWN) { + if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C"); return WS_INVALID_ALGO_ID; } @@ -727,7 +729,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: Compression Algorithms - Client to Server"); listSz = 1; DoNameList(list, &listSz, buf, len, &begin); - if (MatchIdLists(&algoId, 1, list, listSz) == ID_UNKNOWN) { + if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate Compression Algo C2S"); return WS_INVALID_ALGO_ID; } @@ -736,7 +738,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: Compression Algorithms - Server to Client"); listSz = 1; DoNameList(list, &listSz, buf, len, &begin); - if (MatchIdLists(&algoId, 1, list, listSz) == ID_UNKNOWN) { + if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate Compression Algo S2C"); return WS_INVALID_ALGO_ID; } @@ -759,7 +761,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) *idx = begin; - ssh->clientState = CLIENT_ALGO_DONE; + ssh->clientState = CLIENT_KEXINIT_DONE; return WS_SUCCESS; } @@ -848,7 +850,7 @@ static int DoKexDhInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) ssh->handshake->eSz = eSz; } - ssh->clientState = CLIENT_KEXDHINIT_DONE; + ssh->clientState = CLIENT_KEXDH_INIT_DONE; *idx = begin; return WS_SUCCESS; } @@ -862,6 +864,8 @@ static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) ssh->peerEncryptId = ssh->handshake->encryptId; ssh->peerMacId = ssh->handshake->macId; + ssh->peerBlockSz = ssh->handshake->blockSz; + ssh->peerMacSz = ssh->handshake->macSz; switch (ssh->peerEncryptId) { case ID_NONE: @@ -896,7 +900,7 @@ static int GenerateKey(uint8_t* key, uint32_t keySz, uint8_t keyId, uint8_t kSzFlat[LENGTH_SZ]; if (k[0] & 0x80) kPad = 1; - c32toa(kSz, kSzFlat); + c32toa(kSz + kPad, kSzFlat); blocks = keySz / SHA_DIGEST_SIZE; remainder = keySz % SHA_DIGEST_SIZE; @@ -1196,6 +1200,7 @@ static int DoPacket(WOLFSSH* ssh) default: WLOG(WS_LOG_DEBUG, "Unimplemented message ID (%d)", msg); + DumpOctetString(buf + idx, payloadSz - 1); SendUnimplemented(ssh); break; } @@ -1207,6 +1212,8 @@ static int DoPacket(WOLFSSH* ssh) idx += padSz; ssh->inputBuffer.idx = idx; + ssh->peerSeq++; + return WS_SUCCESS; } @@ -1219,18 +1226,18 @@ static INLINE int Decrypt(WOLFSSH* ssh, uint8_t* plain, const uint8_t* input, if (ssh == NULL || plain == NULL || input == NULL || sz == 0) return WS_BAD_ARGUMENT; + WLOG(WS_LOG_DEBUG, "Decrypt %s", IdToName(ssh->peerEncryptId)); + switch (ssh->peerEncryptId) { case ID_NONE: - WLOG(WS_LOG_DEBUG, "Decrypt none"); break; case ID_AES128_CBC: - WLOG(WS_LOG_DEBUG, "Decrypt aes128-cbc"); if (AesCbcDecrypt(&ssh->decryptCipher.aes, plain, input, sz) < 0) ret = WS_DECRYPT_E; + break; default: - WLOG(WS_LOG_DEBUG, "Decrypt invalid algo ID"); ret = WS_INVALID_ALGO_ID; } @@ -1238,11 +1245,42 @@ static INLINE int Decrypt(WOLFSSH* ssh, uint8_t* plain, const uint8_t* input, } -static INLINE int VerifyMac(WOLFSSH* ssh) +static INLINE int VerifyMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, + const uint8_t* mac) { - (void)ssh; - /* Verify the buffer is big enough for the data plus the mac. */ - return WS_SUCCESS; + int ret = WS_SUCCESS; + uint8_t flatSeq[LENGTH_SZ]; + uint8_t checkMac[SHA_DIGEST_SIZE]; + Hmac hmac; + + c32toa(ssh->peerSeq, flatSeq); + + WLOG(WS_LOG_DEBUG, "VerifyMac %s", IdToName(ssh->peerMacId)); + WLOG(WS_LOG_DEBUG, "VM: inSz = %u", inSz); + WLOG(WS_LOG_DEBUG, "VM: seq = %u", ssh->peerSeq); + WLOG(WS_LOG_DEBUG, "VM: keyLen = %u", ssh->macKeyClientSz); + + switch (ssh->peerMacId) { + case ID_NONE: + break; + + case ID_HMAC_SHA1: + case ID_HMAC_SHA1_96: + HmacSetKey(&hmac, SHA, ssh->macKeyClient, ssh->macKeyClientSz); + HmacUpdate(&hmac, flatSeq, sizeof(flatSeq)); + HmacUpdate(&hmac, in, inSz); + HmacFinal(&hmac, checkMac); + DumpOctetString(mac, ssh->peerMacSz); + DumpOctetString(checkMac, ssh->peerMacSz); + if (WMEMCMP(checkMac, mac, ssh->peerMacSz) != 0) + ret = WS_MAC_E; + break; + + default: + ret = WS_INVALID_ALGO_ID; + } + + return ret; } @@ -1250,17 +1288,19 @@ int ProcessReply(WOLFSSH* ssh) { int ret = WS_FATAL_ERROR; uint32_t readSz; + uint8_t peerBlockSz = ssh->peerBlockSz; + uint8_t peerMacSz = ssh->peerMacSz; for (;;) { switch (ssh->processReplyState) { case PROCESS_INIT: - readSz = ssh->blockSz; - WLOG(WS_LOG_DEBUG, "PR1: size = %d", readSz); + readSz = peerBlockSz; + WLOG(WS_LOG_DEBUG, "PR1: size = %u", readSz); if ((ret = GetInputData(ssh, readSz)) < 0) { return ret; } ssh->processReplyState = PROCESS_PACKET_LENGTH; - WLOG(WS_LOG_DEBUG, "idx = %u, length = %u", ssh->inputBuffer.idx, ssh->inputBuffer.length); + WLOG(WS_LOG_DEBUG, "idx = %u, length = %u", ssh->inputBuffer.idx, ssh->inputBuffer.length); /* Decrypt first block if encrypted */ ret = Decrypt(ssh, @@ -1274,29 +1314,40 @@ int ProcessReply(WOLFSSH* ssh) ssh->processReplyState = PROCESS_PACKET_FINISH; case PROCESS_PACKET_FINISH: - readSz = ssh->curSz + LENGTH_SZ + ssh->macSz; - WLOG(WS_LOG_DEBUG, "PR2: size = %d", readSz); + readSz = ssh->curSz + LENGTH_SZ + peerMacSz; + WLOG(WS_LOG_DEBUG, "PR2: size = %u", readSz); if (readSz > 0) { if ((ret = GetInputData(ssh, readSz)) < 0) { return ret; } ret = Decrypt(ssh, - ssh->inputBuffer.buffer + ssh->inputBuffer.idx + ssh->blockSz - LENGTH_SZ, - ssh->inputBuffer.buffer + ssh->inputBuffer.idx + ssh->blockSz - LENGTH_SZ, - ssh->curSz - ssh->blockSz); + ssh->inputBuffer.buffer + ssh->inputBuffer.idx + peerBlockSz, + ssh->inputBuffer.buffer + ssh->inputBuffer.idx + peerBlockSz, + ssh->curSz + LENGTH_SZ - peerBlockSz); + if (ret != WS_SUCCESS) { + WLOG(WS_LOG_DEBUG, "PR: Decrypt fail"); + return ret; + } - - ret = VerifyMac(ssh); + /* Verify the buffer is big enough for the data plus the mac. */ + ret = VerifyMac(ssh, + ssh->inputBuffer.buffer + ssh->inputBuffer.idx, + ssh->curSz + LENGTH_SZ, + ssh->inputBuffer.buffer + ssh->inputBuffer.idx + LENGTH_SZ + ssh->curSz); + if (ret != WS_SUCCESS) { + WLOG(WS_LOG_DEBUG, "PR: VerifyMac fail"); + return ret; + } } - ssh->processReplyState = PROCESS_PACKET; case PROCESS_PACKET: if ( (ret = DoPacket(ssh)) < 0) { return ret; } - ssh->inputBuffer.idx += ssh->macSz; + WLOG(WS_LOG_DEBUG, "PR3: peerMacSz = %u", peerMacSz); + ssh->inputBuffer.idx += peerMacSz; break; default: @@ -1769,7 +1820,9 @@ int SendNewKeys(WOLFSSH* ssh) BundlePacket(ssh); SendBuffered(ssh); + ssh->blockSz = ssh->handshake->blockSz; ssh->encryptId = ssh->handshake->encryptId; + ssh->macSz = ssh->handshake->macSz; ssh->macId = ssh->handshake->macId; switch (ssh->encryptId) { diff --git a/src/ssh.c b/src/ssh.c index fb4bd5c..b1b96ff 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -143,13 +143,17 @@ static WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx) WMEMSET(handshake, 0, sizeof(HandshakeInfo)); ssh->ctx = ctx; + ssh->error = WS_SUCCESS; ssh->rfd = -1; /* set to invalid */ ssh->wfd = -1; /* set to invalid */ ssh->ioReadCtx = &ssh->rfd; /* prevent invalid access if not correctly */ ssh->ioWriteCtx = &ssh->wfd; /* set */ - ssh->blockSz = 8; + ssh->acceptState = ACCEPT_BEGIN; + ssh->clientState = CLIENT_BEGIN; + ssh->blockSz = MIN_BLOCK_SZ; ssh->encryptId = ID_NONE; ssh->macId = ID_NONE; + ssh->peerBlockSz = MIN_BLOCK_SZ; ssh->rng = rng; ssh->kSz = sizeof(ssh->k); ssh->handshake = handshake; @@ -157,6 +161,7 @@ static WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx) handshake->pubKeyId = ID_NONE; handshake->encryptId = ID_NONE; handshake->macId = ID_NONE; + handshake->blockSz = MIN_BLOCK_SZ; if (BufferInit(&ssh->inputBuffer, 0, ctx->heap) != WS_SUCCESS || BufferInit(&ssh->outputBuffer, 0, ctx->heap) != WS_SUCCESS || @@ -286,42 +291,53 @@ int wolfSSH_accept(WOLFSSH* ssh) } } ssh->acceptState = ACCEPT_CLIENT_VERSION_DONE; - WLOG(WS_LOG_DEBUG, "accept state ACCEPT_CLIENT_VERSION_DONE"); + WLOG(WS_LOG_DEBUG, "accept state CLIENT_VERSION_DONE"); case ACCEPT_CLIENT_VERSION_DONE: SendServerVersion(ssh); - ssh->acceptState = SERVER_VERSION_SENT; + ssh->acceptState = ACCEPT_SERVER_VERSION_SENT; WLOG(WS_LOG_DEBUG, "accept state SERVER_VERSION_SENT"); - case SERVER_VERSION_SENT: - while (ssh->clientState < CLIENT_ALGO_DONE) { + case ACCEPT_SERVER_VERSION_SENT: + while (ssh->clientState < CLIENT_KEXINIT_DONE) { if ( (ssh->error = ProcessReply(ssh)) < 0) { WLOG(WS_LOG_DEBUG, "accept reply error 2: %d", ssh->error); return WS_FATAL_ERROR; } } SendKexInit(ssh); - ssh->acceptState = SERVER_ALGO_SENT; + ssh->acceptState = ACCEPT_SERVER_KEXINIT_SENT; + WLOG(WS_LOG_DEBUG, "accept state SERVER_KEXINIT_SENT"); - case SERVER_ALGO_SENT: - while (ssh->clientState < CLIENT_KEXDHINIT_DONE) { + case ACCEPT_SERVER_KEXINIT_SENT: + while (ssh->clientState < CLIENT_KEXDH_INIT_DONE) { if ( (ssh->error = ProcessReply(ssh)) < 0) { WLOG(WS_LOG_DEBUG, "accept reply error 3: %d", ssh->error); return WS_FATAL_ERROR; } } SendKexDhReply(ssh); - ssh->acceptState = SERVER_KEXDH_REPLY_SENT; + SendNewKeys(ssh); + ssh->acceptState = ACCEPT_SERVER_KEXDH_REPLY_SENT; + WLOG(WS_LOG_DEBUG, "accept state SERVER_KEXDH_REPLY_SENT"); - case SERVER_KEXDH_REPLY_SENT: + case ACCEPT_SERVER_KEXDH_REPLY_SENT: while (ssh->clientState < CLIENT_USING_KEYS) { if ( (ssh->error = ProcessReply(ssh)) < 0) { WLOG(WS_LOG_DEBUG, "accept reply error 4: %d", ssh->error); return WS_FATAL_ERROR; } } - SendNewKeys(ssh); - ssh->acceptState = SERVER_USING_KEYS; + ssh->acceptState = ACCEPT_USING_KEYS; + WLOG(WS_LOG_DEBUG, "accept state ACCEPT_USING_KEYS"); + + case ACCEPT_USING_KEYS: + while (ssh->clientState < ACCEPT_CLIENT_USERAUTH_DONE) { + if ( (ssh->error = ProcessReply(ssh)) < 0) { + WLOG(WS_LOG_DEBUG, "accept reply error 5: %d", ssh->error); + return WS_FATAL_ERROR; + } + } } return WS_FATAL_ERROR; diff --git a/wolfssh/error.h b/wolfssh/error.h index 70fa204..a7ac5f5 100644 --- a/wolfssh/error.h +++ b/wolfssh/error.h @@ -60,7 +60,8 @@ enum WS_ErrorCodes { WS_RSA_E = -18, WS_BAD_FILE_E = -19, WS_INVALID_ALGO_ID = -20, - WS_DECRYPT_E = -21 + WS_DECRYPT_E = -21, + WS_MAC_E = -22 }; diff --git a/wolfssh/internal.h b/wolfssh/internal.h index 676fca1..699e7bc 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -86,12 +86,13 @@ enum { #define MAX_INTEGRITY 2 #define MAX_KEY_EXCHANGE 2 #define MAX_PUBLIC_KEY 1 +#define MIN_BLOCK_SZ 8 #define COOKIE_SZ 16 #define LENGTH_SZ 4 #define PAD_LENGTH_SZ 1 #define BOOLEAN_SZ 1 #define MSG_ID_SZ 1 -#define SHA1_96_SZ (96/8) +#define SHA1_96_SZ 12 #define UINT32_SZ 4 @@ -170,8 +171,6 @@ struct WOLFSSH { uint32_t curSz; uint32_t seq; uint32_t peerSeq; - uint8_t blockSz; - uint8_t macSz; uint8_t paddingSz; uint8_t acceptState; uint8_t clientState; @@ -180,10 +179,14 @@ struct WOLFSSH { uint8_t connReset; uint8_t isClosed; + uint8_t blockSz; uint8_t encryptId; uint8_t macId; + uint8_t macSz; + uint8_t peerBlockSz; uint8_t peerEncryptId; uint8_t peerMacId; + uint8_t peerMacSz; Ciphers encryptCipher; Ciphers decryptCipher; @@ -199,17 +202,17 @@ struct WOLFSSH { uint8_t sessionId[SHA_DIGEST_SIZE]; uint32_t sessionIdSz; - uint8_t ivClient[16]; + uint8_t ivClient[AES_BLOCK_SIZE]; uint8_t ivClientSz; - uint8_t ivServer[16]; + uint8_t ivServer[AES_BLOCK_SIZE]; uint8_t ivServerSz; - uint8_t encKeyClient[16]; + uint8_t encKeyClient[AES_BLOCK_SIZE]; uint8_t encKeyClientSz; - uint8_t encKeyServer[16]; + uint8_t encKeyServer[AES_BLOCK_SIZE]; uint8_t encKeyServerSz; - uint8_t macKeyClient[20]; + uint8_t macKeyClient[SHA_DIGEST_SIZE]; uint8_t macKeyClientSz; - uint8_t macKeyServer[20]; + uint8_t macKeyServer[SHA_DIGEST_SIZE]; uint8_t macKeyServerSz; HandshakeInfo* handshake; @@ -240,21 +243,21 @@ WOLFSSH_LOCAL int SendDebug(WOLFSSH*, byte, const char*); enum AcceptStates { ACCEPT_BEGIN = 0, ACCEPT_CLIENT_VERSION_DONE, - SERVER_VERSION_SENT, - ACCEPT_CLIENT_ALGO_DONE, - SERVER_ALGO_SENT, + ACCEPT_SERVER_VERSION_SENT, + ACCEPT_CLIENT_KEXINIT_DONE, + ACCEPT_SERVER_KEXINIT_SENT, ACCEPT_CLIENT_KEXDH_INIT_DONE, - SERVER_KEXDH_REPLY_SENT, - SERVER_KEXDH_ACCEPT_SENT, - SERVER_USING_KEYS + ACCEPT_SERVER_KEXDH_REPLY_SENT, + ACCEPT_USING_KEYS, + ACCEPT_CLIENT_USERAUTH_DONE }; enum ClientStates { CLIENT_BEGIN = 0, CLIENT_VERSION_DONE, - CLIENT_ALGO_DONE, - CLIENT_KEXDHINIT_DONE, + CLIENT_KEXINIT_DONE, + CLIENT_KEXDH_INIT_DONE, CLIENT_USING_KEYS };