Ejemplo n.º 1
0
func (s *state) update() {

	if s.nonce == nil {
		s.nonce = new([lenNonce]byte)
		io.ReadFull(rand.Reader, s.nonce[:])
	}

	if s.pktNoncePrefix == nil {
		s.pktNoncePrefix = new([16]byte)
		io.ReadFull(rand.Reader, s.pktNoncePrefix[:])
	}

	// generate a local line Key
	if s.localLineKey == nil {
		s.localLineKey, _ = generateKey()
	}

	// generate mac key base
	if s.macKeyBase == nil && s.localKey.CanSign() && s.remoteKey.CanEncrypt() {
		s.macKeyBase = new([lenKey]byte)
		box.Precompute(s.macKeyBase, s.remoteKey.pub, s.localKey.prv)
	}

	// make local token
	if s.localToken == nil && s.localLineKey != nil {
		s.localToken = new(cipherset.Token)
		sha := sha256.Sum256((*s.localLineKey.pub)[:lenToken])
		copy((*s.localToken)[:], sha[:lenToken])
	}

	// make remote token
	if s.remoteToken == nil && s.remoteLineKey != nil {
		s.remoteToken = new(cipherset.Token)
		sha := sha256.Sum256((*s.remoteLineKey.pub)[:lenToken])
		copy((*s.remoteToken)[:], sha[:lenToken])
	}

	// generate line keys
	if s.localToken != nil && s.remoteToken != nil &&
		(s.lineEncryptionKey == nil || s.lineDecryptionKey == nil) {
		var sharedKey [lenKey]byte
		box.Precompute(&sharedKey, s.remoteLineKey.pub, s.localLineKey.prv)

		sha := sha256.New()
		s.lineEncryptionKey = new([lenKey]byte)
		sha.Write(sharedKey[:])
		sha.Write(s.localLineKey.pub[:])
		sha.Write(s.remoteLineKey.pub[:])
		sha.Sum((*s.lineEncryptionKey)[:0])

		sha.Reset()
		s.lineDecryptionKey = new([lenKey]byte)
		sha.Write(sharedKey[:])
		sha.Write(s.remoteLineKey.pub[:])
		sha.Write(s.localLineKey.pub[:])
		sha.Sum((*s.lineDecryptionKey)[:0])
	}
}
Ejemplo n.º 2
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
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
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
}