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 }
// 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 }