From 434410d1d6dca790d6abb7614835c6567a90a590 Mon Sep 17 00:00:00 2001 From: Evan Su <48808396+HACKERALERT@users.noreply.github.com> Date: Thu, 25 Apr 2024 10:26:59 -0400 Subject: [PATCH] Reorganize CLI v1 --- cli/{ => v1}/picocrypt/README.md | 0 cli/{ => v1}/picocrypt/go.mod | 0 cli/{ => v1}/picocrypt/go.sum | 0 cli/{ => v1}/picocrypt/main.go | 458 +++++++++++++++---------------- 4 files changed, 229 insertions(+), 229 deletions(-) rename cli/{ => v1}/picocrypt/README.md (100%) rename cli/{ => v1}/picocrypt/go.mod (100%) rename cli/{ => v1}/picocrypt/go.sum (100%) rename cli/{ => v1}/picocrypt/main.go (96%) diff --git a/cli/picocrypt/README.md b/cli/v1/picocrypt/README.md similarity index 100% rename from cli/picocrypt/README.md rename to cli/v1/picocrypt/README.md diff --git a/cli/picocrypt/go.mod b/cli/v1/picocrypt/go.mod similarity index 100% rename from cli/picocrypt/go.mod rename to cli/v1/picocrypt/go.mod diff --git a/cli/picocrypt/go.sum b/cli/v1/picocrypt/go.sum similarity index 100% rename from cli/picocrypt/go.sum rename to cli/v1/picocrypt/go.sum diff --git a/cli/picocrypt/main.go b/cli/v1/picocrypt/main.go similarity index 96% rename from cli/picocrypt/main.go rename to cli/v1/picocrypt/main.go index 2b7eaf56..866412a6 100644 --- a/cli/picocrypt/main.go +++ b/cli/v1/picocrypt/main.go @@ -1,229 +1,229 @@ -package main - -import ( - "bytes" - "crypto/rand" - "flag" - "fmt" - "os" - "strconv" - "strings" - - "github.com/HACKERALERT/crypto/argon2" - "github.com/HACKERALERT/crypto/blake2b" - "github.com/HACKERALERT/crypto/chacha20" - "github.com/HACKERALERT/crypto/hkdf" - "github.com/HACKERALERT/crypto/sha3" - "github.com/HACKERALERT/infectious" -) - -var MiB = 1 << 20 -var GiB = 1 << 30 -var rs5, _ = infectious.NewFEC(5, 15) -var rs16, _ = infectious.NewFEC(16, 48) -var rs24, _ = infectious.NewFEC(24, 72) -var rs32, _ = infectious.NewFEC(32, 96) -var rs64, _ = infectious.NewFEC(64, 192) - -func work(filename string, password string) int { - var salt []byte - var hkdfSalt []byte - var nonce []byte - var keyHash []byte - var keyHashRef []byte - var authTag []byte - - fin, err := os.Open(filename) - if err != nil { - fmt.Println("Couldn't open input file.") - return 1 - } - defer fin.Close() - - var fout *os.File - if strings.HasSuffix(filename, ".pcv") { - fout, err = os.Create(strings.TrimSuffix(filename, ".pcv")) - } else { - fout, err = os.Create(filename + ".pcv") - } - if err != nil { - fmt.Println("Couldn't create output file.") - return 1 - } - defer fout.Close() - - if !strings.HasSuffix(filename, ".pcv") { - salt = make([]byte, 16) - hkdfSalt = make([]byte, 32) - nonce = make([]byte, 24) - rand.Read(salt) - rand.Read(hkdfSalt) - rand.Read(nonce) - fout.Write(rsEncode(rs5, []byte("v1.33"))) - fout.Write(rsEncode(rs5, []byte("00000"))) - fout.Write(rsEncode(rs5, make([]byte, 5))) - fout.Write(rsEncode(rs16, salt)) - fout.Write(rsEncode(rs32, hkdfSalt)) - fout.Write(rsEncode(rs16, make([]byte, 16))) - fout.Write(rsEncode(rs24, nonce)) - fout.Write(make([]byte, 480)) - } else { - errs := make([]error, 7) - comments := make([]byte, 30) - fin.Read(comments) - comments, errs[0] = rsDecode(rs5, comments[15:]) - length, _ := strconv.Atoi(string(comments)) - fin.Read(make([]byte, length*3)) - flags := make([]byte, 15) - fin.Read(flags) - flags, errs[1] = rsDecode(rs5, flags) - salt = make([]byte, 48) - fin.Read(salt) - salt, errs[2] = rsDecode(rs16, salt) - hkdfSalt = make([]byte, 96) - fin.Read(hkdfSalt) - hkdfSalt, errs[3] = rsDecode(rs32, hkdfSalt) - fin.Read(make([]byte, 48)) - nonce = make([]byte, 72) - fin.Read(nonce) - nonce, errs[4] = rsDecode(rs24, nonce) - keyHashRef = make([]byte, 192) - fin.Read(keyHashRef) - keyHashRef, errs[5] = rsDecode(rs64, keyHashRef) - fin.Read(make([]byte, 96)) - authTag = make([]byte, 192) - fin.Read(authTag) - authTag, errs[6] = rsDecode(rs64, authTag) - for _, err := range errs { - if err != nil { - fmt.Println("The header is corrupted.") - return 1 - } - } - if flags[0]+flags[1]+flags[3] > 0 { - fmt.Println("Unsupported volume.") - return 1 - } - } - - key := argon2.IDKey([]byte(password), salt, 4, 1<<20, 4, 32) - tmp := sha3.New512() - tmp.Write(key) - keyHash = tmp.Sum(nil) - if strings.HasSuffix(filename, ".pcv") && !bytes.Equal(keyHash, keyHashRef) { - fmt.Println("Incorrect password.") - return 1 - } - - counter := 0 - chacha, _ := chacha20.NewUnauthenticatedCipher(key, nonce) - subkey := make([]byte, 32) - hkdf := hkdf.New(sha3.New256, key, hkdfSalt, nil) - hkdf.Read(subkey) - mac, _ := blake2b.New512(subkey) - hkdf.Read(make([]byte, 32)) - - for { - src := make([]byte, MiB) - size, err := fin.Read(src) - if err != nil { - break - } - src = src[:size] - dst := make([]byte, len(src)) - - if !strings.HasSuffix(filename, ".pcv") { - chacha.XORKeyStream(dst, src) - mac.Write(dst) - } else { - mac.Write(src) - chacha.XORKeyStream(dst, src) - } - fout.Write(dst) - - counter += MiB - if counter >= 60*GiB { - nonce = make([]byte, 24) - hkdf.Read(nonce) - chacha, _ = chacha20.NewUnauthenticatedCipher(key, nonce) - hkdf.Read(make([]byte, 16)) - counter = 0 - } - } - - if !strings.HasSuffix(filename, ".pcv") { - fout.Seek(309, 0) - fout.Write(rsEncode(rs64, keyHash)) - fout.Write(rsEncode(rs32, make([]byte, 32))) - fout.Write(rsEncode(rs64, mac.Sum(nil))) - } else { - if !bytes.Equal(mac.Sum(nil), authTag) { - fmt.Println("The file has been modified.") - return 1 - } - } - - fmt.Println("Operation successful.") - return 0 -} - -func rsEncode(rs *infectious.FEC, data []byte) []byte { - res := make([]byte, rs.Total()) - rs.Encode(data, func(s infectious.Share) { - res[s.Number] = s.Data[0] - }) - return res -} - -func rsDecode(rs *infectious.FEC, data []byte) ([]byte, error) { - tmp := make([]infectious.Share, rs.Total()) - for i := 0; i < rs.Total(); i++ { - tmp[i].Number = i - tmp[i].Data = []byte{data[i]} - } - res, err := rs.Decode(nil, tmp) - if err != nil { - return data[:rs.Total()/3], err - } - return res, nil -} - -func main() { - flag.Usage = func() { fmt.Println("Usage: picocrypt -p password ") } - password := flag.String("p", "", "") - flag.Parse() - filename := flag.Arg(0) - - if filename == "" || *password == "" || flag.Arg(1) != "" { - flag.Usage() - os.Exit(1) - } - if _, err := os.Stat(filename); err != nil { - fmt.Println("Input file not found.") - os.Exit(1) - } - if stat, _ := os.Stat(filename); stat.IsDir() { - fmt.Println("Directories are not supported.") - os.Exit(1) - } - if !strings.HasSuffix(filename, ".pcv") { - if _, err := os.Stat(filename + ".pcv"); err == nil { - fmt.Println("Output already exists.") - os.Exit(1) - } - } else { - if _, err := os.Stat(strings.TrimSuffix(filename, ".pcv")); err == nil { - fmt.Println("Output already exists.") - os.Exit(1) - } - } - - if work(filename, *password) != 0 { - if !strings.HasSuffix(filename, ".pcv") { - os.Remove(filename + ".pcv") - } else { - os.Remove(strings.TrimSuffix(filename, ".pcv")) - } - os.Exit(1) - } -} +package main + +import ( + "bytes" + "crypto/rand" + "flag" + "fmt" + "os" + "strconv" + "strings" + + "github.com/HACKERALERT/crypto/argon2" + "github.com/HACKERALERT/crypto/blake2b" + "github.com/HACKERALERT/crypto/chacha20" + "github.com/HACKERALERT/crypto/hkdf" + "github.com/HACKERALERT/crypto/sha3" + "github.com/HACKERALERT/infectious" +) + +var MiB = 1 << 20 +var GiB = 1 << 30 +var rs5, _ = infectious.NewFEC(5, 15) +var rs16, _ = infectious.NewFEC(16, 48) +var rs24, _ = infectious.NewFEC(24, 72) +var rs32, _ = infectious.NewFEC(32, 96) +var rs64, _ = infectious.NewFEC(64, 192) + +func work(filename string, password string) int { + var salt []byte + var hkdfSalt []byte + var nonce []byte + var keyHash []byte + var keyHashRef []byte + var authTag []byte + + fin, err := os.Open(filename) + if err != nil { + fmt.Println("Couldn't open input file.") + return 1 + } + defer fin.Close() + + var fout *os.File + if strings.HasSuffix(filename, ".pcv") { + fout, err = os.Create(strings.TrimSuffix(filename, ".pcv")) + } else { + fout, err = os.Create(filename + ".pcv") + } + if err != nil { + fmt.Println("Couldn't create output file.") + return 1 + } + defer fout.Close() + + if !strings.HasSuffix(filename, ".pcv") { + salt = make([]byte, 16) + hkdfSalt = make([]byte, 32) + nonce = make([]byte, 24) + rand.Read(salt) + rand.Read(hkdfSalt) + rand.Read(nonce) + fout.Write(rsEncode(rs5, []byte("v1.33"))) + fout.Write(rsEncode(rs5, []byte("00000"))) + fout.Write(rsEncode(rs5, make([]byte, 5))) + fout.Write(rsEncode(rs16, salt)) + fout.Write(rsEncode(rs32, hkdfSalt)) + fout.Write(rsEncode(rs16, make([]byte, 16))) + fout.Write(rsEncode(rs24, nonce)) + fout.Write(make([]byte, 480)) + } else { + errs := make([]error, 7) + comments := make([]byte, 30) + fin.Read(comments) + comments, errs[0] = rsDecode(rs5, comments[15:]) + length, _ := strconv.Atoi(string(comments)) + fin.Read(make([]byte, length*3)) + flags := make([]byte, 15) + fin.Read(flags) + flags, errs[1] = rsDecode(rs5, flags) + salt = make([]byte, 48) + fin.Read(salt) + salt, errs[2] = rsDecode(rs16, salt) + hkdfSalt = make([]byte, 96) + fin.Read(hkdfSalt) + hkdfSalt, errs[3] = rsDecode(rs32, hkdfSalt) + fin.Read(make([]byte, 48)) + nonce = make([]byte, 72) + fin.Read(nonce) + nonce, errs[4] = rsDecode(rs24, nonce) + keyHashRef = make([]byte, 192) + fin.Read(keyHashRef) + keyHashRef, errs[5] = rsDecode(rs64, keyHashRef) + fin.Read(make([]byte, 96)) + authTag = make([]byte, 192) + fin.Read(authTag) + authTag, errs[6] = rsDecode(rs64, authTag) + for _, err := range errs { + if err != nil { + fmt.Println("The header is corrupted.") + return 1 + } + } + if flags[0]+flags[1]+flags[3] > 0 { + fmt.Println("Unsupported volume.") + return 1 + } + } + + key := argon2.IDKey([]byte(password), salt, 4, 1<<20, 4, 32) + tmp := sha3.New512() + tmp.Write(key) + keyHash = tmp.Sum(nil) + if strings.HasSuffix(filename, ".pcv") && !bytes.Equal(keyHash, keyHashRef) { + fmt.Println("Incorrect password.") + return 1 + } + + counter := 0 + chacha, _ := chacha20.NewUnauthenticatedCipher(key, nonce) + subkey := make([]byte, 32) + hkdf := hkdf.New(sha3.New256, key, hkdfSalt, nil) + hkdf.Read(subkey) + mac, _ := blake2b.New512(subkey) + hkdf.Read(make([]byte, 32)) + + for { + src := make([]byte, MiB) + size, err := fin.Read(src) + if err != nil { + break + } + src = src[:size] + dst := make([]byte, len(src)) + + if !strings.HasSuffix(filename, ".pcv") { + chacha.XORKeyStream(dst, src) + mac.Write(dst) + } else { + mac.Write(src) + chacha.XORKeyStream(dst, src) + } + fout.Write(dst) + + counter += MiB + if counter >= 60*GiB { + nonce = make([]byte, 24) + hkdf.Read(nonce) + chacha, _ = chacha20.NewUnauthenticatedCipher(key, nonce) + hkdf.Read(make([]byte, 16)) + counter = 0 + } + } + + if !strings.HasSuffix(filename, ".pcv") { + fout.Seek(309, 0) + fout.Write(rsEncode(rs64, keyHash)) + fout.Write(rsEncode(rs32, make([]byte, 32))) + fout.Write(rsEncode(rs64, mac.Sum(nil))) + } else { + if !bytes.Equal(mac.Sum(nil), authTag) { + fmt.Println("The file has been modified.") + return 1 + } + } + + fmt.Println("Operation successful.") + return 0 +} + +func rsEncode(rs *infectious.FEC, data []byte) []byte { + res := make([]byte, rs.Total()) + rs.Encode(data, func(s infectious.Share) { + res[s.Number] = s.Data[0] + }) + return res +} + +func rsDecode(rs *infectious.FEC, data []byte) ([]byte, error) { + tmp := make([]infectious.Share, rs.Total()) + for i := 0; i < rs.Total(); i++ { + tmp[i].Number = i + tmp[i].Data = []byte{data[i]} + } + res, err := rs.Decode(nil, tmp) + if err != nil { + return data[:rs.Total()/3], err + } + return res, nil +} + +func main() { + flag.Usage = func() { fmt.Println("Usage: picocrypt -p password ") } + password := flag.String("p", "", "") + flag.Parse() + filename := flag.Arg(0) + + if filename == "" || *password == "" || flag.Arg(1) != "" { + flag.Usage() + os.Exit(1) + } + if _, err := os.Stat(filename); err != nil { + fmt.Println("Input file not found.") + os.Exit(1) + } + if stat, _ := os.Stat(filename); stat.IsDir() { + fmt.Println("Directories are not supported.") + os.Exit(1) + } + if !strings.HasSuffix(filename, ".pcv") { + if _, err := os.Stat(filename + ".pcv"); err == nil { + fmt.Println("Output already exists.") + os.Exit(1) + } + } else { + if _, err := os.Stat(strings.TrimSuffix(filename, ".pcv")); err == nil { + fmt.Println("Output already exists.") + os.Exit(1) + } + } + + if work(filename, *password) != 0 { + if !strings.HasSuffix(filename, ".pcv") { + os.Remove(filename + ".pcv") + } else { + os.Remove(strings.TrimSuffix(filename, ".pcv")) + } + os.Exit(1) + } +}