diff --git a/raylib/rres.go b/raylib/rres.go index 73992ff..dffb904 100644 --- a/raylib/rres.go +++ b/raylib/rres.go @@ -16,6 +16,8 @@ import ( "github.com/pierrec/lz4" "github.com/rootlch/encrypt" "github.com/ulikunitz/xz" + "golang.org/x/crypto/blowfish" + "golang.org/x/crypto/xtea" "github.com/gen2brain/raylib-go/rres" ) @@ -129,6 +131,18 @@ func LoadResource(reader io.ReadSeeker, rresID int, key []byte) (data rres.Data) TraceLog(LogWarning, "[ID %d] %v", infoHeader.ID, err) } data.Data = b + case rres.CryptoBlowfish: + b, err := decryptBlowfish(key, data.Data) + if err != nil { + TraceLog(LogWarning, "[ID %d] %v", infoHeader.ID, err) + } + data.Data = b + case rres.CryptoXTEA: + b, err := decryptXTEA(key, data.Data) + if err != nil { + TraceLog(LogWarning, "[ID %d] %v", infoHeader.ID, err) + } + data.Data = b } if data.Data != nil { @@ -208,3 +222,53 @@ func decrypt3DES(key, text []byte) ([]byte, error) { return unpadMsg, nil } + +// decryptBlowfish +func decryptBlowfish(key, text []byte) ([]byte, error) { + block, err := blowfish.NewCipher(key) + if err != nil { + return nil, err + } + + if (len(text) % blowfish.BlockSize) != 0 { + return nil, fmt.Errorf("blocksize must be multiple of decoded message length") + } + + iv := text[:blowfish.BlockSize] + msg := text[blowfish.BlockSize:] + + cbc := cipher.NewCBCDecrypter(block, iv) + cbc.CryptBlocks(msg, msg) + + unpadMsg, err := unpad(msg) + if err != nil { + return nil, err + } + + return unpadMsg, nil +} + +// decryptXTEA +func decryptXTEA(key, text []byte) ([]byte, error) { + block, err := xtea.NewCipher(key) + if err != nil { + return nil, err + } + + if (len(text) % xtea.BlockSize) != 0 { + return nil, fmt.Errorf("blocksize must be multiple of decoded message length") + } + + iv := text[:xtea.BlockSize] + msg := text[xtea.BlockSize:] + + cbc := cipher.NewCBCDecrypter(block, iv) + cbc.CryptBlocks(msg, msg) + + unpadMsg, err := unpad(msg) + if err != nil { + return nil, err + } + + return unpadMsg, nil +} diff --git a/rres/cmd/rrem/README.md b/rres/cmd/rrem/README.md index 73018e4..700bd55 100644 --- a/rres/cmd/rrem/README.md +++ b/rres/cmd/rrem/README.md @@ -11,9 +11,9 @@ Usage of ./rrem: -bin Generate Go bindata (.go file) -comp int - Compression type, 0=None, 1=Deflate, 2=LZ4, 5=LZMA2 (XZ), 6=BZIP2 (default 5) + Compression type, 0=NONE, 1=DEFLATE, 2=LZ4, 5=LZMA2 (XZ), 6=BZIP2 (default 5) -enc int - Encryption type, 0=None, 1=XOR, 2=AES, 3=3DES + Encryption type, 0=NONE, 1=XOR, 2=AES, 3=3DES, 4=Blowfish, 5=XTEA -header Generate C header (.h file) -key string diff --git a/rres/cmd/rrem/main.go b/rres/cmd/rrem/main.go index 99997e1..8de907d 100644 --- a/rres/cmd/rrem/main.go +++ b/rres/cmd/rrem/main.go @@ -37,6 +37,8 @@ import ( "github.com/pierrec/lz4" "github.com/rootlch/encrypt" "github.com/ulikunitz/xz" + "golang.org/x/crypto/blowfish" + "golang.org/x/crypto/xtea" "github.com/gen2brain/raylib-go/rres" ) @@ -47,8 +49,8 @@ func init() { func main() { base := flag.String("base", "data", "Resources file basename") - comp := flag.Int("comp", rres.CompLZMA2, "Compression type, 0=None, 1=Deflate, 2=LZ4, 5=LZMA2 (XZ), 6=BZIP2") - enc := flag.Int("enc", rres.CryptoNone, "Encryption type, 0=None, 1=XOR, 2=AES, 3=3DES") + comp := flag.Int("comp", rres.CompLZMA2, "Compression type, 0=NONE, 1=DEFLATE, 2=LZ4, 5=LZMA2 (XZ), 6=BZIP2") + enc := flag.Int("enc", rres.CryptoNone, "Encryption type, 0=NONE, 1=XOR, 2=AES, 3=3DES, 4=Blowfish, 5=XTEA") key := flag.String("key", "", "Encryption key") header := flag.Bool("header", false, "Generate C header (.h file)") bin := flag.Bool("bin", false, "Generate Go bindata (.go file)") @@ -75,6 +77,8 @@ func main() { case rres.CryptoXOR: case rres.CryptoAES: case rres.Crypto3DES: + case rres.CryptoBlowfish: + case rres.CryptoXTEA: default: fmt.Printf("encryption type %d not implemented\n", *enc) os.Exit(1) @@ -258,6 +262,20 @@ func main() { fmt.Printf("%v\n", err) } + data = b + case rres.CryptoBlowfish: + b, err := encryptBlowfish([]byte(*key), data) + if err != nil { + fmt.Printf("%v\n", err) + } + + data = b + case rres.CryptoXTEA: + b, err := encryptXTEA([]byte(*key), data) + if err != nil { + fmt.Printf("%v\n", err) + } + data = b } @@ -434,7 +452,7 @@ func encryptAES(key, text []byte) ([]byte, error) { // encrypt3DES func encrypt3DES(key, text []byte) ([]byte, error) { - block, err := des.NewTripleDESCipher([]byte(key)) + block, err := des.NewTripleDESCipher(key) if err != nil { return nil, err } @@ -451,3 +469,43 @@ func encrypt3DES(key, text []byte) ([]byte, error) { return ciphertext, nil } + +// encryptBlowfish +func encryptBlowfish(key, text []byte) ([]byte, error) { + block, err := blowfish.NewCipher(key) + if err != nil { + return nil, err + } + + msg := pad(text, blowfish.BlockSize) + ciphertext := make([]byte, blowfish.BlockSize+len(msg)) + iv := ciphertext[:blowfish.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, err + } + + cbc := cipher.NewCBCEncrypter(block, iv) + cbc.CryptBlocks(ciphertext[blowfish.BlockSize:], msg) + + return ciphertext, nil +} + +// encryptXTEA +func encryptXTEA(key, text []byte) ([]byte, error) { + block, err := xtea.NewCipher(key) + if err != nil { + return nil, err + } + + msg := pad(text, xtea.BlockSize) + ciphertext := make([]byte, xtea.BlockSize+len(msg)) + iv := ciphertext[:xtea.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, err + } + + cbc := cipher.NewCBCEncrypter(block, iv) + cbc.CryptBlocks(ciphertext[xtea.BlockSize:], msg) + + return ciphertext, nil +}