Skip to content

Commit

Permalink
fix 3DES-CBC
Browse files Browse the repository at this point in the history
  • Loading branch information
qmuntal committed Sep 26, 2023
1 parent 4899d53 commit 9375423
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 9 deletions.
2 changes: 1 addition & 1 deletion cng/aes.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func newCBC(encrypt bool, alg string, key, iv []byte) *cbcCipher {
switch alg {
case bcrypt.AES_ALGORITHM:
blockSize = aesBlockSize
case bcrypt.DES_ALGORITHM:
case bcrypt.DES_ALGORITHM, bcrypt.DES3_ALGORITHM:
blockSize = desBlockSize
default:
panic("invalid algorithm: " + alg)
Expand Down
9 changes: 5 additions & 4 deletions cng/des.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const desBlockSize = 8

type desCipher struct {
kh bcrypt.KEY_HANDLE
alg string
key []byte
}

Expand All @@ -26,7 +27,7 @@ func NewDESCipher(key []byte) (cipher.Block, error) {
if err != nil {
return nil, err
}
c := &desCipher{kh: kh, key: make([]byte, len(key))}
c := &desCipher{kh: kh, alg: bcrypt.DES_ALGORITHM, key: make([]byte, len(key))}
copy(c.key, key)
runtime.SetFinalizer(c, (*desCipher).finalize)
return c, nil
Expand All @@ -37,7 +38,7 @@ func NewTripleDESCipher(key []byte) (cipher.Block, error) {
if err != nil {
return nil, err
}
c := &desCipher{kh: kh, key: make([]byte, len(key))}
c := &desCipher{kh: kh, alg: bcrypt.DES3_ALGORITHM, key: make([]byte, len(key))}
copy(c.key, key)
runtime.SetFinalizer(c, (*desCipher).finalize)
return c, nil
Expand Down Expand Up @@ -98,9 +99,9 @@ func (c *desCipher) Decrypt(dst, src []byte) {
}

func (c *desCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode {
return newCBC(true, bcrypt.DES_ALGORITHM, c.key, iv)
return newCBC(true, c.alg, c.key, iv)
}

func (c *desCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode {
return newCBC(false, bcrypt.DES_ALGORITHM, c.key, iv)
return newCBC(false, c.alg, c.key, iv)
}
63 changes: 59 additions & 4 deletions cng/des_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,7 @@ func TestDESSharedBufferWithoutLengthAdjustment(t *testing.T) {
c.Encrypt(dst, src)
}

func TestCBCBlobEncryptBasicBlockEncryption(t *testing.T) {
func TestDESCBCBlobEncryptBasicBlockEncryption(t *testing.T) {
key := []byte{0x24, 0xcd, 0x8b, 0x13, 0x37, 0xc5, 0xc1, 0xb1}
iv := []byte{0x91, 0xc7, 0xa7, 0x54, 0x52, 0xef, 0x10, 0xdb}

Expand Down Expand Up @@ -1563,7 +1563,7 @@ func TestCBCBlobEncryptBasicBlockEncryption(t *testing.T) {
}
}

func TestCBCDecryptSimple(t *testing.T) {
func TestDESCBCDecryptSimple(t *testing.T) {
key := []byte{0x24, 0xcd, 0x8b, 0x13, 0x37, 0xc5, 0xc1, 0xb1}

block, err := cng.NewDESCipher(key)
Expand Down Expand Up @@ -1614,6 +1614,61 @@ func TestCBCDecryptSimple(t *testing.T) {
}
}

func TestTripleDESCBCDecryptSimple(t *testing.T) {
key := []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}

block, err := cng.NewTripleDESCipher(key)
if err != nil {
t.Fatal(err)
}

iv := []byte{0x91, 0xc7, 0xa7, 0x54, 0x52, 0xef, 0x10, 0xdb}

encrypter := cipher.NewCBCEncrypter(block, iv)
decrypter := cipher.NewCBCDecrypter(block, iv)

plainText := []byte{
0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73,
0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e,
0x65, 0x20, 0x4c, 0x6f, 0x72, 0x64, 0x20, 0x6f,
0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x52, 0x69,
0x6e, 0x67, 0x2c, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
}
cipherText := make([]byte, len(plainText))

encrypter.CryptBlocks(cipherText, plainText[:40])
encrypter.CryptBlocks(cipherText[40:], plainText[40:])

expectedCipherText := []byte{
0x44, 0x23, 0xc4, 0xf9, 0x5c, 0x7b, 0x1d, 0xd4,
0x46, 0xeb, 0x7d, 0xfe, 0x32, 0xd8, 0x14, 0x7c,
0x4f, 0xa9, 0x8f, 0x99, 0x55, 0xd4, 0x4a, 0xf9,
0x57, 0xee, 0x1e, 0x5b, 0x5c, 0x49, 0x9e, 0xea,
0x93, 0xd5, 0x4d, 0x54, 0x94, 0xf9, 0x9a, 0x22,
}

if !bytes.Equal(expectedCipherText, cipherText) {
t.Fail()
}

decrypted := make([]byte, len(plainText))

decrypter.CryptBlocks(decrypted, cipherText[:40])
decrypter.CryptBlocks(decrypted[40:], cipherText[40:])

if len(decrypted) != len(plainText) {
t.Fail()
}

if !bytes.Equal(plainText, decrypted) {
t.Errorf("decryption incorrect\nexp %v, got %v\n", plainText, decrypted)
}
}

func BenchmarkEncrypt(b *testing.B) {
tt := encryptDESTests[0]
c, err := cng.NewDESCipher(tt.key)
Expand Down Expand Up @@ -1642,7 +1697,7 @@ func BenchmarkDecrypt(b *testing.B) {
}
}

func BenchmarkTDESEncrypt(b *testing.B) {
func BenchmarkTripleDESEncrypt(b *testing.B) {
tt := encryptTripleDESTests[0]
c, err := cng.NewTripleDESCipher(tt.key)
if err != nil {
Expand All @@ -1656,7 +1711,7 @@ func BenchmarkTDESEncrypt(b *testing.B) {
}
}

func BenchmarkTDESDecrypt(b *testing.B) {
func BenchmarkTripleDESDecrypt(b *testing.B) {
tt := encryptTripleDESTests[0]
c, err := cng.NewTripleDESCipher(tt.key)
if err != nil {
Expand Down

0 comments on commit 9375423

Please sign in to comment.