Пример #1
0
func (c *cipher) DecryptMessage(localKey, remoteKey cipherset.Key, p []byte) ([]byte, error) {
	if len(p) < lenKey+lenNonce+lenAuth {
		return nil, cipherset.ErrInvalidMessage
	}

	var (
		ctLen            = len(p) - (lenKey + lenNonce + lenAuth)
		out              = make([]byte, ctLen)
		cs3aLocalKey, _  = localKey.(*key)
		cs3aRemoteKey, _ = remoteKey.(*key)
		mac              [lenAuth]byte
		nonce            [lenNonce]byte
		macKey           [lenKey]byte
		agreedKey        [lenKey]byte
		remoteLineKey    [lenKey]byte
		ciphertext       []byte
		ok               bool
	)

	if cs3aLocalKey == nil || cs3aRemoteKey == nil {
		return nil, cipherset.ErrInvalidState
	}

	copy(remoteLineKey[:], p[:lenKey])
	copy(nonce[:], p[lenKey:lenKey+lenNonce])
	copy(mac[:], p[lenKey+lenNonce+ctLen:])
	ciphertext = p[lenKey+lenNonce : lenKey+lenNonce+ctLen]

	{ // make macKey
		box.Precompute(&macKey, cs3aRemoteKey.pub, cs3aLocalKey.prv)

		var (
			sha = sha256.New()
		)

		sha.Write(p[lenKey : lenKey+lenNonce])
		sha.Write(macKey[:])
		sha.Sum(macKey[:0])
	}

	if !poly1305.Verify(&mac, p[:lenKey+lenNonce+ctLen], &macKey) {
		return nil, cipherset.ErrInvalidMessage
	}

	// make agreedKey
	box.Precompute(&agreedKey, &remoteLineKey, cs3aLocalKey.prv)

	// decode BODY
	out, ok = box.OpenAfterPrecomputation(out[:0], ciphertext, &nonce, &agreedKey)
	if !ok {
		return nil, cipherset.ErrInvalidMessage
	}

	return out, nil
}
Пример #2
0
func (s *state) DecryptPacket(pkt *lob.Packet) (*lob.Packet, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	if !s.CanDecryptPacket() {
		return nil, cipherset.ErrInvalidState
	}
	if pkt == nil {
		return nil, nil
	}

	if !pkt.Header().IsZero() || pkt.BodyLen() < lenToken+lenNonce {
		return nil, cipherset.ErrInvalidPacket
	}

	var (
		nonce    [lenNonce]byte
		bodyRaw  []byte
		innerRaw []byte
		innerPkt *lob.Packet
		body     = bufpool.New()
		inner    = bufpool.New()
		ok       bool
	)

	pkt.Body(body.SetLen(pkt.BodyLen()).RawBytes()[:0])
	bodyRaw = body.RawBytes()
	innerRaw = inner.RawBytes()

	// compare token
	if !bytes.Equal(bodyRaw[:lenToken], (*s.localToken)[:]) {
		inner.Free()
		body.Free()
		return nil, cipherset.ErrInvalidPacket
	}

	// copy nonce
	copy(nonce[:], bodyRaw[lenToken:lenToken+lenNonce])

	// decrypt inner packet
	innerRaw, ok = box.OpenAfterPrecomputation(
		innerRaw[:0], bodyRaw[lenToken+lenNonce:], &nonce, s.lineDecryptionKey)
	if !ok {
		inner.Free()
		body.Free()
		return nil, cipherset.ErrInvalidPacket
	}
	inner.SetLen(len(innerRaw))

	innerPkt, err := lob.Decode(inner)
	if err != nil {
		inner.Free()
		body.Free()
		return nil, err
	}

	inner.Free()
	body.Free()

	return innerPkt, nil
}
Пример #3
0
func (c *cipher) DecryptHandshake(localKey cipherset.Key, p []byte) (cipherset.Handshake, error) {
	if len(p) < lenKey+lenNonce+lenAuth {
		return nil, cipherset.ErrInvalidMessage
	}

	var (
		ctLen           = len(p) - (lenKey + lenNonce + lenAuth)
		out             = bufpool.New()
		handshake       = &handshake{}
		cs3aLocalKey, _ = localKey.(*key)
		at              uint32
		hasAt           bool
		mac             [lenAuth]byte
		nonce           [lenNonce]byte
		macKey          [lenKey]byte
		agreedKey       [lenKey]byte
		remoteKey       [lenKey]byte
		remoteLineKey   [lenKey]byte
		ciphertext      []byte
		ok              bool
	)

	if cs3aLocalKey == nil {
		return nil, cipherset.ErrInvalidState
	}

	copy(remoteLineKey[:], p[:lenKey])
	copy(nonce[:], p[lenKey:lenKey+lenNonce])
	copy(mac[:], p[lenKey+lenNonce+ctLen:])
	ciphertext = p[lenKey+lenNonce : lenKey+lenNonce+ctLen]

	// make agreedKey
	box.Precompute(&agreedKey, &remoteLineKey, cs3aLocalKey.prv)

	// decode BODY
	outBuf, ok := box.OpenAfterPrecomputation(out.RawBytes(), ciphertext, &nonce, &agreedKey)
	if !ok {
		return nil, cipherset.ErrInvalidMessage
	}
	out.SetLen(len(outBuf))

	{ // decode inner
		inner, err := lob.Decode(out)
		if err != nil {
			return nil, cipherset.ErrInvalidMessage
		}

		at, hasAt = inner.Header().GetUint32("at")
		if !hasAt {
			return nil, cipherset.ErrInvalidMessage
		}

		delete(inner.Header().Extra, "at")

		parts, err := cipherset.PartsFromHeader(inner.Header())
		if err != nil {
			return nil, cipherset.ErrInvalidMessage
		}

		if inner.BodyLen() != lenKey {
			return nil, cipherset.ErrInvalidMessage
		}
		inner.Body(remoteKey[:0])

		handshake.at = at
		handshake.key = makeKey(nil, &remoteKey)
		handshake.lineKey = makeKey(nil, &remoteLineKey)
		handshake.parts = parts
	}

	{ // make macKey
		box.Precompute(&macKey, &remoteKey, cs3aLocalKey.prv)

		var (
			sha = sha256.New()
		)

		sha.Write(p[lenKey : lenKey+lenNonce])
		sha.Write(macKey[:])
		sha.Sum(macKey[:0])
	}

	if !poly1305.Verify(&mac, p[:lenKey+lenNonce+ctLen], &macKey) {
		return nil, cipherset.ErrInvalidMessage
	}

	return handshake, nil
}