@@ -570,13 +570,11 @@ static HandshakeInfo* HandshakeInfoNew(void* heap)
570570 heap, DYNTYPE_HS);
571571 if (newHs != NULL) {
572572 WMEMSET(newHs, 0, sizeof(HandshakeInfo));
573- newHs->expectMsgId = MSGID_NONE;
574- newHs->kexId = ID_NONE;
575573 newHs->kexHashId = WC_HASH_TYPE_NONE;
576- newHs->pubKeyId = ID_NONE;
577- newHs->encryptId = ID_NONE;
578- newHs->macId = ID_NONE;
579574 newHs->blockSz = MIN_BLOCK_SZ;
575+ newHs->peerBlockSz = MIN_BLOCK_SZ;
576+ /* peerEncryptId, peerMacId, peerAeadMode, peerMacSz: left at 0
577+ * (== ID_NONE / no-MAC) by the WMEMSET above. */
580578 newHs->eSz = (word32)sizeof(newHs->e);
581579 newHs->xSz = (word32)sizeof(newHs->x);
582580#ifndef WOLFSSH_NO_DH_GEX_SHA256
@@ -2625,7 +2623,7 @@ static int GenerateKeys(WOLFSSH* ssh, byte hashId, byte doKeyPad)
26252623 Keys* sK = NULL;
26262624 int ret = WS_SUCCESS;
26272625
2628- if (ssh == NULL)
2626+ if (ssh == NULL || ssh->handshake == NULL )
26292627 ret = WS_BAD_ARGUMENT;
26302628 else {
26312629 if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) {
@@ -2658,19 +2656,17 @@ static int GenerateKeys(WOLFSSH* ssh, byte hashId, byte doKeyPad)
26582656 sK->encKey, sK->encKeySz,
26592657 ssh->k, ssh->kSz, ssh->h, ssh->hSz,
26602658 ssh->sessionId, ssh->sessionIdSz, doKeyPad);
2661- if (ret == WS_SUCCESS) {
2662- if (!ssh->handshake->aeadMode) {
2663- ret = GenerateKey(hashId, 'E',
2664- cK->macKey, cK->macKeySz,
2665- ssh->k, ssh->kSz, ssh->h, ssh->hSz,
2666- ssh->sessionId, ssh->sessionIdSz, doKeyPad);
2667- if (ret == WS_SUCCESS) {
2668- ret = GenerateKey(hashId, 'F',
2669- sK->macKey, sK->macKeySz,
2670- ssh->k, ssh->kSz, ssh->h, ssh->hSz,
2671- ssh->sessionId, ssh->sessionIdSz, doKeyPad);
2672- }
2673- }
2659+ if (ret == WS_SUCCESS && cK->macKeySz > 0) {
2660+ ret = GenerateKey(hashId, 'E',
2661+ cK->macKey, cK->macKeySz,
2662+ ssh->k, ssh->kSz, ssh->h, ssh->hSz,
2663+ ssh->sessionId, ssh->sessionIdSz, doKeyPad);
2664+ }
2665+ if (ret == WS_SUCCESS && sK->macKeySz > 0) {
2666+ ret = GenerateKey(hashId, 'F',
2667+ sK->macKey, sK->macKeySz,
2668+ ssh->k, ssh->kSz, ssh->h, ssh->hSz,
2669+ ssh->sessionId, ssh->sessionIdSz, doKeyPad);
26742670 }
26752671
26762672#ifdef SHOW_SECRETS
@@ -4243,6 +4239,52 @@ static word32 AlgoListSz(const char* algoList)
42434239}
42444240
42454241
4242+ static void SetLocalAlgoIds(HandshakeInfo* hs,
4243+ byte encId, byte aeadMode, byte macId)
4244+ {
4245+ byte blkSz = BlockSzForId(encId);
4246+ hs->encryptId = encId;
4247+ hs->aeadMode = aeadMode;
4248+ hs->blockSz = blkSz;
4249+ hs->keys.encKeySz = KeySzForId(encId);
4250+ if (!aeadMode) {
4251+ hs->keys.ivSz = blkSz;
4252+ hs->macId = macId;
4253+ hs->macSz = MacSzForId(macId);
4254+ hs->keys.macKeySz = KeySzForId(macId);
4255+ }
4256+ else {
4257+ hs->keys.ivSz = AEAD_NONCE_SZ;
4258+ hs->macId = ID_NONE;
4259+ hs->macSz = blkSz;
4260+ hs->keys.macKeySz = 0;
4261+ }
4262+ }
4263+
4264+
4265+ static void SetPeerAlgoIds(HandshakeInfo* hs,
4266+ byte encId, byte aeadMode, byte macId)
4267+ {
4268+ byte blkSz = BlockSzForId(encId);
4269+ hs->peerEncryptId = encId;
4270+ hs->peerAeadMode = aeadMode;
4271+ hs->peerBlockSz = blkSz;
4272+ hs->peerKeys.encKeySz = KeySzForId(encId);
4273+ if (!aeadMode) {
4274+ hs->peerKeys.ivSz = blkSz;
4275+ hs->peerMacId = macId;
4276+ hs->peerMacSz = MacSzForId(macId);
4277+ hs->peerKeys.macKeySz = KeySzForId(macId);
4278+ }
4279+ else {
4280+ hs->peerKeys.ivSz = AEAD_NONCE_SZ;
4281+ hs->peerMacId = ID_NONE;
4282+ hs->peerMacSz = blkSz;
4283+ hs->peerKeys.macKeySz = 0;
4284+ }
4285+ }
4286+
4287+
42464288static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
42474289{
42484290 int ret = WS_SUCCESS;
@@ -4258,6 +4300,9 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
42584300 word32 cannedAlgoNamesSz;
42594301 word32 skipSz = 0;
42604302 word32 begin;
4303+ byte c2sEncryptId = ID_NONE, s2cEncryptId = ID_NONE;
4304+ byte c2sMacId = ID_NONE, s2cMacId = ID_NONE;
4305+ byte c2sAeadMode = 0, s2cAeadMode = 0;
42614306
42624307 WLOG(WS_LOG_DEBUG, "Entering DoKexInit()");
42634308
@@ -4399,6 +4444,10 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
43994444 ret = WS_MATCH_ENC_ALGO_E;
44004445 }
44014446 }
4447+ if (ret == WS_SUCCESS) {
4448+ c2sEncryptId = algoId;
4449+ c2sAeadMode = AeadModeForId(algoId);
4450+ }
44024451
44034452 /* Enc Algorithms - Server to Client */
44044453 if (ret == WS_SUCCESS) {
@@ -4407,32 +4456,21 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
44074456 ret = GetNameList(list, &listSz, buf, len, &begin);
44084457 }
44094458 if (ret == WS_SUCCESS) {
4410- algoId = MatchIdLists(side, list, listSz, &algoId, 1);
4459+ cannedAlgoNamesSz = AlgoListSz(ssh->algoListCipher);
4460+ cannedListSz = (word32)sizeof(cannedList);
4461+ ret = GetNameListRaw(cannedList, &cannedListSz,
4462+ (const byte*)ssh->algoListCipher, cannedAlgoNamesSz);
4463+ }
4464+ if (ret == WS_SUCCESS) {
4465+ algoId = MatchIdLists(side, list, listSz, cannedList, cannedListSz);
44114466 if (algoId == ID_UNKNOWN) {
44124467 WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo S2C");
44134468 ret = WS_MATCH_ENC_ALGO_E;
44144469 }
44154470 }
44164471 if (ret == WS_SUCCESS) {
4417- ssh->handshake->encryptId = algoId;
4418- ssh->handshake->aeadMode = AeadModeForId(algoId);
4419- ssh->handshake->blockSz = BlockSzForId(algoId);
4420- ssh->handshake->keys.encKeySz =
4421- ssh->handshake->peerKeys.encKeySz =
4422- KeySzForId(algoId);
4423- if (!ssh->handshake->aeadMode) {
4424- ssh->handshake->keys.ivSz =
4425- ssh->handshake->peerKeys.ivSz =
4426- ssh->handshake->blockSz;
4427- }
4428- else {
4429- #ifndef WOLFSSH_NO_AEAD
4430- ssh->handshake->keys.ivSz =
4431- ssh->handshake->peerKeys.ivSz =
4432- AEAD_NONCE_SZ;
4433- ssh->handshake->macSz = ssh->handshake->blockSz;
4434- #endif
4435- }
4472+ s2cEncryptId = algoId;
4473+ s2cAeadMode = AeadModeForId(algoId);
44364474 }
44374475
44384476 /* MAC Algorithms - Client to Server */
@@ -4441,7 +4479,7 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
44414479 listSz = (word32)sizeof(list);
44424480 ret = GetNameList(list, &listSz, buf, len, &begin);
44434481 }
4444- if (ret == WS_SUCCESS && !ssh->handshake->aeadMode ) {
4482+ if (ret == WS_SUCCESS && !c2sAeadMode ) {
44454483 cannedAlgoNamesSz = AlgoListSz(ssh->algoListMac);
44464484 cannedListSz = (word32)sizeof(cannedList);
44474485 ret = GetNameListRaw(cannedList, &cannedListSz,
@@ -4453,6 +4491,9 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
44534491 WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo C2S");
44544492 ret = WS_MATCH_MAC_ALGO_E;
44554493 }
4494+ else {
4495+ c2sMacId = algoId;
4496+ }
44564497 }
44574498 }
44584499
@@ -4462,18 +4503,20 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
44624503 listSz = (word32)sizeof(list);
44634504 ret = GetNameList(list, &listSz, buf, len, &begin);
44644505 }
4465- if (ret == WS_SUCCESS && !ssh->handshake->aeadMode) {
4466- algoId = MatchIdLists(side, list, listSz, &algoId, 1);
4467- if (algoId == ID_UNKNOWN) {
4468- WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C");
4469- ret = WS_MATCH_MAC_ALGO_E;
4470- }
4471- else {
4472- ssh->handshake->macId = algoId;
4473- ssh->handshake->macSz = MacSzForId(algoId);
4474- ssh->handshake->keys.macKeySz =
4475- ssh->handshake->peerKeys.macKeySz =
4476- KeySzForId(algoId);
4506+ if (ret == WS_SUCCESS && !s2cAeadMode) {
4507+ cannedAlgoNamesSz = AlgoListSz(ssh->algoListMac);
4508+ cannedListSz = (word32)sizeof(cannedList);
4509+ ret = GetNameListRaw(cannedList, &cannedListSz,
4510+ (const byte*)ssh->algoListMac, cannedAlgoNamesSz);
4511+ if (ret == WS_SUCCESS) {
4512+ algoId = MatchIdLists(side, list, listSz, cannedList, cannedListSz);
4513+ if (algoId == ID_UNKNOWN) {
4514+ WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C");
4515+ ret = WS_MATCH_MAC_ALGO_E;
4516+ }
4517+ else {
4518+ s2cMacId = algoId;
4519+ }
44774520 }
44784521 }
44794522
@@ -4547,6 +4590,19 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
45474590 begin += skipSz;
45484591 }
45494592
4593+ if (ret == WS_SUCCESS) {
4594+ if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) {
4595+ /* s2c = local (server outgoing), c2s = peer (client incoming) */
4596+ SetLocalAlgoIds(ssh->handshake, s2cEncryptId, s2cAeadMode, s2cMacId);
4597+ SetPeerAlgoIds (ssh->handshake, c2sEncryptId, c2sAeadMode, c2sMacId);
4598+ }
4599+ else {
4600+ /* c2s = local (client outgoing), s2c = peer (server incoming) */
4601+ SetLocalAlgoIds(ssh->handshake, c2sEncryptId, c2sAeadMode, c2sMacId);
4602+ SetPeerAlgoIds (ssh->handshake, s2cEncryptId, s2cAeadMode, s2cMacId);
4603+ }
4604+ }
4605+
45504606 if (ret == WS_SUCCESS) {
45514607 wc_HashAlg* hash = &ssh->handshake->kexHash;
45524608 enum wc_HashType hashId = (enum wc_HashType)ssh->handshake->kexHashId;
@@ -6226,11 +6282,11 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
62266282 }
62276283
62286284 if (ret == WS_SUCCESS) {
6229- ssh->peerEncryptId = ssh->handshake->encryptId ;
6230- ssh->peerMacId = ssh->handshake->macId ;
6231- ssh->peerBlockSz = ssh->handshake->blockSz ;
6232- ssh->peerMacSz = ssh->handshake->macSz ;
6233- ssh->peerAeadMode = ssh->handshake->aeadMode ;
6285+ ssh->peerEncryptId = ssh->handshake->peerEncryptId ;
6286+ ssh->peerMacId = ssh->handshake->peerMacId ;
6287+ ssh->peerBlockSz = ssh->handshake->peerBlockSz ;
6288+ ssh->peerMacSz = ssh->handshake->peerMacSz ;
6289+ ssh->peerAeadMode = ssh->handshake->peerAeadMode ;
62346290 WMEMCPY(&ssh->peerKeys, &ssh->handshake->peerKeys, sizeof(Keys));
62356291
62366292 switch (ssh->peerEncryptId) {
@@ -17959,6 +18015,25 @@ int wolfSSH_TestDoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
1795918015 return DoKexInit(ssh, buf, len, idx);
1796018016}
1796118017
18018+ int wolfSSH_TestDoNewKeys(WOLFSSH* ssh)
18019+ {
18020+ /* DoNewKeys ignores buf/len/idx (marked WOLFSSH_UNUSED internally). */
18021+ return DoNewKeys(ssh, NULL, 0, NULL);
18022+ }
18023+
18024+ void wolfSSH_TestFreeHandshake(WOLFSSH* ssh)
18025+ {
18026+ if (ssh != NULL) {
18027+ HandshakeInfoFree(ssh->handshake, ssh->ctx ? ssh->ctx->heap : NULL);
18028+ ssh->handshake = NULL;
18029+ }
18030+ }
18031+
18032+ int wolfSSH_TestGenerateKeys(WOLFSSH* ssh, byte hashId)
18033+ {
18034+ return GenerateKeys(ssh, hashId, 1);
18035+ }
18036+
1796218037int wolfSSH_TestDoKexDhInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
1796318038{
1796418039 return DoKexDhInit(ssh, buf, len, idx);
0 commit comments