You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.0 KiB
73 lines
2.0 KiB
package crypto |
|
|
|
import ( |
|
"crypto/aes" |
|
"crypto/sha1" // #nosec |
|
"io" |
|
|
|
"github.com/go-faster/errors" |
|
|
|
"github.com/gotd/ige" |
|
|
|
"github.com/gotd/td/bin" |
|
) |
|
|
|
// DecryptExchangeAnswer decrypts messages created during key exchange. |
|
func DecryptExchangeAnswer(data, key, iv []byte) (dst []byte, err error) { |
|
// Decrypting inner data. |
|
cipher, err := aes.NewCipher(key) |
|
if err != nil { |
|
return nil, errors.Wrap(err, "create aes cipher") |
|
} |
|
|
|
dataWithHash := make([]byte, len(data)) |
|
// Checking length. Invalid length will lead to panic in CryptBlocks. |
|
if len(dataWithHash)%cipher.BlockSize() != 0 { |
|
return nil, errors.Errorf("invalid len of data_with_hash (%d %% 16 != 0)", len(dataWithHash)) |
|
} |
|
ige.DecryptBlocks(cipher, iv, dataWithHash, data) |
|
|
|
dst = GuessDataWithHash(dataWithHash) |
|
if data == nil { |
|
// Most common cause of this error is invalid crypto implementation, |
|
// i.e. invalid keys are used to decrypt payload which lead to |
|
// decrypt failure, so data does not match sha1 with any padding. |
|
return nil, errors.New("guess data from data_with_hash") |
|
} |
|
|
|
return |
|
} |
|
|
|
// EncryptExchangeAnswer encrypts messages created during key exchange. |
|
func EncryptExchangeAnswer(rand io.Reader, answer, key, iv []byte) (dst []byte, err error) { |
|
cipher, err := aes.NewCipher(key) |
|
if err != nil { |
|
return nil, errors.Wrap(err, "create aes cipher") |
|
} |
|
|
|
answerWithHash, err := DataWithHash(answer, rand) |
|
if err != nil { |
|
return nil, errors.Wrap(err, "get answer with hash") |
|
} |
|
|
|
dst = make([]byte, len(answerWithHash)) |
|
ige.EncryptBlocks(cipher, iv, dst, answerWithHash) |
|
return |
|
} |
|
|
|
// NonceHash1 computes nonce_hash_1. |
|
// See https://core.telegram.org/mtproto/auth_key#dh-key-exchange-complete. |
|
func NonceHash1(newNonce bin.Int256, key Key) (r bin.Int128) { |
|
var buf []byte |
|
buf = append(buf, newNonce[:]...) |
|
buf = append(buf, 1) |
|
buf = append(buf, sha(key[:])[0:8]...) |
|
buf = sha(buf)[4:20] |
|
copy(r[:], buf) |
|
return |
|
} |
|
|
|
func sha(v []byte) []byte { |
|
h := sha1.Sum(v) // #nosec |
|
return h[:] |
|
}
|
|
|