Skip to content

Commit 0bd9a59

Browse files
naiming-zededaeriknordmark
authored andcommitted
Replace MD5 with a cryptographically secure random IV generation
- edgeview has the mode of using encryption for the payload, and it was using static md5 IV value. this patch is to fix with the secure random dynamic IV generation for the encryption op. Signed-off-by: naiming-zededa <naiming@zededa.com>
1 parent 780f0c0 commit 0bd9a59

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

pkg/edgeview/src/crypto.go

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"crypto/cipher"
1111
"crypto/ecdsa"
1212
"crypto/hmac"
13-
"crypto/md5"
1413
"crypto/rand"
1514
"crypto/rsa"
1615
"crypto/sha256"
@@ -34,7 +33,6 @@ const hashBytesNum = 32 // Hmac Sha256 Hash is 32 bytes fixed
3433
var (
3534
nonceOpEncrption bool
3635
nonceHash [32]byte // JWT Nonce with Sha256Sum for encryption
37-
viBytes [16]byte // vi 16 bytes data for encryption
3836
jwtNonce string // JWT session Nonce for authentication
3937
clientAuthType types.EvAuthType // edgeview client authentication type
4038
evSSHPrivateKey string // path to Edgeview SSH private key
@@ -47,6 +45,7 @@ type envelopeMsg struct {
4745
Message []byte `json:"message"`
4846
Sha256Hash [hashBytesNum]byte `json:"sha256Hash"`
4947
Signature []byte // Field to store the cert auth signature
48+
IV []byte `json:"iv,omitempty"`
5049
}
5150

5251
// LoadPublicKey loads a public key from a PEM file and determines its type (RSA or EC)
@@ -178,6 +177,13 @@ func addEnvelopeAndWriteWss(msg []byte, isText bool, clientAuthNeeded bool) erro
178177
return err
179178
}
180179

180+
func rawTextMsgWriteWss(msg []byte) error {
181+
wssWrMutex.Lock()
182+
err := websocketConn.WriteMessage(websocket.TextMessage, msg)
183+
wssWrMutex.Unlock()
184+
return err
185+
}
186+
181187
func addEvelopeToData(msg []byte) []byte {
182188
if nonceOpEncrption {
183189
return encryptData(msg)
@@ -208,14 +214,15 @@ func signAuthenData(msg []byte) []byte {
208214
}
209215

210216
func encryptData(msg []byte) []byte {
211-
eMsg, err := encryptEvMsg(msg)
217+
iv, eMsg, err := encryptEvMsg(msg)
212218
if err != nil {
213219
log.Errorf("encrypt failed %v", err)
214220
return nil
215221
}
216222
jmsg := envelopeMsg{
217223
Message: eMsg,
218224
Sha256Hash: sha256.Sum256(msg),
225+
IV: iv,
219226
}
220227

221228
jdata, err := json.Marshal(jmsg)
@@ -284,7 +291,7 @@ func verifyEnvelopeData(data []byte, checkClientAuth bool) (bool, bool, []byte,
284291
}
285292

286293
if nonceOpEncrption {
287-
ok, msg := decryptEvMsg(envelope.Message)
294+
ok, msg := decryptEvMsg(envelope.IV, envelope.Message)
288295
if !ok {
289296
return true, false, nil, keyComment
290297
}
@@ -304,24 +311,37 @@ func verifyEnvelopeData(data []byte, checkClientAuth bool) (bool, bool, []byte,
304311
return true, true, envelope.Message, keyComment
305312
}
306313

307-
func encryptEvMsg(msg []byte) ([]byte, error) {
314+
func encryptEvMsg(msg []byte) ([]byte, []byte, error) {
308315
block, err := aes.NewCipher(nonceHash[:])
309316
if err != nil {
310-
return nil, err
317+
return nil, nil, err
311318
}
312319

313-
cfb := cipher.NewCFBEncrypter(block, viBytes[:])
320+
iv := make([]byte, aes.BlockSize)
321+
if _, err := rand.Read(iv); err != nil {
322+
return nil, nil, err
323+
}
324+
325+
cfb := cipher.NewCFBEncrypter(block, iv)
314326
cipherText := make([]byte, len(msg))
315327
cfb.XORKeyStream(cipherText, msg)
316-
return cipherText, nil
328+
329+
return iv, cipherText, nil
317330
}
318331

319-
func decryptEvMsg(data []byte) (bool, []byte) {
332+
func decryptEvMsg(iv, data []byte) (bool, []byte) {
333+
if len(iv) != aes.BlockSize {
334+
// can not use encryption for sending this message, otherwise client side won't be able to decrypt
335+
_ = rawTextMsgWriteWss([]byte(fmt.Sprintf("Edgeview encrypted message missing or invalid IV. Need Edgeview Client version %s or higher\n", encMinVersion)))
336+
return false, nil
337+
}
338+
320339
block, err := aes.NewCipher(nonceHash[:])
321340
if err != nil {
322341
return false, nil
323342
}
324-
cfb := cipher.NewCFBDecrypter(block, viBytes[:])
343+
344+
cfb := cipher.NewCFBDecrypter(block, iv)
325345
plainText := make([]byte, len(data))
326346
cfb.XORKeyStream(plainText, data)
327347
return true, plainText
@@ -335,7 +355,6 @@ func encryptVarInit(jdata types.EvjwtInfo) {
335355
nonceOpEncrption = jdata.Enc
336356
if nonceOpEncrption {
337357
nonceHash = sha256.Sum256([]byte(jdata.Key))
338-
viBytes = md5.Sum([]byte(jdata.Key))
339358
}
340359
}
341360

pkg/edgeview/src/edge-view.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,14 @@ const (
4444
agentName = "edgeview"
4545
closeMessage = "+++Done+++"
4646
tarCopyDoneMsg = "+++TarCopyDone+++"
47-
edgeViewVersion = "0.8.6" // set the version now to 0.8.6
47+
edgeViewVersion = "0.8.7"
4848
cpLogFileString = "copy-logfiles"
4949
clientIPMsg = "YourEndPointIPAddr:"
5050
serverRateMsg = "ServerRateLimit:disable"
5151
tcpPktRate = MbpsToBytes * 5 * 1.2 // 125k Bytes * 5 * 1.2, or 5Mbits add 20%
5252
tcpPktBurst = 65536 // burst allow bytes
5353
tarMinVersion = "0.8.5" // for tar operation, expect client to have newer version
54+
encMinVersion = "0.8.7" // for encryption operation, expect client to have newer version
5455
verifyFailed = "+++Verify failed+++"
5556
keepaliveInterval = 30 * time.Second // interval for sending websocket ping messages
5657
)

0 commit comments

Comments
 (0)