Merge pull request #34 from ejohnstown/aes-gcm

Add AES-GCM
pull/36/merge
dgarske 2017-07-11 11:13:56 -07:00 committed by GitHub
commit 4106ce3186
6 changed files with 366 additions and 106 deletions

View File

@ -2,7 +2,7 @@
# Copyright (C) 2014-2017 wolfSSL Inc.
# All right reserved.
AC_INIT([wolfssh], [1.1.0], [http://wolfssl.com], [wolfssh])
AC_INIT([wolfssh], [1.2.0], [http://wolfssl.com], [wolfssh])
AC_PREREQ([2.63])
AC_CONFIG_AUX_DIR([build-aux])
@ -17,7 +17,7 @@ AC_ARG_PROGRAM
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([src/config.h])
WOLFSSH_LIBRARY_VERSION=3:0:2
WOLFSSH_LIBRARY_VERSION=3:1:2
# | | |
# +------+ | +---+
# | | |

View File

@ -111,6 +111,75 @@ typedef struct {
#endif
#define MY_EX_USAGE 2
extern int myoptind;
extern char* myoptarg;
static INLINE int mygetopt(int argc, char** argv, const char* optstring)
{
static char* next = NULL;
char c;
char* cp;
if (myoptind == 0)
next = NULL; /* we're starting new/over */
if (next == NULL || *next == '\0') {
if (myoptind == 0)
myoptind++;
if (myoptind >= argc || argv[myoptind][0] != '-' ||
argv[myoptind][1] == '\0') {
myoptarg = NULL;
if (myoptind < argc)
myoptarg = argv[myoptind];
return -1;
}
if (strcmp(argv[myoptind], "--") == 0) {
myoptind++;
myoptarg = NULL;
if (myoptind < argc)
myoptarg = argv[myoptind];
return -1;
}
next = argv[myoptind];
next++; /* skip - */
myoptind++;
}
c = *next++;
/* The C++ strchr can return a different value */
cp = (char*)strchr(optstring, c);
if (cp == NULL || c == ':')
return '?';
cp++;
if (*cp == ':') {
if (*next != '\0') {
myoptarg = next;
next = NULL;
}
else if (myoptind < argc) {
myoptarg = argv[myoptind];
myoptind++;
}
else
return '?';
}
return c;
}
static INLINE WS_NORETURN void err_sys(const char* msg)
{
printf("server error: %s\n", msg);
@ -663,18 +732,45 @@ static int wsUserAuth(uint8_t authType,
}
int main(void)
static void ShowUsage(void)
{
printf("echoserver %s\n", LIBWOLFSSH_VERSION_STRING);
printf("-h Help, print this usage\n");
printf("-m Allow multiple connections\n");
}
int main(int argc, char** argv)
{
WOLFSSH_CTX* ctx = NULL;
PwMapList pwMapList;
SOCKET_T listenFd = 0;
uint32_t defaultHighwater = EXAMPLE_HIGHWATER_MARK;
uint32_t threadCount = 0;
int multipleConnections = 0;
char ch;
#ifdef DEBUG_WOLFSSH
wolfSSH_Debugging_ON();
#endif
while ((ch = mygetopt(argc, argv, "hm")) != -1) {
switch (ch) {
case 'h' :
ShowUsage();
exit(EXIT_SUCCESS);
case 'm' :
multipleConnections = 1;
break;
default:
ShowUsage();
exit(MY_EX_USAGE);
}
}
myoptind = 0; /* reset for test cases */
if (wolfSSH_Init() != WS_SUCCESS) {
fprintf(stderr, "Couldn't initialize wolfSSH.\n");
exit(EXIT_FAILURE);
@ -721,7 +817,7 @@ int main(void)
if (listen(listenFd, 5) != 0)
err_sys("tcp listen failed");
for (;;) {
do {
SOCKET_T clientFd = 0;
SOCKADDR_IN_T clientAddr;
SOCKLEN_T clientAddrSz = sizeof(clientAddr);
@ -759,8 +855,13 @@ int main(void)
threadCtx->id = threadCount++;
pthread_create(&thread, 0, server_worker, threadCtx);
pthread_detach(thread);
}
if (multipleConnections)
pthread_detach(thread);
else
pthread_join(thread, NULL);
} while (multipleConnections);
PwMapListDelete(&pwMapList);
wolfSSH_CTX_free(ctx);
@ -771,3 +872,6 @@ int main(void)
return 0;
}
int myoptind = 0;
char* myoptarg = NULL;

View File

@ -382,8 +382,7 @@ static const NameIdPair NameIdMap[] = {
/* Encryption IDs */
{ ID_AES128_CBC, "aes128-cbc" },
{ ID_AES128_CTR, "aes128-ctr" },
{ ID_AES128_GCM_WOLF, "aes128-gcm@wolfssl.com" },
{ ID_AES128_GCM, "aes128-gcm@openssh.com" },
/* Integrity IDs */
{ ID_HMAC_SHA1, "hmac-sha1" },
@ -1070,7 +1069,7 @@ static int DoNameList(uint8_t* idList, uint32_t* idListSz,
}
static const uint8_t cannedEncAlgo[] = {ID_AES128_CBC};
static const uint8_t cannedEncAlgo[] = {ID_AES128_GCM, ID_AES128_CBC};
static const uint8_t cannedMacAlgo[] = {ID_HMAC_SHA2_256, ID_HMAC_SHA1_96,
ID_HMAC_SHA1};
static const uint8_t cannedKeyAlgo[] = {ID_SSH_RSA};
@ -1109,7 +1108,7 @@ static INLINE uint8_t BlockSzForId(uint8_t id)
{
switch (id) {
case ID_AES128_CBC:
case ID_AES128_CTR:
case ID_AES128_GCM:
return AES_BLOCK_SIZE;
default:
return 0;
@ -1141,7 +1140,7 @@ static INLINE uint8_t KeySzForId(uint8_t id)
case ID_HMAC_SHA2_256:
return SHA256_DIGEST_SIZE;
case ID_AES128_CBC:
case ID_AES128_CTR:
case ID_AES128_GCM:
return AES_BLOCK_SIZE;
default:
return 0;
@ -1163,6 +1162,12 @@ static INLINE uint8_t HashForId(uint8_t id)
}
static INLINE uint8_t AeadModeForId(uint8_t id)
{
return (id == ID_AES128_GCM);
}
static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
{
int ret = WS_SUCCESS;
@ -1266,13 +1271,22 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
}
else {
ssh->handshake->encryptId = algoId;
ssh->handshake->blockSz =
ssh->handshake->clientKeys.ivSz =
ssh->handshake->serverKeys.ivSz =
BlockSzForId(algoId);
ssh->handshake->aeadMode = AeadModeForId(algoId);
ssh->handshake->blockSz = BlockSzForId(algoId);
ssh->handshake->clientKeys.encKeySz =
ssh->handshake->serverKeys.encKeySz =
KeySzForId(algoId);
if (!ssh->handshake->aeadMode) {
ssh->handshake->clientKeys.ivSz =
ssh->handshake->serverKeys.ivSz =
ssh->handshake->blockSz;
}
else {
ssh->handshake->clientKeys.ivSz =
ssh->handshake->serverKeys.ivSz =
AEAD_NONCE_SZ;
ssh->handshake->macSz = ssh->handshake->blockSz;
}
}
}
@ -1281,7 +1295,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;
ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
if (ret == WS_SUCCESS && !ssh->aeadMode) {
algoId = MatchIdLists(list, listSz, cannedMacAlgo, cannedMacAlgoSz);
if (algoId == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo C2S");
@ -1295,7 +1309,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;
ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
if (ret == WS_SUCCESS && !ssh->handshake->aeadMode) {
if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C");
ret = WS_INVALID_ALGO_ID;
@ -1553,6 +1567,7 @@ static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
ssh->peerMacId = ssh->handshake->macId;
ssh->peerBlockSz = ssh->handshake->blockSz;
ssh->peerMacSz = ssh->handshake->macSz;
ssh->peerAeadMode = ssh->handshake->aeadMode;
WMEMCPY(&ssh->clientKeys, &ssh->handshake->clientKeys, sizeof(Keys));
switch (ssh->peerEncryptId) {
@ -1568,6 +1583,13 @@ static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
ssh->clientKeys.iv, AES_DECRYPTION);
break;
case ID_AES128_GCM:
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-gcm");
ret = wc_AesGcmSetKey(&ssh->decryptCipher.aes,
ssh->clientKeys.encKey,
ssh->clientKeys.encKeySz);
break;
default:
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher invalid");
break;
@ -1783,37 +1805,40 @@ static int GenerateKeys(WOLFSSH* ssh)
sK->encKey, sK->encKeySz,
ssh->k, ssh->kSz, ssh->h, ssh->hSz,
ssh->sessionId, ssh->sessionIdSz);
if (ret == WS_SUCCESS)
ret = GenerateKey(hashId, 'E',
cK->macKey, cK->macKeySz,
ssh->k, ssh->kSz, ssh->h, ssh->hSz,
ssh->sessionId, ssh->sessionIdSz);
if (ret == WS_SUCCESS)
ret = GenerateKey(hashId, 'F',
sK->macKey, sK->macKeySz,
ssh->k, ssh->kSz, ssh->h, ssh->hSz,
ssh->sessionId, ssh->sessionIdSz);
if (!ssh->handshake->aeadMode) {
if (ret == WS_SUCCESS)
ret = GenerateKey(hashId, 'E',
cK->macKey, cK->macKeySz,
ssh->k, ssh->kSz, ssh->h, ssh->hSz,
ssh->sessionId, ssh->sessionIdSz);
if (ret == WS_SUCCESS)
ret = GenerateKey(hashId, 'F',
sK->macKey, sK->macKeySz,
ssh->k, ssh->kSz, ssh->h, ssh->hSz,
ssh->sessionId, ssh->sessionIdSz);
}
#ifdef SHOW_SECRETS
printf("\n** Showing Secrets **\nK:\n");
DumpOctetString(ssh->k, ssh->kSz);
printf("H:\n");
DumpOctetString(ssh->h, ssh->hSz);
printf("Session ID:\n");
DumpOctetString(ssh->sessionId, ssh->sessionIdSz);
printf("A:\n");
DumpOctetString(cK->iv, cK->ivSz);
printf("B:\n");
DumpOctetString(sK->iv, sK->ivSz);
printf("C:\n");
DumpOctetString(cK->encKey, cK->encKeySz);
printf("D:\n");
DumpOctetString(sK->encKey, sK->encKeySz);
printf("E:\n");
DumpOctetString(cK->macKey, cK->macKeySz);
printf("F:\n");
DumpOctetString(sK->macKey, sK->macKeySz);
printf("\n");
if (ret == WS_SUCCESS) {
printf("\n** Showing Secrets **\nK:\n");
DumpOctetString(ssh->k, ssh->kSz);
printf("H:\n");
DumpOctetString(ssh->h, ssh->hSz);
printf("Session ID:\n");
DumpOctetString(ssh->sessionId, ssh->sessionIdSz);
printf("A:\n");
DumpOctetString(cK->iv, cK->ivSz);
printf("B:\n");
DumpOctetString(sK->iv, sK->ivSz);
printf("C:\n");
DumpOctetString(cK->encKey, cK->encKeySz);
printf("D:\n");
DumpOctetString(sK->encKey, sK->encKeySz);
printf("E:\n");
DumpOctetString(cK->macKey, cK->macKeySz);
printf("F:\n");
DumpOctetString(sK->macKey, sK->macKeySz);
printf("\n");
}
#endif /* SHOW_SECRETS */
return ret;
@ -3026,6 +3051,75 @@ static INLINE int VerifyMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz,
}
static INLINE void AeadIncrementExpIv(uint8_t* iv)
{
int i;
iv += AEAD_IMP_IV_SZ;
for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) {
if (++iv[i]) return;
}
}
static INLINE int EncryptAead(WOLFSSH* ssh, uint8_t* cipher,
const uint8_t* input, uint16_t sz,
uint8_t* authTag, const uint8_t* auth,
uint16_t authSz)
{
int ret = WS_SUCCESS;
if (ssh == NULL || cipher == NULL || input == NULL || sz == 0 ||
authTag == NULL || auth == NULL || authSz == 0)
return WS_BAD_ARGUMENT;
WLOG(WS_LOG_DEBUG, "EncryptAead %s", IdToName(ssh->encryptId));
if (ssh->encryptId == ID_AES128_GCM) {
ret = wc_AesGcmEncrypt(&ssh->encryptCipher.aes, cipher, input, sz,
ssh->serverKeys.iv, ssh->serverKeys.ivSz,
authTag, ssh->macSz, auth, authSz);
}
else
ret = WS_INVALID_ALGO_ID;
AeadIncrementExpIv(ssh->serverKeys.iv);
ssh->txCount += sz;
return ret;
}
static INLINE int DecryptAead(WOLFSSH* ssh, uint8_t* plain,
const uint8_t* input, uint16_t sz,
const uint8_t* authTag, const uint8_t* auth,
uint16_t authSz)
{
int ret = WS_SUCCESS;
if (ssh == NULL || plain == NULL || input == NULL || sz == 0 ||
authTag == NULL || auth == NULL || authSz == 0)
return WS_BAD_ARGUMENT;
WLOG(WS_LOG_DEBUG, "DecryptAead %s", IdToName(ssh->peerEncryptId));
if (ssh->peerEncryptId == ID_AES128_GCM) {
ret = wc_AesGcmDecrypt(&ssh->decryptCipher.aes, plain, input, sz,
ssh->clientKeys.iv, ssh->clientKeys.ivSz,
authTag, ssh->peerMacSz, auth, authSz);
}
else
ret = WS_INVALID_ALGO_ID;
AeadIncrementExpIv(ssh->clientKeys.iv);
ssh->rxCount += sz;
HighwaterCheck(ssh, WOLFSSH_HWSIDE_RECEIVE);
return ret;
}
int DoReceive(WOLFSSH* ssh)
{
int ret = WS_FATAL_ERROR;
@ -3033,6 +3127,7 @@ int DoReceive(WOLFSSH* ssh)
uint32_t readSz;
uint8_t peerBlockSz = ssh->peerBlockSz;
uint8_t peerMacSz = ssh->peerMacSz;
uint8_t aeadMode = ssh->peerAeadMode;
for (;;) {
switch (ssh->processReplyState) {
@ -3044,14 +3139,18 @@ int DoReceive(WOLFSSH* ssh)
}
ssh->processReplyState = PROCESS_PACKET_LENGTH;
/* Decrypt first block if encrypted */
ret = Decrypt(ssh,
ssh->inputBuffer.buffer + ssh->inputBuffer.idx,
ssh->inputBuffer.buffer + ssh->inputBuffer.idx,
readSz);
if (ret != WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "PR: First decrypt fail");
return ret;
if (!aeadMode) {
/* Decrypt first block if encrypted */
ret = Decrypt(ssh,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx,
readSz);
if (ret != WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "PR: First decrypt fail");
return ret;
}
}
case PROCESS_PACKET_LENGTH:
@ -3068,35 +3167,59 @@ int DoReceive(WOLFSSH* ssh)
return ret;
}
if (ssh->curSz + LENGTH_SZ - peerBlockSz > 0) {
ret = Decrypt(ssh,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx + peerBlockSz,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx + peerBlockSz,
ssh->curSz + LENGTH_SZ - peerBlockSz);
if (!aeadMode) {
if (ssh->curSz + LENGTH_SZ - peerBlockSz > 0) {
ret = Decrypt(ssh,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx + peerBlockSz,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx + peerBlockSz,
ssh->curSz + LENGTH_SZ - peerBlockSz);
}
else {
WLOG(WS_LOG_INFO,
"Not trying to decrypt short message.");
}
/* Verify the buffer is big enough for the data and mac.
* Even if the decrypt step fails, verify the MAC anyway.
* This keeps consistent timing. */
verifyResult = 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: Decrypt fail");
return ret;
}
if (verifyResult != WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "PR: VerifyMac fail");
return ret;
}
}
else {
WLOG(WS_LOG_INFO, "Not trying to decrypt short message.");
}
ret = DecryptAead(ssh,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx +
LENGTH_SZ,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx +
LENGTH_SZ,
ssh->curSz,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx +
ssh->curSz + LENGTH_SZ,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx,
LENGTH_SZ);
/* Verify the buffer is big enough for the data and mac.
* Even if the decrypt step fails, verify the MAC anyway.
* This keeps consistent timing. */
verifyResult = 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: Decrypt fail");
return ret;
}
if (verifyResult != WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "PR: VerifyMac fail");
return ret;
if (ret != WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "PR: DecryptAead fail");
return ret;
}
}
}
ssh->processReplyState = PROCESS_PACKET;
@ -3206,7 +3329,8 @@ static int PreparePacket(WOLFSSH* ssh, uint32_t payloadSz)
if (ret == WS_SUCCESS) {
/* Minimum value for paddingSz is 4. */
paddingSz = ssh->blockSz -
(LENGTH_SZ + PAD_LENGTH_SZ + payloadSz) % ssh->blockSz;
((ssh->aeadMode ? 0 : LENGTH_SZ) +
PAD_LENGTH_SZ + payloadSz) % ssh->blockSz;
if (paddingSz < MIN_PAD_LENGTH)
paddingSz += ssh->blockSz;
ssh->paddingSz = paddingSz;
@ -3255,27 +3379,47 @@ static int BundlePacket(WOLFSSH* ssh)
ret = WS_CRYPTO_FAILED;
}
if (ret == WS_SUCCESS) {
idx += paddingSz;
ret = CreateMac(ssh, ssh->outputBuffer.buffer + ssh->packetStartIdx,
ssh->outputBuffer.length -
ssh->packetStartIdx + paddingSz,
output + idx);
}
else {
WLOG(WS_LOG_DEBUG, "BP: failed to add padding");
}
if (!ssh->aeadMode) {
if (ret == WS_SUCCESS) {
idx += paddingSz;
ret = CreateMac(ssh, ssh->outputBuffer.buffer + ssh->packetStartIdx,
ssh->outputBuffer.length -
ssh->packetStartIdx + paddingSz,
output + idx);
}
else {
WLOG(WS_LOG_DEBUG, "BP: failed to add padding");
}
if (ret == WS_SUCCESS) {
idx += ssh->macSz;
ret = Encrypt(ssh,
ssh->outputBuffer.buffer + ssh->packetStartIdx,
ssh->outputBuffer.buffer + ssh->packetStartIdx,
ssh->outputBuffer.length -
ssh->packetStartIdx + paddingSz);
if (ret == WS_SUCCESS) {
idx += ssh->macSz;
ret = Encrypt(ssh,
ssh->outputBuffer.buffer + ssh->packetStartIdx,
ssh->outputBuffer.buffer + ssh->packetStartIdx,
ssh->outputBuffer.length -
ssh->packetStartIdx + paddingSz);
}
else {
WLOG(WS_LOG_DEBUG, "BP: failed to generate mac");
}
}
else {
WLOG(WS_LOG_DEBUG, "BP: failed to generate mac");
if (ret == WS_SUCCESS) {
idx += paddingSz;
ret = EncryptAead(ssh,
ssh->outputBuffer.buffer +
ssh->packetStartIdx + LENGTH_SZ,
ssh->outputBuffer.buffer +
ssh->packetStartIdx + LENGTH_SZ,
ssh->outputBuffer.length -
ssh->packetStartIdx + paddingSz -
LENGTH_SZ,
output + idx,
ssh->outputBuffer.buffer +
ssh->packetStartIdx,
LENGTH_SZ);
idx += ssh->macSz;
}
}
if (ret == WS_SUCCESS)
@ -3302,7 +3446,7 @@ static INLINE void CopyNameList(uint8_t* buf, uint32_t* idx,
}
static const char cannedEncAlgoNames[] = "aes128-cbc";
static const char cannedEncAlgoNames[] = "aes128-gcm@openssh.com,aes128-cbc";
static const char cannedMacAlgoNames[] = "hmac-sha2-256,hmac-sha1-96,"
"hmac-sha1";
static const char cannedKeyAlgoNames[] = "ssh-rsa";
@ -3833,6 +3977,7 @@ int SendNewKeys(WOLFSSH* ssh)
ssh->encryptId = ssh->handshake->encryptId;
ssh->macSz = ssh->handshake->macSz;
ssh->macId = ssh->handshake->macId;
ssh->aeadMode = ssh->handshake->aeadMode;
WMEMCPY(&ssh->serverKeys, &ssh->handshake->serverKeys, sizeof(Keys));
switch (ssh->encryptId) {
@ -3848,6 +3993,13 @@ int SendNewKeys(WOLFSSH* ssh)
ssh->serverKeys.iv, AES_ENCRYPTION);
break;
case ID_AES128_GCM:
WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-gcm");
ret = wc_AesGcmSetKey(&ssh->encryptCipher.aes,
ssh->serverKeys.encKey,
ssh->serverKeys.encKeySz);
break;
default:
WLOG(WS_LOG_DEBUG, "SNK: using cipher invalid");
ret = WS_INVALID_ALGO_ID;

View File

@ -62,8 +62,7 @@ enum {
/* Encryption IDs */
ID_AES128_CBC,
ID_AES128_CTR,
ID_AES128_GCM_WOLF,
ID_AES128_GCM,
/* Integrity IDs */
ID_HMAC_SHA1,
@ -105,6 +104,9 @@ enum {
#define UINT32_SZ 4
#define SSH_PROTO_SZ 7 /* "SSH-2.0" */
#define SSH_PROTO_EOL_SZ 2 /* Just the CRLF */
#define AEAD_IMP_IV_SZ 4
#define AEAD_EXP_IV_SZ 8
#define AEAD_NONCE_SZ (AEAD_IMP_IV_SZ+AEAD_EXP_IV_SZ)
#ifndef DEFAULT_HIGHWATER_MARK
#define DEFAULT_HIGHWATER_MARK ((1024 * 1024 * 1024) - (32 * 1024))
#endif
@ -181,6 +183,7 @@ typedef struct HandshakeInfo {
uint8_t macId;
uint8_t hashId;
uint8_t kexPacketFollows;
uint8_t aeadMode;
uint8_t blockSz;
uint8_t macSz;
@ -231,10 +234,12 @@ struct WOLFSSH {
uint8_t encryptId;
uint8_t macId;
uint8_t macSz;
uint8_t aeadMode;
uint8_t peerBlockSz;
uint8_t peerEncryptId;
uint8_t peerMacId;
uint8_t peerMacSz;
uint8_t peerAeadMode;
Ciphers encryptCipher;
Ciphers decryptCipher;

View File

@ -133,7 +133,6 @@ WOLFSSH_API int wolfSSH_stream_read(WOLFSSH*, uint8_t*, uint32_t);
WOLFSSH_API int wolfSSH_stream_send(WOLFSSH*, uint8_t*, uint32_t);
WOLFSSH_API int wolfSSH_channel_read(WOLFSSH_CHANNEL*, uint8_t*, uint32_t);
WOLFSSH_API int wolfSSH_channel_send(WOLFSSH_CHANNEL*, uint8_t*, uint32_t);
WOLFSSH_API int wolfSSH_worker(WOLFSSH*);
WOLFSSH_API int wolfSSH_TriggerKeyExchange(WOLFSSH*);
WOLFSSH_API void wolfSSH_GetStats(WOLFSSH*,

View File

@ -33,8 +33,8 @@
extern "C" {
#endif
#define LIBWOLFSSH_VERSION_STRING "1.1.0"
#define LIBWOLFSSH_VERSION_HEX 0x01001000
#define LIBWOLFSSH_VERSION_STRING "1.2.0"
#define LIBWOLFSSH_VERSION_HEX 0x01002000
#ifdef __cplusplus
}