mirror of
https://github.com/Picocrypt/Picocrypt.git
synced 2025-05-12 05:48:30 +02:00
handle more errors
This commit is contained in:
parent
b0c2943bb0
commit
0cc109bc6b
1 changed files with 167 additions and 52 deletions
219
src/Picocrypt.go
219
src/Picocrypt.go
|
@ -1978,17 +1978,27 @@ func work() {
|
|||
var mac hash.Hash
|
||||
subkey := make([]byte, 32)
|
||||
hkdf := hkdf.New(sha3.New256, key, hkdfSalt, nil)
|
||||
hkdf.Read(subkey)
|
||||
if n, err := hkdf.Read(subkey); err != nil || n != 32 {
|
||||
panic(errors.New("fatal hkdf.Read error"))
|
||||
}
|
||||
if paranoid {
|
||||
mac = hmac.New(sha3.New512, subkey) // HMAC-SHA3
|
||||
} else {
|
||||
mac, _ = blake2b.New512(subkey) // Keyed BLAKE2b
|
||||
mac, err = blake2b.New512(subkey) // Keyed BLAKE2b
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate another subkey for use as Serpent's key
|
||||
serpentKey := make([]byte, 32)
|
||||
hkdf.Read(serpentKey)
|
||||
s, _ := serpent.NewCipher(serpentKey)
|
||||
if n, err := hkdf.Read(serpentKey); err != nil || n != 32 {
|
||||
panic(errors.New("fatal hkdf.Read error"))
|
||||
}
|
||||
s, err := serpent.NewCipher(serpentKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
serpent := cipher.NewCTR(s, serpentIV)
|
||||
|
||||
// Start the main encryption process
|
||||
|
@ -2036,7 +2046,9 @@ func work() {
|
|||
}
|
||||
|
||||
chacha.XORKeyStream(dst, src)
|
||||
mac.Write(dst)
|
||||
if _, err := mac.Write(dst); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if reedsolo {
|
||||
copy(src, dst)
|
||||
|
@ -2090,7 +2102,7 @@ func work() {
|
|||
} else {
|
||||
// Decode the full chunks
|
||||
chunks := len(dst)/136 - 1
|
||||
for i := 0; i < chunks; i++ {
|
||||
for i := range chunks {
|
||||
tmp, err := rsDecode(rs128, dst[i*136:(i+1)*136])
|
||||
if err != nil {
|
||||
if keep {
|
||||
|
@ -2125,7 +2137,9 @@ func work() {
|
|||
dst = make([]byte, len(src))
|
||||
}
|
||||
|
||||
mac.Write(src)
|
||||
if _, err := mac.Write(src); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
chacha.XORKeyStream(dst, src)
|
||||
|
||||
if paranoid {
|
||||
|
@ -2167,12 +2181,19 @@ func work() {
|
|||
if counter >= 60*GiB {
|
||||
// ChaCha20
|
||||
nonce = make([]byte, 24)
|
||||
hkdf.Read(nonce)
|
||||
chacha, _ = chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||
if n, err := hkdf.Read(nonce); err != nil || n != 24 {
|
||||
panic(errors.New("fatal hkdf.Read error"))
|
||||
}
|
||||
chacha, err = chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Serpent
|
||||
serpentIV = make([]byte, 16)
|
||||
hkdf.Read(serpentIV)
|
||||
if n, err := hkdf.Read(serpentIV); err != nil || n != 16 {
|
||||
panic(errors.New("fatal hkdf.Read error"))
|
||||
}
|
||||
serpent = cipher.NewCTR(s, serpentIV)
|
||||
|
||||
// Reset counter to 0
|
||||
|
@ -2189,10 +2210,18 @@ func work() {
|
|||
giu.Update()
|
||||
|
||||
// Seek back to header and write important values
|
||||
fout.Seek(int64(309+len(comments)*3), 0)
|
||||
fout.Write(rsEncode(rs64, keyHash))
|
||||
fout.Write(rsEncode(rs32, keyfileHash))
|
||||
fout.Write(rsEncode(rs64, mac.Sum(nil)))
|
||||
if _, err := fout.Seek(int64(309+len(comments)*3), 0); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if _, err := fout.Write(rsEncode(rs64, keyHash)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if _, err := fout.Write(rsEncode(rs32, keyfileHash)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if _, err := fout.Write(rsEncode(rs64, mac.Sum(nil))); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
popupStatus = "Comparing values..."
|
||||
giu.Update()
|
||||
|
@ -2217,10 +2246,16 @@ func work() {
|
|||
}
|
||||
}
|
||||
|
||||
fin.Close()
|
||||
fout.Close()
|
||||
if err := fin.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := fout.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
os.Rename(outputFile+".incomplete", outputFile)
|
||||
if err := os.Rename(outputFile+".incomplete", outputFile); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Add plausible deniability
|
||||
if mode == "encrypt" && deniability {
|
||||
|
@ -2229,29 +2264,51 @@ func work() {
|
|||
giu.Update()
|
||||
|
||||
// Get size of volume for showing progress
|
||||
stat, _ := os.Stat(outputFile)
|
||||
stat, err := os.Stat(outputFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
total := stat.Size()
|
||||
|
||||
// Rename the output volume to free up the filename
|
||||
os.Rename(outputFile, outputFile+".tmp")
|
||||
fin, _ := os.Open(outputFile + ".tmp")
|
||||
fout, _ := os.Create(outputFile + ".incomplete")
|
||||
fin, err := os.Open(outputFile + ".tmp")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fout, err := os.Create(outputFile + ".incomplete")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Use a random Argon2 salt and XChaCha20 nonce
|
||||
salt := make([]byte, 16)
|
||||
nonce := make([]byte, 24)
|
||||
if _, err := rand.Read(salt); err != nil {
|
||||
if n, err := rand.Read(salt); err != nil || n != 16 {
|
||||
panic(errors.New("fatal crypto/rand error"))
|
||||
}
|
||||
if n, err := rand.Read(nonce); err != nil || n != 24 {
|
||||
panic(errors.New("fatal crypto/rand error"))
|
||||
}
|
||||
if bytes.Equal(salt, make([]byte, 16)) || bytes.Equal(nonce, make([]byte, 24)) {
|
||||
panic(errors.New("fatal crypto/rand error"))
|
||||
}
|
||||
if _, err := fout.Write(salt); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if _, err := rand.Read(nonce); err != nil {
|
||||
if _, err := fout.Write(nonce); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fout.Write(salt)
|
||||
fout.Write(nonce)
|
||||
|
||||
// Generate key and XChaCha20
|
||||
key := argon2.IDKey([]byte(password), salt, 4, 1<<20, 4, 32)
|
||||
chacha, _ := chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||
if bytes.Equal(key, make([]byte, 32)) {
|
||||
panic(errors.New("fatal crypto/argon2 error"))
|
||||
}
|
||||
chacha, err := chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Encrypt the entire volume
|
||||
done, counter := 0, 0
|
||||
|
@ -2264,7 +2321,9 @@ func work() {
|
|||
src = src[:size]
|
||||
dst := make([]byte, len(src))
|
||||
chacha.XORKeyStream(dst, src)
|
||||
fout.Write(dst)
|
||||
if _, err := fout.Write(dst); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Update stats
|
||||
done += size
|
||||
|
@ -2275,17 +2334,30 @@ func work() {
|
|||
// Change nonce after 60 GiB to prevent overflow
|
||||
if counter >= 60*GiB {
|
||||
tmp := sha3.New256()
|
||||
tmp.Write(nonce)
|
||||
if _, err := tmp.Write(nonce); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nonce = tmp.Sum(nil)[:24]
|
||||
chacha, _ = chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||
chacha, err = chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
counter = 0
|
||||
}
|
||||
}
|
||||
|
||||
fin.Close()
|
||||
fout.Close()
|
||||
os.Remove(fin.Name())
|
||||
os.Rename(outputFile+".incomplete", outputFile)
|
||||
if err := fin.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := fout.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := os.Remove(fin.Name()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := os.Rename(outputFile+".incomplete", outputFile); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
canCancel = true
|
||||
giu.Update()
|
||||
}
|
||||
|
@ -2293,11 +2365,17 @@ func work() {
|
|||
// Split the file into chunks
|
||||
if split {
|
||||
var splitted []string
|
||||
stat, _ := os.Stat(outputFile)
|
||||
stat, err := os.Stat(outputFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
size := stat.Size()
|
||||
finishedFiles := 0
|
||||
finishedBytes := 0
|
||||
chunkSize, _ := strconv.Atoi(splitSize)
|
||||
chunkSize, err := strconv.Atoi(splitSize)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Calculate chunk size
|
||||
if splitSelected == 0 {
|
||||
|
@ -2318,17 +2396,25 @@ func work() {
|
|||
giu.Update()
|
||||
|
||||
// Open the volume for reading
|
||||
fin, _ := os.Open(outputFile)
|
||||
fin, err := os.Open(outputFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Delete existing chunks to prevent mixed chunks
|
||||
names, _ := filepath.Glob(outputFile + ".*")
|
||||
names, err := filepath.Glob(outputFile + ".*")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, i := range names {
|
||||
os.Remove(i)
|
||||
if err := os.Remove(i); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start the splitting process
|
||||
startTime := time.Now()
|
||||
for i := 0; i < chunks; i++ {
|
||||
for i := range chunks {
|
||||
// Make the chunk
|
||||
fout, _ := os.Create(fmt.Sprintf("%s.%d.incomplete", outputFile, i))
|
||||
done := 0
|
||||
|
@ -2382,7 +2468,9 @@ func work() {
|
|||
popupStatus = fmt.Sprintf("Splitting at %.2f MiB/s (ETA: %s)", speed, eta)
|
||||
giu.Update()
|
||||
}
|
||||
fout.Close()
|
||||
if err := fout.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Update stats
|
||||
finishedFiles++
|
||||
|
@ -2394,11 +2482,20 @@ func work() {
|
|||
giu.Update()
|
||||
}
|
||||
|
||||
fin.Close()
|
||||
os.Remove(outputFile)
|
||||
names, _ = filepath.Glob(outputFile + ".*.incomplete")
|
||||
if err := fin.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := os.Remove(outputFile); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
names, err = filepath.Glob(outputFile + ".*.incomplete")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, i := range names {
|
||||
os.Rename(i, strings.TrimSuffix(i, ".incomplete"))
|
||||
if err := os.Rename(i, strings.TrimSuffix(i, ".incomplete")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2409,9 +2506,13 @@ func work() {
|
|||
|
||||
// Delete temporary files used during encryption and decryption
|
||||
if recombine || len(allFiles) > 1 || len(onlyFolders) > 0 || compress {
|
||||
os.Remove(inputFile)
|
||||
if err := os.Remove(inputFile); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if deniability {
|
||||
os.Remove(strings.TrimSuffix(inputFile, ".tmp"))
|
||||
if err := os.Remove(strings.TrimSuffix(inputFile, ".tmp")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2428,26 +2529,38 @@ func work() {
|
|||
if err != nil {
|
||||
break
|
||||
}
|
||||
os.Remove(fmt.Sprintf("%s.%d", inputFileOld, i))
|
||||
if err := os.Remove(fmt.Sprintf("%s.%d", inputFileOld, i)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
os.Remove(inputFile)
|
||||
if err := os.Remove(inputFile); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if deniability {
|
||||
os.Remove(strings.TrimSuffix(inputFile, ".tmp"))
|
||||
if err := os.Remove(strings.TrimSuffix(inputFile, ".tmp")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, i := range onlyFiles {
|
||||
os.Remove(i)
|
||||
if err := os.Remove(i); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
for _, i := range onlyFolders {
|
||||
os.RemoveAll(i)
|
||||
if err := os.RemoveAll(i); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if mode == "decrypt" && deniability {
|
||||
os.Remove(inputFile)
|
||||
if err := os.Remove(inputFile); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if mode == "decrypt" && !kept && autoUnzip {
|
||||
|
@ -2462,7 +2575,9 @@ func work() {
|
|||
return
|
||||
}
|
||||
|
||||
os.Remove(outputFile)
|
||||
if err := os.Remove(outputFile); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// All done, reset the UI
|
||||
|
|
Loading…
Add table
Reference in a new issue