Example #1
0
func (h *Hash) Write(p []byte) (n int, err error) {
	if h.state != stateInput {
		return 0, ErrWrongState
	}

	n += buf.CopyReassemble(&h.xfer, &p)
	switch {
	case !h.xfer.FixedSizeComplete():
		// Less than a single block available to process.
		return
	case len(p) == 0:
		// We can't process the block yet, because it might or might not be the last one.
		return
	}

	// Definitely not the last block.
	h.processBlock(h.xfer[:])
	h.xfer.Reset()

	// This must be greater-than, not greater-or-equal, because we only want to process
	// non-final blocks here.
	for len(p) > blockSizeBytes {
		h.processBlock(p[:blockSizeBytes])
		p = p[blockSizeBytes:]
		n += blockSizeBytes
	}

	n += buf.CopyReassemble(&h.xfer, &p)
	return
}
Example #2
0
// Write processes new pre-decryption bytes in p, handling handshake completions and sending any usable
// plaintext that results onward.
func (ic *incoming) Write(p []byte) (n int, err error) {
	log.Debug("<   pushing %d bytes", len(p))
	n, err = 0, nil

	for len(p) > 0 {
		if ic.state == stateFailed {
			return n + len(p), err
		}

		if ic.handshakeReassembly != nil {
			n += buf.CopyReassemble(&ic.handshakeReassembly, &p)
			if ic.handshakeReassembly.FixedSizeComplete() {
				switch ic.state {
				default:
					panic("Dust/crypting: handshake reassembly in weird state")
				case stateHandshakeNoKey:
					ic.receivedEphemeralKey()
				case stateHandshakeKey:
					ic.checkConfirmation()
				}
			}
		} else {
			subn := ic.frameReassembly.TransformIn(p, ic.cipher.XORKeyStream)
			err = ic.decodeFrames(p[:subn], ic.frameReassembly.ValidLen()-subn)
			n += subn
			p = p[subn:]
		}
	}

	return n, err
}