// Yes, AniDB works in ECB mode
type ecbState struct {
- udpKey string
- aes cipher.Block
+ cipher.Block
}
func newECBState(udpKey string, salt []byte) *ecbState {
- ecb := &ecbState{udpKey: udpKey}
- ecb.Init(salt)
+ ecb := &ecbState{}
+ ecb.Init(udpKey, salt)
return ecb
}
-func (ecb *ecbState) Init(salt []byte) {
+func (ecb *ecbState) Init(udpKey string, salt []byte) {
h := md5.New()
- h.Write([]byte(ecb.udpKey))
+ h.Write([]byte(udpKey))
h.Write(salt)
key := h.Sum(nil)
- ecb.aes, _ = aes.NewCipher(key)
+ b, err := aes.NewCipher(key)
+ ecb.Block = b
+ if err != nil {
+ panic(err)
+ }
}
func (ecb *ecbState) BlockSize() int {
}
padded := pkcs7Pad(p, aes.BlockSize)
- c = make([]byte, 0, len(padded))
+ c = make([]byte, len(padded))
for i := 0; i < len(padded); i += aes.BlockSize {
- ecb.aes.Encrypt(c[i:i+aes.BlockSize], padded[i:i+aes.BlockSize])
+ ecb.Block.Encrypt(c[i:i+aes.BlockSize], padded[i:i+aes.BlockSize])
}
return c
}
-func (ecb *ecbState) Decrypt(c []byte) (p []byte) {
+func (ecb *ecbState) Decrypt(c []byte) []byte {
if ecb == nil {
return c
}
- for i := 0; i < len(c); i += ecb.aes.BlockSize() {
- ecb.aes.Decrypt(p[i:], c[i:])
+ p := make([]byte, len(c))
+ for i := 0; i < len(c); i += aes.BlockSize {
+ ecb.Block.Decrypt(p[i:i+aes.BlockSize], c[i:i+aes.BlockSize])
}
return pkcs7Unpad(p, aes.BlockSize)
}
package udpapi
import (
+ "math/rand"
+ "reflect"
"testing"
)
+func TestECB(T *testing.T) {
+ T.Parallel()
+
+ rnd := rand.New(rand.NewSource(31415))
+
+ salt := make([]byte, rnd.Intn(64))
+ for i := range salt {
+ salt[i] = byte(rnd.Intn(255))
+ }
+ plain := make([]byte, 1200+rnd.Intn(200))
+ for i := range plain {
+ plain[i] = byte(rnd.Intn(255))
+ }
+
+ ecbState := newECBState("agaa", salt)
+
+ T.Log("Length of plaintext:", len(plain))
+ cipher := ecbState.Encrypt(plain)
+ T.Log("Length of ciphertext:", len(cipher))
+ plain2 := ecbState.Decrypt(cipher)
+ T.Log("Length of roundtrip plaintext:", len(plain2))
+
+ if !reflect.DeepEqual(plain, plain2) {
+ T.Error("Encoding roundtrip result doesn't match plaintext")
+ }
+}
+
func TestPKCS7(T *testing.T) {
+ T.Parallel()
+
blockSize := byte(4)
vec := [][2]string{
[2]string{"testing", "testing\x01"},