func (s *state) EncryptMessage(in []byte) ([]byte, error) { var ( out = bufpool.New().SetLen(lenKey + lenNonce + len(in) + box.Overhead + lenAuth) raw = out.RawBytes() agreedKey [lenKey]byte ctLen int ) if !s.CanEncryptMessage() { panic("unable to encrypt message") } // copy public senderLineKey copy(raw[:lenKey], (*s.localLineKey.pub)[:]) // copy the nonce copy(raw[lenKey:lenKey+lenNonce], s.nonce[:lenNonce]) // make the agreedKey box.Precompute(&agreedKey, s.remoteKey.pub, s.localLineKey.prv) // encrypt p ctLen = len(box.SealAfterPrecomputation(raw[lenKey+lenNonce:lenKey+lenNonce], in, s.nonce, &agreedKey)) // Sign message s.sign(raw[lenKey+lenNonce+ctLen:], s.nonce[:lenNonce], raw[:lenKey+lenNonce+ctLen]) out.SetLen(lenKey + lenNonce + ctLen + lenAuth) return out.Get(nil), nil }
func (s *state) EncryptPacket(pkt *lob.Packet) (*lob.Packet, error) { s.mtx.RLock() defer s.mtx.RUnlock() var ( outer *lob.Packet inner *bufpool.Buffer body *bufpool.Buffer bodyRaw []byte nonce [lenNonce]byte ctLen int err error ) if !s.CanEncryptPacket() { return nil, cipherset.ErrInvalidState } if pkt == nil { return nil, nil } // encode inner packet inner, err = lob.Encode(pkt) if err != nil { return nil, err } // make nonce copy(nonce[:], s.pktNoncePrefix[:]) nonceSuffix := atomic.AddUint64(&s.pktNonceSuffix, 1) binary.BigEndian.PutUint64(nonce[16:], nonceSuffix) // alloc enough space body = bufpool.New().SetLen(lenToken + lenNonce + inner.Len() + box.Overhead) bodyRaw = body.RawBytes() // copy token copy(bodyRaw[:lenToken], s.remoteToken[:]) // copy nonce copy(bodyRaw[lenToken:lenToken+lenNonce], nonce[:]) // encrypt inner packet ctLen = len(box.SealAfterPrecomputation( bodyRaw[lenToken+lenNonce:lenToken+lenNonce], inner.RawBytes(), &nonce, s.lineEncryptionKey)) body.SetLen(lenToken + lenNonce + ctLen) outer = lob.New(body.RawBytes()) inner.Free() body.Free() return outer, nil }