@@ -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
@@ -2624,7 +2622,7 @@ static int GenerateKeys(WOLFSSH* ssh, byte hashId, byte doKeyPad)
26242622 Keys* sK = NULL;
26252623 int ret = WS_SUCCESS;
26262624
2627- if (ssh == NULL)
2625+ if (ssh == NULL || ssh->handshake == NULL )
26282626 ret = WS_BAD_ARGUMENT;
26292627 else {
26302628 if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) {
@@ -2657,19 +2655,17 @@ static int GenerateKeys(WOLFSSH* ssh, byte hashId, byte doKeyPad)
26572655 sK->encKey, sK->encKeySz,
26582656 ssh->k, ssh->kSz, ssh->h, ssh->hSz,
26592657 ssh->sessionId, ssh->sessionIdSz, doKeyPad);
2660- if (ret == WS_SUCCESS) {
2661- if (!ssh->handshake->aeadMode) {
2662- ret = GenerateKey(hashId, 'E',
2663- cK->macKey, cK->macKeySz,
2664- ssh->k, ssh->kSz, ssh->h, ssh->hSz,
2665- ssh->sessionId, ssh->sessionIdSz, doKeyPad);
2666- if (ret == WS_SUCCESS) {
2667- ret = GenerateKey(hashId, 'F',
2668- sK->macKey, sK->macKeySz,
2669- ssh->k, ssh->kSz, ssh->h, ssh->hSz,
2670- ssh->sessionId, ssh->sessionIdSz, doKeyPad);
2671- }
2672- }
2658+ if (ret == WS_SUCCESS && cK->macKeySz > 0) {
2659+ ret = GenerateKey(hashId, 'E',
2660+ cK->macKey, cK->macKeySz,
2661+ ssh->k, ssh->kSz, ssh->h, ssh->hSz,
2662+ ssh->sessionId, ssh->sessionIdSz, doKeyPad);
2663+ }
2664+ if (ret == WS_SUCCESS && sK->macKeySz > 0) {
2665+ ret = GenerateKey(hashId, 'F',
2666+ sK->macKey, sK->macKeySz,
2667+ ssh->k, ssh->kSz, ssh->h, ssh->hSz,
2668+ ssh->sessionId, ssh->sessionIdSz, doKeyPad);
26732669 }
26742670
26752671#ifdef SHOW_SECRETS
@@ -4242,6 +4238,52 @@ static word32 AlgoListSz(const char* algoList)
42424238}
42434239
42444240
4241+ static void SetLocalAlgoIds(HandshakeInfo* hs,
4242+ byte encId, byte aeadMode, byte macId)
4243+ {
4244+ byte blkSz = BlockSzForId(encId);
4245+ hs->encryptId = encId;
4246+ hs->aeadMode = aeadMode;
4247+ hs->blockSz = blkSz;
4248+ hs->keys.encKeySz = KeySzForId(encId);
4249+ if (!aeadMode) {
4250+ hs->keys.ivSz = blkSz;
4251+ hs->macId = macId;
4252+ hs->macSz = MacSzForId(macId);
4253+ hs->keys.macKeySz = KeySzForId(macId);
4254+ }
4255+ else {
4256+ hs->keys.ivSz = AEAD_NONCE_SZ;
4257+ hs->macId = ID_NONE;
4258+ hs->macSz = blkSz;
4259+ hs->keys.macKeySz = 0;
4260+ }
4261+ }
4262+
4263+
4264+ static void SetPeerAlgoIds(HandshakeInfo* hs,
4265+ byte encId, byte aeadMode, byte macId)
4266+ {
4267+ byte blkSz = BlockSzForId(encId);
4268+ hs->peerEncryptId = encId;
4269+ hs->peerAeadMode = aeadMode;
4270+ hs->peerBlockSz = blkSz;
4271+ hs->peerKeys.encKeySz = KeySzForId(encId);
4272+ if (!aeadMode) {
4273+ hs->peerKeys.ivSz = blkSz;
4274+ hs->peerMacId = macId;
4275+ hs->peerMacSz = MacSzForId(macId);
4276+ hs->peerKeys.macKeySz = KeySzForId(macId);
4277+ }
4278+ else {
4279+ hs->peerKeys.ivSz = AEAD_NONCE_SZ;
4280+ hs->peerMacId = ID_NONE;
4281+ hs->peerMacSz = blkSz;
4282+ hs->peerKeys.macKeySz = 0;
4283+ }
4284+ }
4285+
4286+
42454287static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
42464288{
42474289 int ret = WS_SUCCESS;
@@ -4257,6 +4299,9 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
42574299 word32 cannedAlgoNamesSz;
42584300 word32 skipSz = 0;
42594301 word32 begin;
4302+ byte c2sEncryptId = ID_NONE, s2cEncryptId = ID_NONE;
4303+ byte c2sMacId = ID_NONE, s2cMacId = ID_NONE;
4304+ byte c2sAeadMode = 0, s2cAeadMode = 0;
42604305
42614306 WLOG(WS_LOG_DEBUG, "Entering DoKexInit()");
42624307
@@ -4398,6 +4443,10 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
43984443 ret = WS_MATCH_ENC_ALGO_E;
43994444 }
44004445 }
4446+ if (ret == WS_SUCCESS) {
4447+ c2sEncryptId = algoId;
4448+ c2sAeadMode = AeadModeForId(algoId);
4449+ }
44014450
44024451 /* Enc Algorithms - Server to Client */
44034452 if (ret == WS_SUCCESS) {
@@ -4406,32 +4455,21 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
44064455 ret = GetNameList(list, &listSz, buf, len, &begin);
44074456 }
44084457 if (ret == WS_SUCCESS) {
4409- algoId = MatchIdLists(side, list, listSz, &algoId, 1);
4458+ cannedAlgoNamesSz = AlgoListSz(ssh->algoListCipher);
4459+ cannedListSz = (word32)sizeof(cannedList);
4460+ ret = GetNameListRaw(cannedList, &cannedListSz,
4461+ (const byte*)ssh->algoListCipher, cannedAlgoNamesSz);
4462+ }
4463+ if (ret == WS_SUCCESS) {
4464+ algoId = MatchIdLists(side, list, listSz, cannedList, cannedListSz);
44104465 if (algoId == ID_UNKNOWN) {
44114466 WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo S2C");
44124467 ret = WS_MATCH_ENC_ALGO_E;
44134468 }
44144469 }
44154470 if (ret == WS_SUCCESS) {
4416- ssh->handshake->encryptId = algoId;
4417- ssh->handshake->aeadMode = AeadModeForId(algoId);
4418- ssh->handshake->blockSz = BlockSzForId(algoId);
4419- ssh->handshake->keys.encKeySz =
4420- ssh->handshake->peerKeys.encKeySz =
4421- KeySzForId(algoId);
4422- if (!ssh->handshake->aeadMode) {
4423- ssh->handshake->keys.ivSz =
4424- ssh->handshake->peerKeys.ivSz =
4425- ssh->handshake->blockSz;
4426- }
4427- else {
4428- #ifndef WOLFSSH_NO_AEAD
4429- ssh->handshake->keys.ivSz =
4430- ssh->handshake->peerKeys.ivSz =
4431- AEAD_NONCE_SZ;
4432- ssh->handshake->macSz = ssh->handshake->blockSz;
4433- #endif
4434- }
4471+ s2cEncryptId = algoId;
4472+ s2cAeadMode = AeadModeForId(algoId);
44354473 }
44364474
44374475 /* MAC Algorithms - Client to Server */
@@ -4440,7 +4478,7 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
44404478 listSz = (word32)sizeof(list);
44414479 ret = GetNameList(list, &listSz, buf, len, &begin);
44424480 }
4443- if (ret == WS_SUCCESS && !ssh->handshake->aeadMode ) {
4481+ if (ret == WS_SUCCESS && !c2sAeadMode ) {
44444482 cannedAlgoNamesSz = AlgoListSz(ssh->algoListMac);
44454483 cannedListSz = (word32)sizeof(cannedList);
44464484 ret = GetNameListRaw(cannedList, &cannedListSz,
@@ -4452,6 +4490,9 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
44524490 WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo C2S");
44534491 ret = WS_MATCH_MAC_ALGO_E;
44544492 }
4493+ else {
4494+ c2sMacId = algoId;
4495+ }
44554496 }
44564497 }
44574498
@@ -4461,18 +4502,20 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
44614502 listSz = (word32)sizeof(list);
44624503 ret = GetNameList(list, &listSz, buf, len, &begin);
44634504 }
4464- if (ret == WS_SUCCESS && !ssh->handshake->aeadMode) {
4465- algoId = MatchIdLists(side, list, listSz, &algoId, 1);
4466- if (algoId == ID_UNKNOWN) {
4467- WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C");
4468- ret = WS_MATCH_MAC_ALGO_E;
4469- }
4470- else {
4471- ssh->handshake->macId = algoId;
4472- ssh->handshake->macSz = MacSzForId(algoId);
4473- ssh->handshake->keys.macKeySz =
4474- ssh->handshake->peerKeys.macKeySz =
4475- KeySzForId(algoId);
4505+ if (ret == WS_SUCCESS && !s2cAeadMode) {
4506+ cannedAlgoNamesSz = AlgoListSz(ssh->algoListMac);
4507+ cannedListSz = (word32)sizeof(cannedList);
4508+ ret = GetNameListRaw(cannedList, &cannedListSz,
4509+ (const byte*)ssh->algoListMac, cannedAlgoNamesSz);
4510+ if (ret == WS_SUCCESS) {
4511+ algoId = MatchIdLists(side, list, listSz, cannedList, cannedListSz);
4512+ if (algoId == ID_UNKNOWN) {
4513+ WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C");
4514+ ret = WS_MATCH_MAC_ALGO_E;
4515+ }
4516+ else {
4517+ s2cMacId = algoId;
4518+ }
44764519 }
44774520 }
44784521
@@ -4546,6 +4589,19 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
45464589 begin += skipSz;
45474590 }
45484591
4592+ if (ret == WS_SUCCESS) {
4593+ if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) {
4594+ /* s2c = local (server outgoing), c2s = peer (client incoming) */
4595+ SetLocalAlgoIds(ssh->handshake, s2cEncryptId, s2cAeadMode, s2cMacId);
4596+ SetPeerAlgoIds (ssh->handshake, c2sEncryptId, c2sAeadMode, c2sMacId);
4597+ }
4598+ else {
4599+ /* c2s = local (client outgoing), s2c = peer (server incoming) */
4600+ SetLocalAlgoIds(ssh->handshake, c2sEncryptId, c2sAeadMode, c2sMacId);
4601+ SetPeerAlgoIds (ssh->handshake, s2cEncryptId, s2cAeadMode, s2cMacId);
4602+ }
4603+ }
4604+
45494605 if (ret == WS_SUCCESS) {
45504606 wc_HashAlg* hash = &ssh->handshake->kexHash;
45514607 enum wc_HashType hashId = (enum wc_HashType)ssh->handshake->kexHashId;
@@ -6225,11 +6281,11 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
62256281 }
62266282
62276283 if (ret == WS_SUCCESS) {
6228- ssh->peerEncryptId = ssh->handshake->encryptId ;
6229- ssh->peerMacId = ssh->handshake->macId ;
6230- ssh->peerBlockSz = ssh->handshake->blockSz ;
6231- ssh->peerMacSz = ssh->handshake->macSz ;
6232- ssh->peerAeadMode = ssh->handshake->aeadMode ;
6284+ ssh->peerEncryptId = ssh->handshake->peerEncryptId ;
6285+ ssh->peerMacId = ssh->handshake->peerMacId ;
6286+ ssh->peerBlockSz = ssh->handshake->peerBlockSz ;
6287+ ssh->peerMacSz = ssh->handshake->peerMacSz ;
6288+ ssh->peerAeadMode = ssh->handshake->peerAeadMode ;
62336289 WMEMCPY(&ssh->peerKeys, &ssh->handshake->peerKeys, sizeof(Keys));
62346290
62356291 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