// AesOracle prepends and appends 5-10 random bytes to a plaintext, // encrypts the plaintext under a predetermined BlockMode, then // returns the detected BlockMode func AesOracle(plaintext []byte, encrypter cipher.BlockMode) string { // Generate random bytes to prepend/append to plaintext prependBytes, _ := bytes.Random(r.Intn(5) + 5) appendBytes, _ := bytes.Random(r.Intn(5) + 5) plaintext = append(prependBytes, plaintext...) plaintext = append(plaintext, appendBytes...) plaintext, _ = blocks.Pkcs7(plaintext, aes.BlockSize) ciphertext := make([]byte, len(plaintext)) modifiedCiphertext := make([]byte, len(plaintext)) // Modify the first block of the plaintext modified := plaintext modified[0] = byte(255) encrypter.CryptBlocks(ciphertext, plaintext) encrypter.CryptBlocks(modifiedCiphertext, modified) // If the second block in the modified ciphertext is affected by a // change in the first block of the plaintext, return CBC mode if ciphertext[16] != modifiedCiphertext[16] { return "CBC" } return "ECB" }
// AES-CBC 返回binary结果 func AESCBC(byteKey, src []byte, isEncode bool) (rst []byte) { rst = make([]byte, len(src)) b, err := aes.NewCipher(byteKey) if err != nil { return } iv := byteKey[:aes.BlockSize] var cc cipher.BlockMode var nsrc []byte if isEncode { cc = cipher.NewCBCEncrypter(b, iv) nsrc = PKCS5Padding(src, aes.BlockSize) } else { cc = cipher.NewCBCDecrypter(b, iv) nsrc = src } dst := make([]byte, len(nsrc)) cc.CryptBlocks(dst, nsrc) if isEncode { rst = dst } else { rst = PKCS5UnPadding(dst) } return }
func decrypt(block cipher.Block, in io.Reader, size int, out io.WriteCloser) error { var err error var buf []byte var count int var decrypter cipher.BlockMode defer out.Close() buf = make([]byte, block.BlockSize()) if _, err = io.ReadFull(in, buf); err != nil { return err } decrypter = cipher.NewCBCDecrypter(block, buf) count = (size - block.BlockSize()) / block.BlockSize() for count > 0 && err == nil { if _, err = io.ReadFull(in, buf); err == nil { decrypter.CryptBlocks(buf, buf) if count == 1 { for count = block.BlockSize() - 1; buf[count] == 0x00; count-- { continue } if buf[count] == 0x80 { buf = buf[:count] } } _, err = out.Write(buf) } count-- } if err == io.EOF { return nil } return err }
func (eng *Engine) serverHandle(connidx uint64, conn *net.TCPConn) { var blockEncrypt, blockDecrypt cipher.BlockMode // BUG: handle eat up CPUs, and main goroutine is hungry // waiting for start signal <-eng.workswitch aesblock, err := aes.NewCipher(eng.aeskey) if err != nil { panic(err.Error()) } blockDecrypt = cipher.NewCBCDecrypter(aesblock, eng.ivbuf) if eng.conf.twoway { blockEncrypt = cipher.NewCBCEncrypter(aesblock, eng.ivbuf) } // read from peer until error for eng.closing == false { if eng.conf.QPSLimit > 0 { <-eng.qpschannel } // work load atomic.AddInt64(eng.rwCount, 1) // read request _, err = conn.Read(eng.dummyBuf) if err != nil { // when peer closed, got EOF. break } blockDecrypt.CryptBlocks(eng.dummyBuf, eng.dummyBuf) if eng.conf.twoway { blockEncrypt.CryptBlocks(eng.dummyBuf, eng.dummyBuf) // write response _, err = conn.Write(eng.dummyBuf) if err != nil { break } } } // conn.Close() conn = nil // if eng.conf.nomap == false { eng.maxLock.Lock() delete(eng.conns, connidx) eng.maxLock.Unlock() } atomic.AddInt64(eng.aliveCount, -1) }
func clientDecryptUnpadDecode(ciphertext []byte, engine cipher.BlockMode) ( msg *UpaxClientMsg, err error) { plaintext := make([]byte, len(ciphertext)) engine.CryptBlocks(plaintext, ciphertext) // dest <- src unpaddedCData, err := xc.StripPKCS7Padding(plaintext, aes.BlockSize) if err == nil { msg, err = decodeClientPacket(unpaddedCData) } return }
func (c *DefaultCryptor) Encrypt(encryptor cipher.BlockMode, msg []byte) (cipherText []byte, err error) { if msg != nil { // let caller do pkcs7 padding msg = padding.PKCS7.Padding(msg, encryptor.BlockSize()) if len(msg) < encryptor.BlockSize() || len(msg)%encryptor.BlockSize() != 0 { err = ErrInputTextSize return } cipherText = msg encryptor.CryptBlocks(cipherText, msg) } return }
func (c *DefaultCryptor) Decrypt(decryptor cipher.BlockMode, cipherText []byte) (msg []byte, err error) { if decryptor != nil { if len(cipherText) < decryptor.BlockSize() || len(cipherText)%decryptor.BlockSize() != 0 { err = ErrInputTextSize return } msg = cipherText decryptor.CryptBlocks(msg, cipherText) // let caller do pkcs7 unpadding msg, err = padding.PKCS7.Unpadding(msg, decryptor.BlockSize()) } return }
func clientEncodePadEncrypt(msg *UpaxClientMsg, engine cipher.BlockMode) ( ciphertext []byte, err error) { var paddedData []byte cData, err := encodeClientPacket(msg) if err == nil { paddedData, err = xc.AddPKCS7Padding(cData, aes.BlockSize) } if err == nil { msgLen := len(paddedData) nBlocks := (msgLen + aes.BlockSize - 2) / aes.BlockSize ciphertext = make([]byte, nBlocks*aes.BlockSize) engine.CryptBlocks(ciphertext, paddedData) // dest <- src } return }
func writeField(w io.Writer, engine cipher.BlockMode, hmacEngine hash.Hash, ftype uint8, fdata []byte) error { if len(fdata) < 1 { return nil } type field struct { Length uint32 Type uint8 Data [11]byte } var datafield field datafield.Length = uint32(len(fdata)) datafield.Type = ftype copy(datafield.Data[:], fdata) var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, &datafield) if datafield.Length > 11 { datafield.Length = datafield.Length - 11 numBlocksToWrite := datafield.Length / 16 if datafield.Length%16 != 0 { numBlocksToWrite++ } blockData := make([]byte, numBlocksToWrite*16) copy(blockData, fdata[11:]) buf.Write(blockData) } bufData := buf.Bytes() blockData := make([]byte, len(bufData)) engine.CryptBlocks(blockData[:], bufData[:]) hmacEngine.Write(fdata) _, errw := w.Write(blockData) return errw }
func encrypt(block cipher.Block, in io.Reader, size int, out io.WriteCloser) error { var err error var rd int var buf []byte var last bool var encrypter cipher.BlockMode defer out.Close() buf = make([]byte, block.BlockSize()) if _, err = io.ReadFull(rand.Reader, buf); err != nil { return err } encrypter = cipher.NewCBCEncrypter(block, buf) if _, err = out.Write(buf); err != nil { return err } for !last { if rd, err = io.ReadFull(in, buf); err != nil { if err == io.ErrUnexpectedEOF || err == io.EOF { buf = buf[:rd] buf = append(buf, 0x80) for len(buf) < block.BlockSize() { buf = append(buf, 0x00) } last = true } else { return err } } encrypter.CryptBlocks(buf, buf) if _, err = out.Write(buf); err != nil { return err } } return nil }
// They are submitted as HTTP GET requests with the following fields: // // - door is the name of the door which is sending updates, // - val is 0 or 1 depending on whether the door is closed or open, // - ts is the integer timestamp in seconds since January 1, 1970, // - hash is a SHA-256 hash of all of the above, and // - iv is the initialization vector used for encrypting the hash. func (w *WriteAPI) ServeHTTP(rw http.ResponseWriter, req *http.Request) { var hashComputation = sha256.New() var secret []byte var block cipher.Block var mode cipher.BlockMode var hashdata []byte var orighash []byte var door string var val bool var ts int64 var iv []byte var ok bool var err error err = req.ParseForm() if err != nil { invalidForms.Add(1) log.Print("Error parsing form: ", err) http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } door = req.FormValue("door") if !doornameRe.MatchString(door) { invalidDoorName.Add(1) log.Print("Door name contains invalid characters: ", door) http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } val, err = strconv.ParseBool(req.FormValue("val")) if err != nil { unparseableValue.Add(1) log.Print("Error parsing ", req.FormValue("val"), " as boolean: ", err) http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } ts, err = strconv.ParseInt(req.FormValue("ts"), 10, 64) if err != nil { unparseableTimestamp.Add(1) log.Print("Error parsing ", req.FormValue("ts"), " as number: ", err) http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } hashdata, err = base64.URLEncoding.DecodeString(req.FormValue("hash")) if err != nil { unparseableHash.Add(1) log.Print("Error parsing ", req.FormValue("hash"), " as base64: ", err) http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } if len(hashdata) != sha256.Size { unparseableHash.Add(1) log.Print("Hashdata ", req.FormValue("hash"), " is not of expected length") http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } secret, ok = w.secrets[door] if !ok { unknownDoor.Add(1) log.Print("Unknown door ", door) http.Error(rw, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } block, err = aes.NewCipher(secret) if err != nil { hashVerificationFailed.Add(1) log.Print("Error creating AES cipher: ", err) http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } iv, err = hex.DecodeString(req.FormValue("iv")) if err != nil { unparseableHash.Add(1) log.Print("Error decoding IV ", req.FormValue("iv"), ": ", err) http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } if len(iv) != aes.BlockSize { unparseableHash.Add(1) log.Print("IV length is not ", aes.BlockSize) http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } mode = cipher.NewCBCDecrypter(block, iv) orighash = make([]byte, sha256.Size) mode.CryptBlocks(orighash, hashdata) _, err = io.WriteString(hashComputation, door+"\n"+req.FormValue("val")+ "\n"+req.FormValue("ts")) if err != nil { hashVerificationFailed.Add(1) log.Print("Error computing request hash: ", err) http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if !bytes.Equal(orighash, hashComputation.Sum([]byte{})) { hashVerificationFailed.Add(1) log.Print("Hash sum mismatch") http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } err = w.ts.Insert(door, time.Unix(ts, 0), val) if err != nil { insertError.Add(1) log.Print("Unable to insert timestamp: ", err) http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) } }
func cryptstream(bm cipher.BlockMode, in io.Reader, out io.Writer, enc bool) (int, os.Error) { plaintext := make([]byte, aes.BlockSize) ciphertext := make([]byte, aes.BlockSize) total := 0 pad := 0 delayed := false for { n, err := in.Read(plaintext) if err == os.EOF { if n == 0 { break } } else if err != nil { return total, err } if enc { pad = aes.BlockSize - n for i := 0; i < pad; i++ { plaintext[aes.BlockSize-i-1] = byte(pad) } } else if delayed { n, err := out.Write(ciphertext) if err != nil { return total, err } total += n } bm.CryptBlocks(ciphertext, plaintext) if enc { n, err = out.Write(ciphertext) if err != nil { return total, err } total += n } else { delayed = true } } if pad == 0 && enc { for i := 0; i < aes.BlockSize; i++ { plaintext[i] = aes.BlockSize } bm.CryptBlocks(ciphertext, plaintext) n, err := out.Write(ciphertext) if err != nil { return total, err } total += n } // last block for decryption if !enc && delayed { strip := int(ciphertext[len(ciphertext)-1]) if strip <= aes.BlockSize { ciphertext = ciphertext[0 : len(ciphertext)-strip] n, err := out.Write(ciphertext) if err != nil { return total, err } total += n } else if strip > aes.BlockSize { return total, fmt.Errorf("Decryption failed (wrong key?)") } } return total, nil }
func (eng *Engine) clientHandle(idx int, connidx uint64, conn *net.TCPConn) { var blockEncrypt, blockDecrypt cipher.BlockMode // BUG: handle eat up CPUs, and main goroutine is hungry // should we impl goroutine-grouping // BUG: blockEncrypt only, qps = 3500000, blockEncrypt + blockDecrypt, qps = 280000, more then 10x decr. // waiting for start signal <-eng.workswitch aesblock, err := aes.NewCipher(eng.aeskey) if err != nil { panic(err.Error()) } if eng.conf.twoway { blockDecrypt = cipher.NewCBCDecrypter(aesblock, eng.ivbuf) } blockEncrypt = cipher.NewCBCEncrypter(aesblock, eng.ivbuf) if eng.conf.noworkload { // read from peer until error // peer is reading too, so nothing happen for eng.closing == false { _, err = conn.Read(eng.dummyBuf) if err != nil { // when peer closed, got EOF. break } atomic.AddInt64(eng.rwCount, 1) } } else { // warite to peer until error for eng.closing == false { if eng.conf.QPSLimit > 0 { <-eng.qpschannel } // work load atomic.AddInt64(eng.rwCount, 1) blockEncrypt.CryptBlocks(eng.dummyBuf, eng.dummyBuf) // write request _, err = conn.Write(eng.dummyBuf) if err != nil { break } if eng.conf.twoway { // read respose _, err = conn.Read(eng.dummyBuf) if err != nil { // when peer closed, got EOF. break } blockDecrypt.CryptBlocks(eng.dummyBuf, eng.dummyBuf) } } } conn.Close() conn = nil eng.laddrPool[idx] <- connidx if eng.conf.nomap == false { eng.maxLock.Lock() delete(eng.conns, connidx) eng.maxLock.Unlock() } atomic.AddInt64(eng.aliveCount, -1) }
func main() { fmt.Println("visualmoo - illustrate ECB badness through images.") flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [options] <input image> <output image>\n", os.Args[0]) fmt.Fprintf(os.Stderr, "Options:\n") flag.PrintDefaults() } flag.Parse() if flag.NArg() != 2 { flag.Usage() os.Exit(1) } inputFile, outputFile := flag.Arg(0), flag.Arg(1) reader, err := os.Open(inputFile) if err != nil { log.Fatal(err) } defer reader.Close() m, _, err := image.Decode(reader) imageData := image.NewRGBA(m.Bounds()) draw.Draw(imageData, imageData.Rect, m, image.ZP, draw.Src) key := make([]byte, 16) if *fixedKey == "random" { // use a random key rand.Read(key) } else { var err error key, err = hex.DecodeString(*fixedKey) if err != nil { log.Fatal("Error decoding key from commandline: ", err) } } bc, err := aes.NewCipher(key) if err != nil { log.Fatal("Error setting up block cipher: ", err) } blockSize := bc.BlockSize() var blockMode cipher.BlockMode switch *mode { case "ECB": blockMode = NewECBEncrypter(bc) case "CBC": // Let's simply use all zero IV blockMode = cipher.NewCBCEncrypter(bc, make([]byte, blockSize)) default: log.Fatal("Error: unsupported mode-of-operation.") } numPixels := len(imageData.Pix) / 4 imageSize := numPixels * 4 if *skipAlpha { imageSize = numPixels * 3 } // Make sure the size of the input/output buffers are a multiple of the block // size nBlocks := 1 + ((imageSize - 1) / blockSize) inputBuffer := make([]byte, nBlocks*blockSize) outputBuffer := make([]byte, nBlocks*blockSize) // copy the data if *skipAlpha { // We skip the alpha channel in the RGBA data for i := 0; i < numPixels; i++ { copy(inputBuffer[i*3:i*3+3], imageData.Pix[i*4:i*4+3]) } } else { // We can simply copy the RGBA data copy(inputBuffer[:len(imageData.Pix)], imageData.Pix) } // now encrypt blockMode.CryptBlocks(outputBuffer, inputBuffer) // And copy back the data into an image if *skipAlpha { for i := 0; i < numPixels; i++ { copy(imageData.Pix[i*4:i*4+3], outputBuffer[i*3:i*3+3]) } } else { copy(imageData.Pix, outputBuffer[:len(imageData.Pix)]) } // Write this mangled image to a file writer, err := os.Create(outputFile) if err != nil { log.Fatal(err) } defer writer.Close() newImage := imageData.SubImage(imageData.Rect) png.Encode(writer, newImage) }