예제 #1
0
// XORKeyStream crypts bytes from src to dst. Src and dst may be the same slice
// but otherwise should not overlap. If len(dst) < len(src) the function panics.
func (c *Cipher) XORKeyStream(dst, src []byte) {
	length := len(src)
	if len(dst) < length {
		panic("chacha20/chacha: dst buffer is to small")
	}

	if c.off > 0 {
		n := crypto.XOR(dst, src, c.block[c.off:])
		if n == length {
			c.off += n
			return
		}
		src = src[n:]
		dst = dst[n:]
		length -= n
		c.off = 0
	}

	if length >= 64 {
		XORBlocks(dst, src, &(c.state), c.rounds)
	}

	if n := length & (^(64 - 1)); length-n > 0 {
		Core(&(c.block), &(c.state), c.rounds)

		c.off += crypto.XOR(dst[n:], src[n:], c.block[:])
	}
}
예제 #2
0
파일: cmac.go 프로젝트: enceve/crypto
func (h *macFunc) Write(msg []byte) (int, error) {
	bs := h.BlockSize()
	n := len(msg)

	if h.off > 0 {
		dif := bs - h.off
		if n > dif {
			crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg[:dif])
			msg = msg[dif:]
			h.cipher.Encrypt(h.buf, h.buf)
			h.off = 0
		} else {
			crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg)
			h.off += n
			return n, nil
		}
	}

	if length := len(msg); length > bs {
		nn := length & (^(bs - 1))
		if length == nn {
			nn -= bs
		}
		for i := 0; i < nn; i += bs {
			crypto.XOR(h.buf, h.buf, msg[i:i+bs])
			h.cipher.Encrypt(h.buf, h.buf)
		}
		msg = msg[nn:]
	}

	if length := len(msg); length > 0 {
		crypto.XOR(h.buf[h.off:], h.buf[h.off:], msg)
		h.off += length
	}

	return n, nil
}
예제 #3
0
파일: eax.go 프로젝트: enceve/crypto
// ctrCrypt encrypts the bytes in src with the CTR mode and writes
// the ciphertext into dst
func (c *eaxCipher) ctrCrypt(dst, src []byte) {
	length := len(src)
	bs := c.blockCipher.BlockSize()
	n := length & (^(length - bs))

	for i := 0; i < n; i += bs {
		j := i + bs
		c.blockCipher.Encrypt(c.block, c.ctr)
		crypto.XOR(dst[i:j], src[i:j], c.block)

		// Increment counter
		for k := len(c.ctr) - 1; k >= 0; k-- {
			c.ctr[k]++
			if c.ctr[k] != 0 {
				break
			}
		}
	}
	if n < length {
		c.blockCipher.Encrypt(c.block, c.ctr)
		crypto.XOR(dst[n:], src[n:], c.block)
	}
	// no reset of ctr needed - Seal or Open does this for us
}
예제 #4
0
파일: cmac.go 프로젝트: enceve/crypto
func (h *macFunc) Sum(b []byte) []byte {
	bs := h.cipher.BlockSize()

	// Don't change the buffer so the
	// caller can keep writing and suming.
	hash := make([]byte, bs)

	k := h.k0
	if h.off < bs {
		k = h.k1
	}
	crypto.XOR(hash, k, h.buf)
	if h.off < h.cipher.BlockSize() {
		hash[h.off] ^= 0x80
	}

	h.cipher.Encrypt(hash, hash)
	return append(b, hash...)
}
예제 #5
0
파일: hc128_ref.go 프로젝트: enceve/crypto
func (c *streamCipher) XORKeyStream(dst, src []byte) {
	length := len(src)
	if len(dst) < length {
		panic("dst buffer is to small")
	}

	if c.off > 0 {
		left := 4 - c.off
		if left > length {
			left = length
		}
		for i, v := range c.keyStream[c.off : c.off+left] {
			dst[i] = src[i] ^ v
		}
		src = src[left:]
		dst = dst[left:]
		length -= left
		c.off += left
		if c.off == 4 {
			c.off = 0
		}
	}

	n := length - (length % 4)
	for i := 0; i < n; i += 4 {
		k := genKeyStream(&(c.ctr), &(c.p), &(c.q))
		dst[i] = src[i] ^ byte(k)
		dst[i+1] = src[i+1] ^ byte(k>>8)
		dst[i+2] = src[i+2] ^ byte(k>>16)
		dst[i+3] = src[i+3] ^ byte(k>>24)
	}

	length -= n
	if length > 0 {
		k := genKeyStream(&(c.ctr), &(c.p), &(c.q))
		c.keyStream[0] = byte(k)
		c.keyStream[1] = byte(k >> 8)
		c.keyStream[2] = byte(k >> 16)
		c.keyStream[3] = byte(k >> 24)
		c.off += crypto.XOR(dst[n:], src[n:], c.keyStream[:])
	}
}
예제 #6
0
// XORKeyStream crypts bytes from src to dst using the given key, nonce and counter.
// The rounds argument specifies the number of rounds (must be even) performed for
// keystream generation. (Common values are 20, 12 or 8) Src and dst may be the same
// slice but otherwise should not overlap. If len(dst) < len(src) this function panics.
func XORKeyStream(dst, src []byte, nonce *[12]byte, key *[32]byte, counter uint32, rounds int) {
	length := len(src)
	if len(dst) < length {
		panic("chacha20/chacha: dst buffer is to small")
	}
	if rounds <= 0 || rounds%2 != 0 {
		panic("chacha20/chacha: rounds must be a multiple of 2")
	}

	var state [64]byte

	copy(state[:], constants[:])

	statePtr := (*[8]uint64)(unsafe.Pointer(&state[0]))
	keyPtr := (*[4]uint64)(unsafe.Pointer(&key[0]))

	statePtr[2] = keyPtr[0]
	statePtr[3] = keyPtr[1]
	statePtr[4] = keyPtr[2]
	statePtr[5] = keyPtr[3]

	statePtr[6] = (*(*uint64)(unsafe.Pointer(&nonce[0])) << 32) | uint64(counter)

	statePtr[7] = *(*uint64)(unsafe.Pointer(&nonce[4]))

	if length >= 64 {
		XORBlocks(dst, src, &state, rounds)
	}

	if n := length & (^(64 - 1)); length-n > 0 {
		var block [64]byte
		Core(&block, &state, rounds)

		crypto.XOR(dst[n:], src[n:], block[:])
	}
}