示例#1
0
文件: crypto.go 项目: rastech/dropbox
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
}
示例#2
0
// 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"
}
示例#3
0
// 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
}
示例#4
0
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
}
示例#5
0
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
}
示例#6
0
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
}
示例#7
0
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
}
示例#8
0
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
}
示例#9
0
文件: crypto.go 项目: rastech/dropbox
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
}
示例#10
0
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)
}
示例#11
0
// 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)
	}
}
示例#12
0
文件: enc.go 项目: hotei/gosteg
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
}
示例#13
0
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)
}
示例#14
0
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)
}
示例#15
0
// newCipherBlockReader returns an io.Reader that decrypts the given io.Reader using
// the provided block mode cipher.
func newCipherBlockReader(r io.Reader, mode cipher.BlockMode) io.Reader {
	cr := &cipherBlockReader{r: r, mode: mode}
	cr.outbuf = make([]byte, 0, mode.BlockSize())
	cr.inbuf = make([]byte, 0, mode.BlockSize())
	return cr
}