mirror of https://github.com/wolfSSL/wolfssh.git
1. Generates the session keys.
2. Starting to tie into the bulk encryption and MAC.pull/1/head
parent
917c6a84c4
commit
2d959d7bea
115
src/internal.c
115
src/internal.c
|
@ -655,7 +655,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
|
|||
return WS_INVALID_ALGO_ID;
|
||||
}
|
||||
|
||||
ssh->handshake->keyExchangeId = algoId;
|
||||
ssh->handshake->kexId = algoId;
|
||||
|
||||
/* Server Host Key Algorithms */
|
||||
WLOG(WS_LOG_DEBUG, "DKI: Server Host Key Algorithms");
|
||||
|
@ -667,7 +667,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
|
|||
return WS_INVALID_ALGO_ID;
|
||||
}
|
||||
|
||||
ssh->handshake->publicKeyId = algoId;
|
||||
ssh->handshake->pubKeyId = algoId;
|
||||
|
||||
/* Enc Algorithms - Client to Server */
|
||||
WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Client to Server");
|
||||
|
@ -688,7 +688,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
|
|||
return WS_INVALID_ALGO_ID;
|
||||
}
|
||||
|
||||
ssh->handshake->encryptionId = algoId;
|
||||
ssh->handshake->encryptId = algoId;
|
||||
ssh->handshake->blockSz = ssh->ivClientSz = ssh->ivServerSz
|
||||
= BlockSzForId(algoId);
|
||||
ssh->encKeyClientSz = ssh->encKeyServerSz = KeySzForId(algoId);
|
||||
|
@ -712,7 +712,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
|
|||
return WS_INVALID_ALGO_ID;
|
||||
}
|
||||
|
||||
ssh->handshake->integrityId = algoId;
|
||||
ssh->handshake->macId = algoId;
|
||||
ssh->handshake->macSz = MacSzForId(algoId);
|
||||
ssh->macKeyClientSz = ssh->macKeyServerSz = KeySzForId(algoId);
|
||||
|
||||
|
@ -850,6 +850,21 @@ static int DoKexDhInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
|
|||
}
|
||||
|
||||
|
||||
static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
|
||||
{
|
||||
(void)buf;
|
||||
(void)len;
|
||||
(void)idx;
|
||||
|
||||
ssh->peerEncryptId = ssh->handshake->encryptId;
|
||||
ssh->peerMacId = ssh->handshake->macId;
|
||||
|
||||
ssh->clientState = CLIENT_USING_KEYS;
|
||||
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int GenerateKey(uint8_t* key, uint32_t keySz, uint8_t keyId,
|
||||
const uint8_t* k, uint32_t kSz,
|
||||
const uint8_t* h, uint32_t hSz,
|
||||
|
@ -857,11 +872,19 @@ static int GenerateKey(uint8_t* key, uint32_t keySz, uint8_t keyId,
|
|||
{
|
||||
uint32_t blocks, remainder;
|
||||
Sha sha;
|
||||
uint8_t kPad = 0;
|
||||
uint8_t pad = 0;
|
||||
uint8_t kSzFlat[LENGTH_SZ];
|
||||
|
||||
if (k[0] & 0x80) kPad = 1;
|
||||
c32toa(kSz, kSzFlat);
|
||||
|
||||
blocks = keySz / SHA_DIGEST_SIZE;
|
||||
remainder = keySz % SHA_DIGEST_SIZE;
|
||||
|
||||
InitSha(&sha);
|
||||
ShaUpdate(&sha, kSzFlat, LENGTH_SZ);
|
||||
if (kPad) ShaUpdate(&sha, &pad, 1);
|
||||
ShaUpdate(&sha, k, kSz);
|
||||
ShaUpdate(&sha, h, hSz);
|
||||
ShaUpdate(&sha, &keyId, sizeof(keyId));
|
||||
|
@ -882,6 +905,8 @@ static int GenerateKey(uint8_t* key, uint32_t keySz, uint8_t keyId,
|
|||
|
||||
for (curBlock = 1; curBlock < blocks; curBlock++) {
|
||||
InitSha(&sha);
|
||||
ShaUpdate(&sha, kSzFlat, LENGTH_SZ);
|
||||
if (kPad) ShaUpdate(&sha, &pad, 1);
|
||||
ShaUpdate(&sha, k, kSz);
|
||||
ShaUpdate(&sha, h, hSz);
|
||||
ShaUpdate(&sha, key, runningKeySz);
|
||||
|
@ -892,6 +917,8 @@ static int GenerateKey(uint8_t* key, uint32_t keySz, uint8_t keyId,
|
|||
if (remainder > 0) {
|
||||
uint8_t lastBlock[SHA_DIGEST_SIZE];
|
||||
InitSha(&sha);
|
||||
ShaUpdate(&sha, kSzFlat, LENGTH_SZ);
|
||||
if (kPad) ShaUpdate(&sha, &pad, 1);
|
||||
ShaUpdate(&sha, k, kSz);
|
||||
ShaUpdate(&sha, h, hSz);
|
||||
ShaUpdate(&sha, key, runningKeySz);
|
||||
|
@ -900,6 +927,9 @@ static int GenerateKey(uint8_t* key, uint32_t keySz, uint8_t keyId,
|
|||
}
|
||||
}
|
||||
|
||||
printf("Key ID %c:", keyId);
|
||||
DumpOctetString(key, keySz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -935,6 +965,7 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
uint8_t padSz;
|
||||
uint8_t msg;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "DoPacket sequence number: %d", ssh->peerSeq);
|
||||
/* Problem: len is equal to the amount of data left in the input buffer.
|
||||
* The beginning part of that data is the packet we want to
|
||||
* decode. The remainder is the pad and the MAC. */
|
||||
|
@ -944,6 +975,22 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
msg = buf[idx++];
|
||||
switch (msg) {
|
||||
|
||||
case MSGID_DISCONNECT:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_INIT (len = %d)", payloadSz - 1);
|
||||
break;
|
||||
|
||||
case MSGID_IGNORE:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_INIT (len = %d)", payloadSz - 1);
|
||||
break;
|
||||
|
||||
case MSGID_UNIMPLEMENTED:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_INIT (len = %d)", payloadSz - 1);
|
||||
break;
|
||||
|
||||
case MSGID_DEBUG:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_INIT (len = %d)", payloadSz - 1);
|
||||
break;
|
||||
|
||||
case MSGID_KEXINIT:
|
||||
{
|
||||
uint8_t scratchLen[LENGTH_SZ];
|
||||
|
@ -956,6 +1003,11 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
}
|
||||
break;
|
||||
|
||||
case MSGID_NEWKEYS:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_NEWKEYS (len = %d)", payloadSz - 1);
|
||||
DoNewKeys(ssh, buf, payloadSz - 1, &idx);
|
||||
break;
|
||||
|
||||
case MSGID_KEXDH_INIT:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_INIT (len = %d)", payloadSz - 1);
|
||||
/* The mpint is 256 bytes long, the length is the standard 4 bytes,
|
||||
|
@ -1116,24 +1168,44 @@ static int BundlePacket(WOLFSSH* ssh)
|
|||
uint8_t* output;
|
||||
uint32_t idx;
|
||||
uint8_t paddingSz;
|
||||
uint8_t flatSeq[LENGTH_SZ];
|
||||
|
||||
output = ssh->outputBuffer.buffer;
|
||||
idx = ssh->outputBuffer.length;
|
||||
paddingSz = ssh->paddingSz;
|
||||
c32toa(ssh->seq++, flatSeq);
|
||||
|
||||
/* Add the padding */
|
||||
WMEMSET(output + idx, 0, paddingSz);
|
||||
idx += paddingSz;
|
||||
|
||||
/* Need to MAC the sequence number and the unencrypted packet */
|
||||
switch (ssh->integrityId) {
|
||||
switch (ssh->macId) {
|
||||
case ID_NONE:
|
||||
break;
|
||||
#if 0
|
||||
case ID_HMAC_SHA1_96:
|
||||
{
|
||||
Hmac hmac;
|
||||
uint8_t digest[SHA_DIGEST_SIZE];
|
||||
|
||||
HmacSetKey(&hmac, SHA, ssh->macKeyServer, ssh->macKeyServerSz);
|
||||
HmacUpdate(&hmac, flatSeq, sizeof(flatSeq));
|
||||
HmacUpdate(&sha,);
|
||||
HmacFinal(&sha, digest);
|
||||
WMEMCPY(, digest, SHA1_96_SIZE);
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_HMAC_SHA1:
|
||||
{
|
||||
Hmac hmac;
|
||||
|
||||
HmacSetKey(&hmac, SHA, ssh->macKeyServer, ssh->macKeyServerSz);
|
||||
HmacUpdate(&hmac, flatSeq, sizeof(flatSeq));
|
||||
HmacUpdate(&hmac,);
|
||||
HmacFinal(&hmac, );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -1144,7 +1216,7 @@ static int BundlePacket(WOLFSSH* ssh)
|
|||
ssh->seq++;
|
||||
|
||||
/* Encrypt the packet */
|
||||
switch (ssh->encryptionId) {
|
||||
switch (ssh->encryptId) {
|
||||
case ID_NONE:
|
||||
break;
|
||||
#if 0
|
||||
|
@ -1278,7 +1350,7 @@ int SendKexDhReply(WOLFSSH* ssh)
|
|||
|
||||
InitDhKey(&dhKey);
|
||||
|
||||
switch (ssh->handshake->keyExchangeId) {
|
||||
switch (ssh->handshake->kexId) {
|
||||
case ID_DH_GROUP1_SHA1:
|
||||
DhSetKey(&dhKey, dhPrimeGroup1, dhPrimeGroup1Sz,
|
||||
dhGenerator, dhGeneratorSz);
|
||||
|
@ -1395,10 +1467,7 @@ int SendKexDhReply(WOLFSSH* ssh)
|
|||
FreeRsaKey(&rsaKey);
|
||||
sigBlockSz = (LENGTH_SZ * 2) + 7 + sigSz;
|
||||
|
||||
if (0)
|
||||
GenerateKeys(ssh);
|
||||
else
|
||||
GenerateKeys(NULL);
|
||||
GenerateKeys(ssh);
|
||||
|
||||
/* Get the buffer, copy the packet data, once f is laid into the buffer,
|
||||
* add it to the hash and then add K. */
|
||||
|
@ -1454,6 +1523,30 @@ int SendKexDhReply(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
|
||||
int SendNewKeys(WOLFSSH* ssh)
|
||||
{
|
||||
uint8_t* output;
|
||||
uint32_t idx = 0;
|
||||
|
||||
PreparePacket(ssh, 1);
|
||||
|
||||
output = ssh->outputBuffer.buffer;
|
||||
idx = ssh->outputBuffer.length;
|
||||
|
||||
output[idx] = MSGID_NEWKEYS;
|
||||
|
||||
ssh->outputBuffer.length = idx;
|
||||
|
||||
BundlePacket(ssh);
|
||||
SendBuffered(ssh);
|
||||
|
||||
ssh->encryptId = ssh->handshake->encryptId;
|
||||
ssh->macId = ssh->handshake->macId;
|
||||
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#define LINE_WIDTH 16
|
||||
void DumpOctetString(const uint8_t* input, uint32_t inputSz)
|
||||
{
|
||||
|
|
14
src/ssh.c
14
src/ssh.c
|
@ -148,17 +148,15 @@ static WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
|
|||
ssh->ioReadCtx = &ssh->rfd; /* prevent invalid access if not correctly */
|
||||
ssh->ioWriteCtx = &ssh->wfd; /* set */
|
||||
ssh->blockSz = 8;
|
||||
ssh->keyExchangeId = ID_NONE;
|
||||
ssh->publicKeyId = ID_NONE;
|
||||
ssh->encryptionId = ID_NONE;
|
||||
ssh->integrityId = ID_NONE;
|
||||
ssh->encryptId = ID_NONE;
|
||||
ssh->macId = ID_NONE;
|
||||
ssh->rng = rng;
|
||||
ssh->kSz = sizeof(ssh->k);
|
||||
ssh->handshake = handshake;
|
||||
handshake->keyExchangeId = ID_NONE;
|
||||
handshake->publicKeyId = ID_NONE;
|
||||
handshake->encryptionId = ID_NONE;
|
||||
handshake->integrityId = ID_NONE;
|
||||
handshake->kexId = ID_NONE;
|
||||
handshake->pubKeyId = ID_NONE;
|
||||
handshake->encryptId = ID_NONE;
|
||||
handshake->macId = ID_NONE;
|
||||
|
||||
if (BufferInit(&ssh->inputBuffer, 0, ctx->heap) != WS_SUCCESS ||
|
||||
BufferInit(&ssh->outputBuffer, 0, ctx->heap) != WS_SUCCESS ||
|
||||
|
|
|
@ -90,6 +90,7 @@ enum {
|
|||
#define PAD_LENGTH_SZ 1
|
||||
#define BOOLEAN_SZ 1
|
||||
#define MSG_ID_SZ 1
|
||||
#define SHA1_96_SZ (96/8)
|
||||
|
||||
|
||||
WOLFSSH_LOCAL uint8_t NameToId(const char*, uint32_t);
|
||||
|
@ -134,10 +135,10 @@ struct WOLFSSH_CTX {
|
|||
|
||||
|
||||
typedef struct HandshakeInfo {
|
||||
uint8_t keyExchangeId;
|
||||
uint8_t publicKeyId;
|
||||
uint8_t encryptionId;
|
||||
uint8_t integrityId;
|
||||
uint8_t kexId;
|
||||
uint8_t pubKeyId;
|
||||
uint8_t encryptId;
|
||||
uint8_t macId;
|
||||
uint8_t kexPacketFollows;
|
||||
|
||||
uint8_t blockSz;
|
||||
|
@ -172,10 +173,10 @@ struct WOLFSSH {
|
|||
uint8_t connReset;
|
||||
uint8_t isClosed;
|
||||
|
||||
uint8_t keyExchangeId; /* not needed after handshake */
|
||||
uint8_t publicKeyId;
|
||||
uint8_t encryptionId;
|
||||
uint8_t integrityId;
|
||||
uint8_t encryptId;
|
||||
uint8_t macId;
|
||||
uint8_t peerEncryptId;
|
||||
uint8_t peerMacId;
|
||||
|
||||
Buffer inputBuffer;
|
||||
Buffer outputBuffer;
|
||||
|
@ -219,6 +220,7 @@ WOLFSSH_LOCAL int ProcessClientVersion(WOLFSSH*);
|
|||
WOLFSSH_LOCAL int SendServerVersion(WOLFSSH*);
|
||||
WOLFSSH_LOCAL int SendKexInit(WOLFSSH*);
|
||||
WOLFSSH_LOCAL int SendKexDhReply(WOLFSSH*);
|
||||
WOLFSSH_LOCAL int SendNewKeys(WOLFSSH*);
|
||||
|
||||
|
||||
enum AcceptStates {
|
||||
|
@ -236,7 +238,8 @@ enum ClientStates {
|
|||
CLIENT_BEGIN = 0,
|
||||
CLIENT_VERSION_DONE,
|
||||
CLIENT_ALGO_DONE,
|
||||
CLIENT_KEXDHINIT_DONE
|
||||
CLIENT_KEXDHINIT_DONE,
|
||||
CLIENT_USING_KEYS
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue