package tdesktop
import (
"bytes"
"crypto/aes"
"crypto/sha1"
"crypto/sha512"
"github.com/go-faster/errors"
"golang.org/x/crypto/pbkdf2"
"github.com/gotd/ige"
"github.com/gotd/td/bin"
"github.com/gotd/td/internal/crypto"
)
func createLegacyLocalKey (passcode , salt []byte ) (r crypto .Key ) {
iters := localEncryptNoPwdIterCount
if len (passcode ) > 0 {
iters = localEncryptIterCount
}
key := pbkdf2 .Key (passcode , salt , iters , len (r ), sha1 .New )
copy (r [:], key )
return r
}
func createLocalKey (passcode , salt []byte ) (r crypto .Key ) {
iters := 1
if len (passcode ) > 0 {
iters = kStrongIterationsCount
}
h := sha512 .New ()
_, _ = h .Write (salt )
_, _ = h .Write (passcode )
_, _ = h .Write (salt )
key := pbkdf2 .Key (h .Sum (nil ), salt , iters , len (r ), sha512 .New )
copy (r [:], key )
return r
}
func decryptLocal (encrypted []byte , localKey crypto .Key ) ([]byte , error ) {
if l := len (encrypted ); l %aes .BlockSize != 0 {
return nil , errors .Errorf ("invalid length %d, must be padded to 16" , l )
}
var msgKey bin .Int128
n := copy (msgKey [:], encrypted )
encrypted = encrypted [n :]
aesKey , aesIV := crypto .OldKeys (localKey , msgKey , crypto .Server )
cipher , err := aes .NewCipher (aesKey [:])
if err != nil {
return nil , errors .Wrap (err , "create cipher" )
}
decrypted := make ([]byte , len (encrypted ))
ige .DecryptBlocks (cipher , aesIV [:], decrypted , encrypted )
if h := sha1 .Sum (decrypted ); !bytes .Equal (h [:16 ], msgKey [:]) {
return nil , errors .New ("msg_key mismatch" )
}
return decrypted , nil
}
func encryptLocal (decrypted []byte , localKey crypto .Key ) ([]byte , error ) {
if l := len (decrypted ); l %aes .BlockSize != 0 {
return nil , errors .Errorf ("invalid length %d, must be padded to 16" , l )
}
var msgKey bin .Int128
h := sha1 .Sum (decrypted )
copy (msgKey [:], h [:])
aesKey , aesIV := crypto .OldKeys (localKey , msgKey , crypto .Server )
cipher , err := aes .NewCipher (aesKey [:])
if err != nil {
return nil , errors .Wrap (err , "create cipher" )
}
encrypted := make ([]byte , 16 +len (decrypted ))
copy (encrypted , msgKey [:])
ige .EncryptBlocks (cipher , aesIV [:], encrypted [16 :], decrypted )
return encrypted , nil
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .