Example #1
0
// keyExchange is a convenience function that takes keys as byte slices,
// copying them into the appropriate arrays.
func keyExchange(shared *[32]byte, priv, pub []byte) {
	// Copy the private key and wipe it, as it will no longer be needed.
	var kexPriv [32]byte
	copy(kexPriv[:], priv)
	util.Zero(priv)

	var kexPub [32]byte
	copy(kexPub[:], pub)

	box.Precompute(shared, &kexPub, &kexPriv)
	util.Zero(kexPriv[:])
}
Example #2
0
// FinishKEX verifies the signed public key. If it is valid, it will
// carry out an ECDH key agreement, zeroise the private key, and store
// the shared key.
func (kex *Session) FinishKEX(signer *ecdsa.PublicKey, signed []byte) error {
	var skey signedKey
	rest, err := asn1.Unmarshal(signed, &skey)
	if err != nil {
		return err
	} else if len(rest) != 0 {
		return errors.New("eckex: trailing data in key exchange")
	}

	hashed := sha256.Sum256(skey.Public)

	if !ecdsa.Verify(signer, hashed[:], skey.R, skey.S) {
		return errors.New("eckex: verification failure")
	}

	pub, err := unpackECPKIX(skey.Public)
	if err != nil {
		return err
	}

	priv, err := x509.ParseECPrivateKey(kex.priv)
	util.Zero(kex.priv)
	if err != nil {
		return err
	}

	kex.shared, err = nistecdh.ECDH(priv, pub)
	kex.shared = kex.shared[:32]
	return err
}
Example #3
0
// deriveKey generates a new NaCl key from a passphrase and salt.
func deriveKey(pass, salt []byte) (*[secret.KeySize]byte, error) {
	var naclKey = new([secret.KeySize]byte)
	key, err := scrypt.Key(pass, salt, 1048576, 8, 1, secret.KeySize)
	if err != nil {
		return nil, err
	}

	copy(naclKey[:], key)
	util.Zero(key)
	return naclKey, nil
}
Example #4
0
// Encrypt secures a message using a passphrase.
func Encrypt(pass, message []byte) ([]byte, error) {
	salt, err := util.RandBytes(SaltSize)
	if err != nil {
		return nil, ErrEncrypt
	}

	key, err := deriveKey(pass, salt)
	if err != nil {
		return nil, ErrEncrypt
	}

	out, err := secret.Encrypt(key, message)
	util.Zero(key[:]) // Zero key immediately after
	if err != nil {
		return nil, ErrEncrypt
	}

	out = append(salt, out...)
	return out, nil
}
Example #5
0
// Decrypt recovers a message encrypted using a passphrase.
func Decrypt(pass, message []byte) ([]byte, error) {
	if len(message) < Overhead {
		log.Print("length")
		return nil, ErrDecrypt
	}

	key, err := deriveKey(pass, message[:SaltSize])
	if err != nil {
		log.Print("scrypt")
		return nil, ErrDecrypt
	}

	out, err := secret.Decrypt(key, message[SaltSize:])
	util.Zero(key[:]) // Zero key immediately after
	if err != nil {
		log.Printf("decrypt")
		return nil, ErrDecrypt
	}

	return out, nil
}
Example #6
0
// Close zeroises the keys in the session. Once a session is closed,
// the traffic that was sent over the channel can no longer be decrypted
// and any attempts at sending or receiving messages over the channel
// will fail.
func (s *Session) Close() error {
	util.Zero(s.sendKey[:])
	util.Zero(s.recvKey[:])
	return nil
}
Example #7
0
// Close zeroises any remaining key material.
func (kex *Session) Close() {
	util.Zero(kex.priv)
	util.Zero(kex.shared)
}