github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/encrypt/aes_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package encrypt 15 16 import ( 17 "crypto/aes" 18 "encoding/hex" 19 "strings" 20 "testing" 21 22 . "github.com/whtcorpsinc/check" 23 "github.com/whtcorpsinc/milevadb/soliton/testleak" 24 ) 25 26 var _ = Suite(&testEncryptSuite{}) 27 28 func TestT(t *testing.T) { 29 CustomVerboseFlag = true 30 TestingT(t) 31 } 32 33 type testEncryptSuite struct { 34 } 35 36 func toHex(buf []byte) string { 37 return strings.ToUpper(hex.EncodeToString(buf)) 38 } 39 40 func (s *testEncryptSuite) TestPad(c *C) { 41 defer testleak.AfterTest(c)() 42 43 p := []byte{0x0A, 0x0B, 0x0C, 0x0D} 44 p, err := PKCS7Pad(p, 8) 45 c.Assert(err, IsNil) 46 c.Assert(toHex(p), Equals, "0A0B0C0D04040404") 47 48 p = []byte{0x0A, 0x0B, 0x0C, 0x0D, 0x0A, 0x0B, 0x0C, 0x0D} 49 p, err = PKCS7Pad(p, 8) 50 c.Assert(err, IsNil) 51 c.Assert(toHex(p), Equals, "0A0B0C0D0A0B0C0D0808080808080808") 52 53 p = []byte{0x0A, 0x0B, 0x0C, 0x0D} 54 p, err = PKCS7Pad(p, 16) 55 c.Assert(err, IsNil) 56 c.Assert(toHex(p), Equals, "0A0B0C0D0C0C0C0C0C0C0C0C0C0C0C0C") 57 } 58 59 func (s *testEncryptSuite) TestUnpad(c *C) { 60 defer testleak.AfterTest(c)() 61 62 // Valid paddings. 63 p := []byte{0x0A, 0x0B, 0x0C, 0x0D, 0x04, 0x04, 0x04, 0x04} 64 p, err := PKCS7Unpad(p, 8) 65 c.Assert(err, IsNil) 66 c.Assert(toHex(p), Equals, "0A0B0C0D") 67 68 p = []byte{0x0A, 0x0B, 0x0C, 0x0D, 0x0A, 0x0B, 0x0C, 0x0D, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08} 69 p, err = PKCS7Unpad(p, 8) 70 c.Assert(err, IsNil) 71 c.Assert(toHex(p), Equals, "0A0B0C0D0A0B0C0D") 72 73 p = []byte{0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C} 74 p, err = PKCS7Unpad(p, 16) 75 c.Assert(err, IsNil) 76 c.Assert(toHex(p), Equals, "0A0B0C0D") 77 78 p = []byte{0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08} 79 p, err = PKCS7Unpad(p, 8) 80 c.Assert(err, IsNil) 81 c.Assert(toHex(p), Equals, "") 82 83 // Invalid padding: incorrect causet size 84 p = []byte{0x0A, 0x0B, 0x0C, 0x04, 0x04, 0x04, 0x04} 85 _, err = PKCS7Unpad(p, 8) 86 c.Assert(err, NotNil) 87 88 p = []byte{0x0A, 0x0B, 0x0C, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04} 89 _, err = PKCS7Unpad(p, 8) 90 c.Assert(err, NotNil) 91 92 p = []byte{} 93 _, err = PKCS7Unpad(p, 8) 94 c.Assert(err, NotNil) 95 96 // Invalid padding: padding length > causet length 97 p = []byte{0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09} 98 _, err = PKCS7Unpad(p, 8) 99 c.Assert(err, NotNil) 100 101 // Invalid padding: padding length == 0 102 p = []byte{0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x00} 103 // ^^^^ 104 _, err = PKCS7Unpad(p, 8) 105 c.Assert(err, NotNil) 106 107 // Invalid padding: padding content invalid 108 p = []byte{0x0A, 0x0B, 0x0C, 0x0D, 0x0A, 0x0B, 0x0C, 0x0D, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08} 109 // ^^^^ 110 _, err = PKCS7Unpad(p, 8) 111 c.Assert(err, NotNil) 112 113 // Invalid padding: padding content invalid 114 p = []byte{0x03, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08} 115 // ^^^^ 116 _, err = PKCS7Unpad(p, 8) 117 c.Assert(err, NotNil) 118 119 // Invalid padding: padding content invalid 120 p = []byte{0x0A, 0x0B, 0x0C, 0x0D, 0x04, 0x04, 0x03, 0x04} 121 // ^^^^ 122 _, err = PKCS7Unpad(p, 8) 123 c.Assert(err, NotNil) 124 } 125 126 func (s *testEncryptSuite) TestAESECB(c *C) { 127 defer testleak.AfterTest(c)() 128 var commonInput = []byte{ 129 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 130 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 131 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 132 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, 133 } 134 var commonKey128 = []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c} 135 var commonKey192 = []byte{ 136 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, 137 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, 138 } 139 var commonKey256 = []byte{ 140 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 141 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, 142 } 143 var ecbAESTests = []struct { 144 name string 145 key []byte 146 in []byte 147 out []byte 148 }{ 149 // NIST SP 800-38A pp 24-27 150 { 151 "ECB-AES128", 152 commonKey128, 153 commonInput, 154 []byte{ 155 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, 156 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf, 157 0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88, 158 0x7b, 0x0c, 0x78, 0x5e, 0x27, 0xe8, 0xad, 0x3f, 0x82, 0x23, 0x20, 0x71, 0x04, 0x72, 0x5d, 0xd4, 159 }, 160 }, 161 { 162 "ECB-AES192", 163 commonKey192, 164 commonInput, 165 []byte{ 166 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc, 167 0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad, 0x77, 0x34, 0xec, 0xb3, 0xec, 0xee, 0x4e, 0xef, 168 0xef, 0x7a, 0xfd, 0x22, 0x70, 0xe2, 0xe6, 0x0a, 0xdc, 0xe0, 0xba, 0x2f, 0xac, 0xe6, 0x44, 0x4e, 169 0x9a, 0x4b, 0x41, 0xba, 0x73, 0x8d, 0x6c, 0x72, 0xfb, 0x16, 0x69, 0x16, 0x03, 0xc1, 0x8e, 0x0e, 170 }, 171 }, 172 { 173 "ECB-AES256", 174 commonKey256, 175 commonInput, 176 []byte{ 177 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8, 178 0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26, 0xdc, 0x5b, 0xa7, 0x4a, 0x31, 0x36, 0x28, 0x70, 179 0xb6, 0xed, 0x21, 0xb9, 0x9c, 0xa6, 0xf4, 0xf9, 0xf1, 0x53, 0xe7, 0xb1, 0xbe, 0xaf, 0xed, 0x1d, 180 0x23, 0x30, 0x4b, 0x7a, 0x39, 0xf9, 0xf3, 0xff, 0x06, 0x7d, 0x8d, 0x8f, 0x9e, 0x24, 0xec, 0xc7, 181 }, 182 }, 183 } 184 185 for _, tt := range ecbAESTests { 186 test := tt.name 187 188 cipher, err := aes.NewCipher(tt.key) 189 c.Assert(err, IsNil, Commentf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)) 190 191 encrypter := newECBEncrypter(cipher) 192 d := make([]byte, len(tt.in)) 193 encrypter.CryptBlocks(d, tt.in) 194 c.Assert(toHex(tt.out), Equals, toHex(d), Commentf("%s: ECBEncrypter\nhave %x\nwant %x", test, d, tt.out)) 195 196 decrypter := newECBDecrypter(cipher) 197 p := make([]byte, len(d)) 198 decrypter.CryptBlocks(p, d) 199 c.Assert(toHex(tt.in), Equals, toHex(p), Commentf("%s: ECBDecrypter\nhave %x\nwant %x", test, d, tt.in)) 200 } 201 } 202 203 func (s *testEncryptSuite) TestAESEncryptWithECB(c *C) { 204 defer testleak.AfterTest(c)() 205 tests := []struct { 206 str string 207 key string 208 expect string 209 isError bool 210 }{ 211 // 128 bits key 212 {"whtcorpsinc", "1234567890123456", "697BFE9B3F8C2F289DD82C88C7BC95C4", false}, 213 {"WHTCORPS INC123", "1234567890123456", "CEC348F4EF5F84D3AA6C4FA184C65766", false}, 214 // 192 bits key 215 {"whtcorpsinc", "123456789012345678901234", "E435438AC6798B4718533096436EC342", false}, // 192 bit 216 // negtive cases: invalid key length 217 {"whtcorpsinc", "12345678901234567", "", true}, 218 {"whtcorpsinc", "123456789012345", "", true}, 219 } 220 221 for _, t := range tests { 222 str := []byte(t.str) 223 key := []byte(t.key) 224 225 crypted, err := AESEncryptWithECB(str, key) 226 if t.isError { 227 c.Assert(err, NotNil, Commentf("%v", t)) 228 continue 229 } 230 c.Assert(err, IsNil, Commentf("%v", t)) 231 result := toHex(crypted) 232 c.Assert(result, Equals, t.expect, Commentf("%v", t)) 233 } 234 } 235 236 func (s *testEncryptSuite) TestAESDecryptWithECB(c *C) { 237 defer testleak.AfterTest(c)() 238 tests := []struct { 239 expect string 240 key string 241 hexCryptStr string 242 isError bool 243 }{ 244 // 128 bits key 245 {"whtcorpsinc", "1234567890123456", "697BFE9B3F8C2F289DD82C88C7BC95C4", false}, 246 {"WHTCORPS INC123", "1234567890123456", "CEC348F4EF5F84D3AA6C4FA184C65766", false}, 247 // 192 bits key 248 {"whtcorpsinc", "123456789012345678901234", "E435438AC6798B4718533096436EC342", false}, // 192 bit 249 // negtive cases: invalid key length 250 {"whtcorpsinc", "12345678901234567", "", true}, 251 {"whtcorpsinc", "123456789012345", "", true}, 252 // negtive cases: invalid padding / padding size 253 {"", "1234567890123456", "11223344556677112233", true}, 254 {"", "1234567890123456", "11223344556677112233112233445566", true}, 255 {"", "1234567890123456", "1122334455667711223311223344556611", true}, 256 } 257 258 for _, t := range tests { 259 cryptStr, _ := hex.DecodeString(t.hexCryptStr) 260 key := []byte(t.key) 261 262 result, err := AESDecryptWithECB(cryptStr, key) 263 if t.isError { 264 c.Assert(err, NotNil) 265 continue 266 } 267 c.Assert(err, IsNil) 268 c.Assert(string(result), Equals, t.expect) 269 } 270 } 271 272 func (s *testEncryptSuite) TestAESEncryptWithCBC(c *C) { 273 defer testleak.AfterTest(c)() 274 tests := []struct { 275 str string 276 key string 277 iv string 278 expect string 279 isError bool 280 }{ 281 // 128 bits key 282 {"whtcorpsinc", "1234567890123456", "1234567890123456", "2ECA0077C5EA5768A0485AA522774792", false}, 283 {"WHTCORPS INC123", "1234567890123456", "1234567890123456", "042962D340F2F95BCC07B56EAC378D3A", false}, 284 // 192 bits key 285 {"whtcorpsinc", "123456789012345678901234", "1234567890123456", "EDECE05D9FE662E381130F7F19BA67F7", false}, // 192 bit 286 // negtive cases: invalid key length 287 {"whtcorpsinc", "12345678901234567", "1234567890123456", "", true}, 288 {"whtcorpsinc", "123456789012345", "1234567890123456", "", true}, 289 } 290 291 for _, t := range tests { 292 str := []byte(t.str) 293 key := []byte(t.key) 294 iv := []byte(t.iv) 295 296 crypted, err := AESEncryptWithCBC(str, key, iv) 297 if t.isError { 298 c.Assert(err, NotNil, Commentf("%v", t)) 299 continue 300 } 301 c.Assert(err, IsNil, Commentf("%v", t)) 302 result := toHex(crypted) 303 c.Assert(result, Equals, t.expect, Commentf("%v", t)) 304 } 305 } 306 307 func (s *testEncryptSuite) TestAESEncryptWithOFB(c *C) { 308 defer testleak.AfterTest(c)() 309 tests := []struct { 310 str string 311 key string 312 iv string 313 expect string 314 isError bool 315 }{ 316 // 128 bits key 317 {"whtcorpsinc", "1234567890123456", "1234567890123456", "0515A36BBF3DE0", false}, 318 {"WHTCORPS INC123", "1234567890123456", "1234567890123456", "0515A36BBF3DE0DBE9DD", false}, 319 // 192 bits key 320 {"whtcorpsinc", "123456789012345678901234", "1234567890123456", "45A57592449893", false}, // 192 bit 321 // negtive cases: invalid key length 322 {"whtcorpsinc", "12345678901234567", "1234567890123456", "", true}, 323 {"whtcorpsinc", "123456789012345", "1234567890123456", "", true}, 324 } 325 326 for _, t := range tests { 327 str := []byte(t.str) 328 key := []byte(t.key) 329 iv := []byte(t.iv) 330 331 crypted, err := AESEncryptWithOFB(str, key, iv) 332 if t.isError { 333 c.Assert(err, NotNil, Commentf("%v", t)) 334 continue 335 } 336 c.Assert(err, IsNil, Commentf("%v", t)) 337 result := toHex(crypted) 338 c.Assert(result, Equals, t.expect, Commentf("%v", t)) 339 } 340 } 341 342 func (s *testEncryptSuite) TestAESDecryptWithOFB(c *C) { 343 defer testleak.AfterTest(c)() 344 tests := []struct { 345 str string 346 key string 347 iv string 348 expect string 349 isError bool 350 }{ 351 // 128 bits key 352 {"0515A36BBF3DE0", "1234567890123456", "1234567890123456", "whtcorpsinc", false}, 353 {"0515A36BBF3DE0DBE9DD", "1234567890123456", "1234567890123456", "WHTCORPS INC123", false}, 354 // 192 bits key 355 {"45A57592449893", "123456789012345678901234", "1234567890123456", "whtcorpsinc", false}, // 192 bit 356 // negtive cases: invalid key length 357 {"whtcorpsinc", "12345678901234567", "1234567890123456", "", true}, 358 {"whtcorpsinc", "123456789012345", "1234567890123456", "", true}, 359 } 360 361 for _, t := range tests { 362 str, _ := hex.DecodeString(t.str) 363 key := []byte(t.key) 364 iv := []byte(t.iv) 365 366 plainText, err := AESDecryptWithOFB(str, key, iv) 367 if t.isError { 368 c.Assert(err, NotNil, Commentf("%v", t)) 369 continue 370 } 371 c.Assert(err, IsNil, Commentf("%v", t)) 372 c.Assert(string(plainText), Equals, t.expect, Commentf("%v", t)) 373 } 374 } 375 376 func (s *testEncryptSuite) TestAESDecryptWithCBC(c *C) { 377 defer testleak.AfterTest(c)() 378 tests := []struct { 379 expect string 380 key string 381 iv string 382 hexCryptStr string 383 isError bool 384 }{ 385 // 128 bits key 386 {"whtcorpsinc", "1234567890123456", "1234567890123456", "2ECA0077C5EA5768A0485AA522774792", false}, 387 {"WHTCORPS INC123", "1234567890123456", "1234567890123456", "042962D340F2F95BCC07B56EAC378D3A", false}, 388 // 192 bits key 389 {"whtcorpsinc", "123456789012345678901234", "1234567890123456", "EDECE05D9FE662E381130F7F19BA67F7", false}, // 192 bit 390 // negtive cases: invalid key length 391 {"whtcorpsinc", "12345678901234567", "1234567890123456", "", true}, 392 {"whtcorpsinc", "123456789012345", "1234567890123456", "", true}, 393 // negtive cases: invalid padding / padding size 394 {"", "1234567890123456", "1234567890123456", "11223344556677112233", true}, 395 {"", "1234567890123456", "1234567890123456", "11223344556677112233112233445566", true}, 396 {"", "1234567890123456", "1234567890123456", "1122334455667711223311223344556611", true}, 397 } 398 399 for _, t := range tests { 400 cryptStr, _ := hex.DecodeString(t.hexCryptStr) 401 key := []byte(t.key) 402 iv := []byte(t.iv) 403 404 result, err := AESDecryptWithCBC(cryptStr, key, iv) 405 if t.isError { 406 c.Assert(err, NotNil) 407 continue 408 } 409 c.Assert(err, IsNil) 410 c.Assert(string(result), Equals, t.expect) 411 } 412 } 413 414 func (s *testEncryptSuite) TestAESEncryptWithCFB(c *C) { 415 defer testleak.AfterTest(c)() 416 tests := []struct { 417 str string 418 key string 419 iv string 420 expect string 421 isError bool 422 }{ 423 // 128 bits key 424 {"whtcorpsinc", "1234567890123456", "1234567890123456", "0515A36BBF3DE0", false}, 425 {"WHTCORPS INC123", "1234567890123456", "1234567890123456", "0515A36BBF3DE0DBE9DD", false}, 426 // 192 bits key 427 {"whtcorpsinc", "123456789012345678901234", "1234567890123456", "45A57592449893", false}, // 192 bit 428 // negtive cases: invalid key length 429 {"whtcorpsinc", "12345678901234567", "1234567890123456", "", true}, 430 {"whtcorpsinc", "123456789012345", "1234567890123456", "", true}, 431 } 432 433 for _, t := range tests { 434 str := []byte(t.str) 435 key := []byte(t.key) 436 iv := []byte(t.iv) 437 438 crypted, err := AESEncryptWithCFB(str, key, iv) 439 if t.isError { 440 c.Assert(err, NotNil, Commentf("%v", t)) 441 continue 442 } 443 c.Assert(err, IsNil, Commentf("%v", t)) 444 result := toHex(crypted) 445 c.Assert(result, Equals, t.expect, Commentf("%v", t)) 446 } 447 } 448 449 func (s *testEncryptSuite) TestAESDecryptWithCFB(c *C) { 450 defer testleak.AfterTest(c)() 451 tests := []struct { 452 str string 453 key string 454 iv string 455 expect string 456 isError bool 457 }{ 458 // 128 bits key 459 {"0515A36BBF3DE0", "1234567890123456", "1234567890123456", "whtcorpsinc", false}, 460 {"0515A36BBF3DE0DBE9DD", "1234567890123456", "1234567890123456", "WHTCORPS INC123", false}, 461 // 192 bits key 462 {"45A57592449893", "123456789012345678901234", "1234567890123456", "whtcorpsinc", false}, // 192 bit 463 // negtive cases: invalid key length 464 {"whtcorpsinc", "12345678901234567", "1234567890123456", "", true}, 465 {"whtcorpsinc", "123456789012345", "1234567890123456", "", true}, 466 } 467 468 for _, t := range tests { 469 str, _ := hex.DecodeString(t.str) 470 key := []byte(t.key) 471 iv := []byte(t.iv) 472 473 plainText, err := AESDecryptWithCFB(str, key, iv) 474 if t.isError { 475 c.Assert(err, NotNil, Commentf("%v", t)) 476 continue 477 } 478 c.Assert(err, IsNil, Commentf("%v", t)) 479 c.Assert(string(plainText), Equals, t.expect, Commentf("%v", t)) 480 } 481 } 482 483 func (s *testEncryptSuite) TestDeriveKeyMyALLEGROSQL(c *C) { 484 defer testleak.AfterTest(c)() 485 486 p := []byte("MyALLEGROSQL=insecure! MyALLEGROSQL=insecure! ") 487 p = DeriveKeyMyALLEGROSQL(p, 16) 488 c.Assert(toHex(p), Equals, "00000000000000000000000000000000") 489 490 // Short password. 491 p = []byte{0xC0, 0x10, 0x44, 0xCC, 0x10, 0xD9} 492 p = DeriveKeyMyALLEGROSQL(p, 16) 493 c.Assert(toHex(p), Equals, "C01044CC10D900000000000000000000") 494 495 // Long password. 496 p = []byte("MySecretVeryLooooongPassword") 497 p = DeriveKeyMyALLEGROSQL(p, 16) 498 c.Assert(toHex(p), Equals, "22163D0233131607210A001D4C6F6F6F") 499 }