diff --git a/migration-guides/decrypt/bin/ente-decrypt-darwin-amd64 b/migration-guides/decrypt/bin/ente-decrypt-darwin-amd64 new file mode 100755 index 0000000000000000000000000000000000000000..10777f9c07ee6b24c9115e0bd7c5a9f1c44bf1d4 Binary files /dev/null and b/migration-guides/decrypt/bin/ente-decrypt-darwin-amd64 differ diff --git a/migration-guides/decrypt/bin/ente-decrypt-darwin-arm64 b/migration-guides/decrypt/bin/ente-decrypt-darwin-arm64 new file mode 100755 index 0000000000000000000000000000000000000000..7442335973cdc44426001d977fe589f049375a0c Binary files /dev/null and b/migration-guides/decrypt/bin/ente-decrypt-darwin-arm64 differ diff --git a/migration-guides/decrypt/bin/ente-decrypt-linux-386 b/migration-guides/decrypt/bin/ente-decrypt-linux-386 new file mode 100755 index 0000000000000000000000000000000000000000..9ec58483cad8a9ba3930de0b7f51de1d52f61c49 Binary files /dev/null and b/migration-guides/decrypt/bin/ente-decrypt-linux-386 differ diff --git a/migration-guides/decrypt/bin/ente-decrypt-linux-amd64 b/migration-guides/decrypt/bin/ente-decrypt-linux-amd64 new file mode 100755 index 0000000000000000000000000000000000000000..4ae82204846c8e3a49fd52aa57abdf87222c9f9f Binary files /dev/null and b/migration-guides/decrypt/bin/ente-decrypt-linux-amd64 differ diff --git a/migration-guides/decrypt/bin/ente-decrypt-linux-arm b/migration-guides/decrypt/bin/ente-decrypt-linux-arm new file mode 100755 index 0000000000000000000000000000000000000000..77f7f5803cc5e1c416ddd9233be2d9c96a5e9406 Binary files /dev/null and b/migration-guides/decrypt/bin/ente-decrypt-linux-arm differ diff --git a/migration-guides/decrypt/bin/ente-decrypt-linux-arm64 b/migration-guides/decrypt/bin/ente-decrypt-linux-arm64 new file mode 100755 index 0000000000000000000000000000000000000000..e0646e1b2a7c6b61f42e5b1ad8840e60d516059e Binary files /dev/null and b/migration-guides/decrypt/bin/ente-decrypt-linux-arm64 differ diff --git a/migration-guides/decrypt/bin/ente-decrypt-windows-386.exe b/migration-guides/decrypt/bin/ente-decrypt-windows-386.exe new file mode 100755 index 0000000000000000000000000000000000000000..6718b4ec68653441b2a64ace92da55db3bac3e10 Binary files /dev/null and b/migration-guides/decrypt/bin/ente-decrypt-windows-386.exe differ diff --git a/migration-guides/decrypt/bin/ente-decrypt-windows-amd64.exe b/migration-guides/decrypt/bin/ente-decrypt-windows-amd64.exe new file mode 100755 index 0000000000000000000000000000000000000000..587485eaab17ed51f1644f4304d28c1198dedead Binary files /dev/null and b/migration-guides/decrypt/bin/ente-decrypt-windows-amd64.exe differ diff --git a/migration-guides/decrypt/crypt.go b/migration-guides/decrypt/crypt.go index 3a64b43bba1e244d43a7539e55922856261973cf..4d546c9925631dc4b7573a525d8550f3bec84713 100644 --- a/migration-guides/decrypt/crypt.go +++ b/migration-guides/decrypt/crypt.go @@ -1,13 +1,10 @@ package main import ( - "bytes" "encoding/base64" + "errors" "fmt" - "io" - "log" - "github.com/jamesruan/sodium" "golang.org/x/crypto/argon2" ) @@ -48,23 +45,38 @@ func deriveArgonKey(password, salt string, memLimit, opsLimit int) ([]byte, erro // Returns: // - A byte slice representing the decrypted data. // - An error object, which is nil if no error occurs. -func decryptChaCha20poly1305(data []byte, key []byte, nonce []byte) ([]byte, error) { - reader := bytes.NewReader(data) - header := sodium.SecretStreamXCPHeader{Bytes: nonce} - decoder, err := sodium.MakeSecretStreamXCPDecoder( - sodium.SecretStreamXCPKey{Bytes: key}, - reader, - header) +// func decryptChaCha20poly13052(data []byte, key []byte, nonce []byte) ([]byte, error) { +// reader := bytes.NewReader(data) +// header := sodium.SecretStreamXCPHeader{Bytes: nonce} +// decoder, err := sodium.MakeSecretStreamXCPDecoder( +// sodium.SecretStreamXCPKey{Bytes: key}, +// reader, +// header) +// if err != nil { +// log.Println("Failed to make secret stream decoder", err) +// return nil, err +// } +// // Buffer to store the decrypted data +// decryptedData := make([]byte, len(data)) +// n, err := decoder.Read(decryptedData) +// if err != nil && err != io.EOF { +// log.Println("Failed to read from decoder", err) +// return nil, err +// } +// return decryptedData[:n], nil +// } + +func decryptChaCha20poly13052(data []byte, key []byte, nonce []byte) ([]byte, error) { + decryptor, err := NewDecryptor(key, nonce) if err != nil { - log.Println("Failed to make secret stream decoder", err) return nil, err } - // Buffer to store the decrypted data - decryptedData := make([]byte, len(data)) - n, err := decoder.Read(decryptedData) - if err != nil && err != io.EOF { - log.Println("Failed to read from decoder", err) + decoded, tag, err := decryptor.Pull(data) + if tag != TagFinal { + return nil, errors.New("invalid tag") + } + if err != nil { return nil, err } - return decryptedData[:n], nil + return decoded, nil } diff --git a/migration-guides/decrypt/crypt_test.go b/migration-guides/decrypt/crypt_test.go index bf933a33e3266c79b40a75926923e00f9e553e96..5907fdb89d33858fc2206b9304ff25ed377059bb 100644 --- a/migration-guides/decrypt/crypt_test.go +++ b/migration-guides/decrypt/crypt_test.go @@ -43,7 +43,7 @@ func TestDecryptChaCha20poly1305(t *testing.T) { t.Fatalf("Failed to decode cipher nonce: %v", err) } - decryptedText, err := decryptChaCha20poly1305(decodedCipherText, derivedKey, decodedCipherNonce) + decryptedText, err := decryptChaCha20poly13052(decodedCipherText, derivedKey, decodedCipherNonce) if err != nil { t.Fatalf("Failed to decrypt: %v", err) } diff --git a/migration-guides/decrypt/decrypt b/migration-guides/decrypt/decrypt deleted file mode 100755 index 3307438c0c9596581acfd190317732fb58833715..0000000000000000000000000000000000000000 Binary files a/migration-guides/decrypt/decrypt and /dev/null differ diff --git a/migration-guides/decrypt/decrypt.go b/migration-guides/decrypt/decrypt.go index 8ffefd4e69e889886d80878303328cce7a6d2440..8604b1ce968c3de5a2a4a23b404576ef07f7c2d5 100644 --- a/migration-guides/decrypt/decrypt.go +++ b/migration-guides/decrypt/decrypt.go @@ -90,7 +90,7 @@ func main() { return } - decryptedData, err := decryptChaCha20poly1305(encryptedData, key, nonce) + decryptedData, err := decryptChaCha20poly13052(encryptedData, key, nonce) if err != nil { fmt.Println("Error decrypting data:", err) return diff --git a/migration-guides/decrypt/go.mod b/migration-guides/decrypt/go.mod index 7be92d08c4c8dd28bd8c2699a398ab275f492c07..4c562fd7b1fcc5541dc01c97f298f194e541e6c3 100644 --- a/migration-guides/decrypt/go.mod +++ b/migration-guides/decrypt/go.mod @@ -2,9 +2,6 @@ module decrypt go 1.20 -require ( - github.com/jamesruan/sodium v1.0.14 - golang.org/x/crypto v0.11.0 -) +require golang.org/x/crypto v0.11.0 require golang.org/x/sys v0.10.0 // indirect diff --git a/migration-guides/decrypt/go.sum b/migration-guides/decrypt/go.sum index 3b18a3ccab959154def6efc1f2237c53fa38a81a..7f8014749c2bb938e3fc00468de78ef41a590751 100644 --- a/migration-guides/decrypt/go.sum +++ b/migration-guides/decrypt/go.sum @@ -1,5 +1,3 @@ -github.com/jamesruan/sodium v1.0.14 h1:JfOHobip/lUWouxHV3PwYwu3gsLewPrDrZXO3HuBzUU= -github.com/jamesruan/sodium v1.0.14/go.mod h1:GK2+LACf7kuVQ9k7Irk0MB2B65j5rVqkz+9ylGIggZk= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= diff --git a/migration-guides/decrypt/release.sh b/migration-guides/decrypt/release.sh new file mode 100644 index 0000000000000000000000000000000000000000..9a2e9fdddd3aa930a3023db43d62444be54fa54c --- /dev/null +++ b/migration-guides/decrypt/release.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# Create a "bin" directory if it doesn't exist +mkdir -p bin + +# List of target operating systems +OS_TARGETS=("windows" "linux" "darwin") + +# Corresponding architectures for each OS +ARCH_TARGETS=("386 amd64" "386 amd64 arm arm64" "amd64 arm64") + +# Loop through each OS target +for index in "${!OS_TARGETS[@]}" +do + OS=${OS_TARGETS[$index]} + for ARCH in ${ARCH_TARGETS[$index]} + do + # Set the GOOS environment variable for the current target OS + export GOOS="$OS" + export GOARCH="$ARCH" + + # Set the output binary name to "ente-decrypt" for the current OS and architecture + BINARY_NAME="ente-decrypt-$OS-$ARCH" + + # Add .exe extension for Windows + if [ "$OS" == "windows" ]; then + BINARY_NAME="ente-decrypt-$OS-$ARCH.exe" + fi + + # Build the binary and place it in the "bin" directory + go build -o "bin/$BINARY_NAME" decrypt.go crypt.go stream.go + + # Print a message indicating the build is complete for the current OS and architecture + echo "Built for $OS ($ARCH) as bin/$BINARY_NAME" + done +done + +# Clean up any environment variables +unset GOOS +unset GOARCH + +# Print a message indicating the build process is complete +echo "Build process completed for all platforms and architectures. Binaries are in the 'bin' directory." diff --git a/migration-guides/decrypt/stream.go b/migration-guides/decrypt/stream.go new file mode 100644 index 0000000000000000000000000000000000000000..828d9ccbf7675650a4a7746ee9fffca975e429cf --- /dev/null +++ b/migration-guides/decrypt/stream.go @@ -0,0 +1,409 @@ +package main + +import ( + "bytes" + "crypto/rand" + "encoding/binary" + "errors" + "fmt" + + "golang.org/x/crypto/chacha20" + "golang.org/x/crypto/chacha20poly1305" + "golang.org/x/crypto/poly1305" +) + +// public constants +const ( + //TagMessage the most common tag, that doesn't add any information about the nature of the message. + TagMessage = 0 + // TagPush indicates that the message marks the end of a set of messages, + // but not the end of the stream. For example, a huge JSON string sent as multiple chunks can use this tag to indicate to the application that the string is complete and that it can be decoded. But the stream itself is not closed, and more data may follow. + TagPush = 0x01 + // TagRekey "forget" the key used to encrypt this message and the previous ones, and derive a new secret key. + TagRekey = 0x02 + // TagFinal indicates that the message marks the end of the stream, and erases the secret key used to encrypt the previous sequence. + TagFinal = TagPush | TagRekey + + StreamKeyBytes = chacha20poly1305.KeySize + StreamHeaderBytes = chacha20poly1305.NonceSizeX + // XChaCha20Poly1305IetfABYTES links to crypto_secretstream_xchacha20poly1305_ABYTES + XChaCha20Poly1305IetfABYTES = 16 + 1 +) + +const cryptoCoreHchacha20InputBytes = 16 + +/* const crypto_secretstream_xchacha20poly1305_INONCEBYTES = 8 */ +const cryptoSecretStreamXchacha20poly1305Counterbytes = 4 + +var pad0 [16]byte + +var invalidKey = errors.New("invalid key") +var invalidInput = errors.New("invalid input") +var cryptoFailure = errors.New("crypto failed") + +func memZero(b []byte) { + for i := range b { + b[i] = 0 + } +} + +func xorBuf(out, in []byte) { + for i := range out { + out[i] ^= in[i] + } +} + +func bufInc(n []byte) { + c := 1 + + for i := range n { + c += int(n[i]) + n[i] = byte(c) + c >>= 8 + } +} + +// crypto_secretstream_xchacha20poly1305_state +type streamState struct { + k [StreamKeyBytes]byte + nonce [chacha20poly1305.NonceSize]byte + pad [8]byte +} + +func (s *streamState) reset() { + for i := range s.nonce { + s.nonce[i] = 0 + } + s.nonce[0] = 1 +} + +type Encryptor interface { + Push(m []byte, tag byte) ([]byte, error) +} + +type Decryptor interface { + Pull(m []byte) ([]byte, byte, error) +} + +type encryptor struct { + streamState +} + +type decryptor struct { + streamState +} + +func NewStreamKey() []byte { + k := make([]byte, chacha20poly1305.KeySize) + _, _ = rand.Read(k) + return k +} + +func NewEncryptor(key []byte) (Encryptor, []byte, error) { + if len(key) != StreamKeyBytes { + return nil, nil, invalidKey + } + + header := make([]byte, StreamHeaderBytes) + _, _ = rand.Read(header) + + stream := &encryptor{} + + k, err := chacha20.HChaCha20(key[:], header[:16]) + if err != nil { + //fmt.Printf("error: %v", err) + return nil, nil, err + } + copy(stream.k[:], k) + stream.reset() + + for i := range stream.pad { + stream.pad[i] = 0 + } + + for i, b := range header[cryptoCoreHchacha20InputBytes:] { + stream.nonce[i+cryptoSecretStreamXchacha20poly1305Counterbytes] = b + } + // fmt.Printf("stream: %+v\n", stream.streamState) + + return stream, header, nil +} + +func (s *encryptor) Push(plain []byte, tag byte) ([]byte, error) { + var err error + + //crypto_onetimeauth_poly1305_state poly1305_state; + var poly *poly1305.MAC + + //unsigned char block[64U]; + var block [64]byte + + //unsigned char slen[8U]; + var slen [8]byte + + //unsigned char *c; + //unsigned char *mac; + // + //if (outlen_p != NULL) { + //*outlen_p = 0U; + //} + + mlen := len(plain) + //if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { + //sodium_misuse(); + //} + + out := make([]byte, mlen+XChaCha20Poly1305IetfABYTES) + + chacha, err := chacha20.NewUnauthenticatedCipher(s.k[:], s.nonce[:]) + if err != nil { + return nil, err + } + //crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); + chacha.XORKeyStream(block[:], block[:]) + + //crypto_onetimeauth_poly1305_init(&poly1305_state, block); + var poly_init [32]byte + copy(poly_init[:], block[:]) + poly = poly1305.New(&poly_init) + + // TODO add support for add data + //sodium_memzero(block, sizeof block); + //crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); + //crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, + //(0x10 - adlen) & 0xf); + + //memset(block, 0, sizeof block); + //block[0] = tag; + memZero(block[:]) + block[0] = tag + + // + //crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, state->nonce, 1U, state->k); + //crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); + //out[0] = block[0]; + chacha.XORKeyStream(block[:], block[:]) + _, _ = poly.Write(block[:]) + out[0] = block[0] + + // + //c = out + (sizeof tag); + c := out[1:] + //crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); + //crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); + //crypto_onetimeauth_poly1305_update (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); + chacha.XORKeyStream(c, plain) + _, _ = poly.Write(c[:mlen]) + padlen := (0x10 - len(block) + mlen) & 0xf + _, _ = poly.Write(pad0[:padlen]) + + // + //STORE64_LE(slen, (uint64_t) adlen); + //crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + binary.LittleEndian.PutUint64(slen[:], uint64(0)) + _, _ = poly.Write(slen[:]) + + //STORE64_LE(slen, (sizeof block) + mlen); + //crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + binary.LittleEndian.PutUint64(slen[:], uint64(len(block)+mlen)) + _, _ = poly.Write(slen[:]) + + // + //mac = c + mlen; + //crypto_onetimeauth_poly1305_final(&poly1305_state, mac); + mac := c[mlen:] + copy(mac, poly.Sum(nil)) + //sodium_memzero(&poly1305_state, sizeof poly1305_state); + // + + //XOR_BUF(STATE_INONCE(state), mac, crypto_secretstream_xchacha20poly1305_INONCEBYTES); + //sodium_increment(STATE_COUNTER(state), crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + xorBuf(s.nonce[cryptoSecretStreamXchacha20poly1305Counterbytes:], mac) + bufInc(s.nonce[:cryptoSecretStreamXchacha20poly1305Counterbytes]) + + // TODO + //if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || + //sodium_is_zero(STATE_COUNTER(state), + //crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { + //crypto_secretstream_xchacha20poly1305_rekey(state); + //} + + //if (outlen_p != NULL) { + //*outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; + //} + + //return 0; + return out, nil +} + +func NewDecryptor(key, header []byte) (Decryptor, error) { + stream := &decryptor{} + + //crypto_core_hchacha20(state->k, in, k, NULL); + k, err := chacha20.HChaCha20(key, header[:16]) + if err != nil { + fmt.Printf("error: %v", err) + return nil, err + } + copy(stream.k[:], k) + + //_crypto_secretstream_xchacha20poly1305_counter_reset(state); + stream.reset() + + //memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, + // crypto_secretstream_xchacha20poly1305_INONCEBYTES); + copy(stream.nonce[cryptoSecretStreamXchacha20poly1305Counterbytes:], + header[cryptoCoreHchacha20InputBytes:]) + + //memset(state->_pad, 0, sizeof state->_pad); + copy(stream.pad[:], pad0[:]) + + //fmt.Printf("decryptor: %+v\n", stream.streamState) + + return stream, nil +} + +func (s *decryptor) Pull(cipher []byte) ([]byte, byte, error) { + cipherLen := len(cipher) + + //crypto_onetimeauth_poly1305_state poly1305_state; + var poly1305State [32]byte + + //unsigned char block[64U]; + var block [64]byte + //unsigned char slen[8U]; + var slen [8]byte + + //unsigned char mac[crypto_onetimeauth_poly1305_BYTES]; + //const unsigned char *c; + //const unsigned char *stored_mac; + //unsigned long long mlen; // length of the returned message + //unsigned char tag; // for the return value + // + //if (mlen_p != NULL) { + //*mlen_p = 0U; + //} + //if (tag_p != NULL) { + //*tag_p = 0xff; + //} + + /* + if (inlen < crypto_secretstream_xchacha20poly1305_ABYTES) { + return -1; + } + mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; + */ + if cipherLen < XChaCha20Poly1305IetfABYTES { + return nil, 0, invalidInput + } + mlen := cipherLen - XChaCha20Poly1305IetfABYTES + + //if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { + //sodium_misuse(); + //} + + //crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); + chacha, err := chacha20.NewUnauthenticatedCipher(s.k[:], s.nonce[:]) + if err != nil { + return nil, 0, err + } + chacha.XORKeyStream(block[:], block[:]) + + //crypto_onetimeauth_poly1305_init(&poly1305_state, block); + + copy(poly1305State[:], block[:]) + poly := poly1305.New(&poly1305State) + + // TODO + //sodium_memzero(block, sizeof block); + //crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); + //crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, + //(0x10 - adlen) & 0xf); + // + + //memset(block, 0, sizeof block); + //block[0] = in[0]; + //crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, state->nonce, 1U, state->k); + memZero(block[:]) + block[0] = cipher[0] + chacha.XORKeyStream(block[:], block[:]) + + //tag = block[0]; + //block[0] = in[0]; + //crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); + tag := block[0] + block[0] = cipher[0] + if _, err = poly.Write(block[:]); err != nil { + return nil, 0, err + } + + //c = in + (sizeof tag); + //crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); + //crypto_onetimeauth_poly1305_update (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); + c := cipher[1:] + if _, err = poly.Write(c[:mlen]); err != nil { + return nil, 0, err + } + padLen := (0x10 - len(block) + mlen) & 0xf + if _, err = poly.Write(pad0[:padLen]); err != nil { + return nil, 0, err + } + + // + //STORE64_LE(slen, (uint64_t) adlen); + //crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + binary.LittleEndian.PutUint64(slen[:], uint64(0)) + if _, err = poly.Write(slen[:]); err != nil { + return nil, 0, err + } + + //STORE64_LE(slen, (sizeof block) + mlen); + //crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + binary.LittleEndian.PutUint64(slen[:], uint64(len(block)+mlen)) + if _, err = poly.Write(slen[:]); err != nil { + return nil, 0, err + } + + // + //crypto_onetimeauth_poly1305_final(&poly1305_state, mac); + //sodium_memzero(&poly1305_state, sizeof poly1305_state); + + mac := poly.Sum(nil) + memZero(poly1305State[:]) + + //stored_mac = c + mlen; + //if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { + //sodium_memzero(mac, sizeof mac); + //return -1; + //} + storedMac := c[mlen:] + if !bytes.Equal(mac, storedMac) { + memZero(mac) + return nil, 0, cryptoFailure + } + + //crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); + //XOR_BUF(STATE_INONCE(state), mac, crypto_secretstream_xchacha20poly1305_INONCEBYTES); + //sodium_increment(STATE_COUNTER(state), crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + m := make([]byte, mlen) + chacha.XORKeyStream(m, c[:mlen]) + + xorBuf(s.nonce[cryptoSecretStreamXchacha20poly1305Counterbytes:], mac) + bufInc(s.nonce[:cryptoSecretStreamXchacha20poly1305Counterbytes]) + + // TODO + //if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || + //sodium_is_zero(STATE_COUNTER(state), + //crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { + //crypto_secretstream_xchacha20poly1305_rekey(state); + //} + + //if (mlen_p != NULL) { + //*mlen_p = mlen; + //} + //if (tag_p != NULL) { + //*tag_p = tag; + //} + //return 0; + return m, tag, nil +} diff --git a/migration-guides/encrypted_export.md b/migration-guides/encrypted_export.md index 9ac3b91142ffd131527ab1a95dd1760d97cccb8c..0eeb7d0f79fd96c3e7217c1ea79178b09116edcc 100644 --- a/migration-guides/encrypted_export.md +++ b/migration-guides/encrypted_export.md @@ -56,7 +56,7 @@ For encryption, we are using `XChaCha20-Poly1305` algorithm. * **ente Authenticator app**: You can directly import the codes in the ente Authenticator app. > Settings -> Data -> Import Codes -> ente Encrypted export. -* **Decryption Tool** : You can download the prebuilt [decryption tool](decrypt/decrypt) (or build it from [source](decrypt)) and run the following command. +* **Decryption Tool** : You can download the prebuilt [decryption tool](decrypt/bin/) (or build it from [source](decrypt)) and run the following command. ``` ./decrypt