//For simplicity sake, return key and iv too. func EncryptComment(comment string) (key, iv, ciphertext []byte) { pre := []byte("comment1=cooking%20MCs;userdata=") //Eat illegal characters comment = strings.Split(comment, ";")[0] comment = strings.Split(comment, "=")[0] combytes := []byte(comment) post := []byte(";comment2=%20like%20a%20pound%20of%20bacon") plaintext := append(pre, combytes...) plaintext = append(plaintext, post...) plaintext = aes.Pad(plaintext, 16) key = aes.RandBytes(16) iv = aes.RandBytes(16) ciphertext = aes.CBCEncrypt(key, iv, plaintext) return }
//Test for set 2 challenge 13 func TestECBCutAndPaste(t *testing.T) { key := aes.RandBytes(16) oracle := func(in string) []byte { return ProfileFor(key, in) } //This payload will give me an padded admin block. payload1 := "kelbyXXXXXadmin\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" //This payload will give me a ct with "role=" at a block border. payload2 := "kelbyXXXXXXXX" ct1 := oracle(payload1) ct2 := oracle(payload2) new_ct := append(ct2[:32], ct1[16:32]...) if !CTIsAdmin(key, new_ct) { t.Errorf("ECBCutAndPaste: Failed to create admin profile") } }
//Test for challenge 25 func TestCTREdit(t *testing.T) { plaintext := []byte("My shell, mechanical found ghost. But my ghetto is animal found toast") key := aes.RandBytes(16) nonce := uint64(0) ciphertext := aes.CTREncrypt(key, nonce, plaintext) oracle := func(ct []byte, offset int, insert []byte) []byte { pt := aes.CTRDecrypt(key, nonce, ct) begin := pt[0:offset] end := pt[offset+len(insert):] newPt := append(begin, insert...) newPt = append(newPt, end...) return aes.CTREncrypt(key, nonce, newPt) } recoveredPlaintext := CTREditAttack(ciphertext, oracle) if string(recoveredPlaintext) != string(plaintext) { t.Errorf("CTREdit: Attack failed.") } }
//Test for set 2 challenge 14 func TestECBChosenInfixAttack(t *testing.T) { key := make([]byte, 16) _, err := rand.Read(key) if err != nil { t.Errorf("ECBChosenInfixAttack: Failed reading from urandom") } var prefix uint32 binary.Read(rand.Reader, binary.LittleEndian, &prefix) num := int(prefix % 32) random_prefix := aes.RandBytes(num) oracle := func(input []byte) []byte { return ECBChosenInfix(random_prefix, input, key) } //Determine block size of oracle bs := DetermineOracleBlockSize(oracle) if bs != 16 { t.Errorf("ECBChosenInfixAttack: Failed to determine correct block size") } //Determine if oracle is using ECB mode //TODO: This is silly. You should make your cryptanalysis functions take an oracle function. Will be more reusable. data := []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") if !DetectECB256Mode(oracle(data)) { t.Errorf("ECBChosenInfixAttack: Failed to correctly guess that the oracle used ECB mode.") } result := ECBSecretInfixAttack(oracle) expected_result := `Rollin' in my 5.0 With my rag-top down so my hair can blow The girlies on standby waving just to say hi Did you stop? No, I just drove by` if result[:12] != expected_result[:12] { t.Errorf("ECBChosenInfixAttack: Expected decryption did not actually match real decryption") } }