func()

in v3/internal/aes_cbc.go [129:179]


func (reader *cbcDecryptReader) Read(data []byte) (int, error) {
	n, err := reader.src.Read(data)
	blockSize := reader.decrypter.BlockSize()
	reader.buf.Write(data[:n])

	if err == io.EOF {
		b := make([]byte, getSliceSize(blockSize, reader.buf.Len(), len(data)))
		n, err = reader.buf.Read(b)
		if err != nil && err != io.EOF {
			return n, err
		}
		// We only want to decrypt if we have read anything
		if n > 0 {
			reader.decrypter.CryptBlocks(data, b)
		}

		if reader.buf.Len() == 0 {
			b, err = reader.padder.Unpad(data[:n])
			n = len(b)
			if err != nil {
				return n, err
			}
			err = io.EOF
		}
		return n, err
	}

	if err != nil {
		return n, err
	}

	if size := reader.buf.Len(); size >= blockSize {
		nBlocks := size / blockSize
		if size > len(data) {
			nBlocks = len(data) / blockSize
		}
		// The last block is always padded. This will allow us to unpad
		// when we receive an io.EOF error
		nBlocks -= blockSize

		if nBlocks > 0 {
			b := make([]byte, nBlocks*blockSize)
			n, _ = reader.buf.Read(b)
			reader.decrypter.CryptBlocks(data, b[:n])
		} else {
			n = 0
		}
	}

	return n, nil
}