Beispiel #1
0
// Open authenticates and recovers the message secured in the box.
func Open(password, box []byte) (msg []byte, ok bool) {
	if len(box) < (secretbox.Overhead + 2*saltLength) {
		return
	}

	key, ok := recoverKey(password, box[:saltLength])
	if !ok {
		return
	}
	ok = false

	tag := keccakMac(key[:saltLength], box[:saltLength])
	if subtle.ConstantTimeCompare(tag, box[saltLength:2*saltLength]) != 1 {
		return
	}

	var sbKey [secretbox.KeySize]byte
	copy(sbKey[:], key[saltLength:])
	msg, ok = secretbox.Open(box[2*saltLength:], &sbKey)
	secretbox.Zero(sbKey[:])
	if !ok {
		msg = nil
		return
	}
	ok = true
	return
}
Beispiel #2
0
// GenerateKey returns an appropriate private and public key pair
// for securing messages.
func GenerateKey() (priv *[PrivateKeySize]byte, pub *[PublicKeySize]byte, ok bool) {
	var priv1 [32]byte
	var priv2 [32]byte
	var pub1 [32]byte
	var pub2 [32]byte

	_, err := io.ReadFull(PRNG, priv1[:])
	if err != nil {
		return
	}

	_, err = io.ReadFull(PRNG, priv2[:])
	if err != nil {
		return
	}

	h := sha3.NewKeccak384()
	h.Write(priv1[:])
	digest := h.Sum(nil)
	copy(priv1[:], digest)
	priv1[0] &= 248
	priv1[31] &= 127
	priv1[31] |= 64

	h.Reset()
	h.Write(priv2[:])
	digest = h.Sum(nil)
	copy(priv2[:], digest)
	priv2[0] &= 248
	priv2[31] &= 127
	priv2[31] |= 64

	curve25519.ScalarBaseMult(&pub1, &priv1)
	curve25519.ScalarBaseMult(&pub2, &priv2)
	priv = new([PrivateKeySize]byte)
	copy(priv[:32], priv1[:])
	copy(priv[32:], priv2[:])

	pub = new([PublicKeySize]byte)
	copy(pub[:32], pub1[:])
	copy(pub[32:], pub2[:])
	secretbox.Zero(priv1[:])
	secretbox.Zero(priv2[:])

	ok = true
	return
}
Beispiel #3
0
// SharedKey generates a secretbox key from a key exchange. Alice
// receives Bob's public key, and uses her private key in conjunction
// with Bob's public key to generate a suitable encryption key. In
// practice, Alice actually receives an ephemeral public key from
// Bob. This is handled automatically by Seal and Open, and should
// only be used by protocols or applications that use a different key
// exchange mechanism.
func SharedKey(priv *[PrivateKeySize]byte, pub *[PublicKeySize]byte) *[secretbox.KeySize]byte {
	split := splitKeys(priv, pub)
	defer secretbox.Zero(split.priv1[:])
	defer secretbox.Zero(split.priv2[:])
	sk1 := sharedKey(&split.priv1, &split.pub1)
	sk2 := sharedKey(&split.priv2, &split.pub2)
	defer secretbox.Zero(sk1[:])
	defer secretbox.Zero(sk2[:])
	h := sha3.NewKeccak384()
	h.Write(sk2[:])
	sk3 := h.Sum(nil)
	defer secretbox.Zero(sk3)

	var sk = new([secretbox.KeySize]byte)
	copy(sk[:32], sk1[:])
	copy(sk[32:], sk3)
	return sk
}
Beispiel #4
0
// Benchmark encryption of an 80-byte strongbox key.
func BenchmarkEncrypt(b *testing.B) {
	b.StopTimer()
	sbKey, ok := secretbox.GenerateKey()
	if !ok {
		fmt.Println("tkdf: failed to generate secretbox secret key.")
		b.FailNow()
	}
	bmData = make([]byte, secretbox.KeySize)
	copy(bmData, sbKey[:])
	secretbox.Zero(sbKey[:])
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		bmBox = Encrypt(testKey, bmData)
		if bmBox == nil {
			fmt.Println("tkdf: failed to encrypt benchmark")
			b.FailNow()
		}
	}
}
Beispiel #5
0
// Seal secures a message using public key cryptography. It uses
// ephemeral Curve25519 key pairs for encryption, but does not
// digitally sign the box.
func Seal(msg []byte, pub *[PublicKeySize]byte) (box []byte, ok bool) {
	epriv, epub, ok := GenerateKey()
	if !ok {
		return
	}
	sk := SharedKey(epriv, pub)
	defer secretbox.Zero(sk[:])

	sbox, ok := secretbox.Seal(msg, sk)
	if !ok {
		return
	}

	box = make([]byte, len(sbox)+PublicKeySize+3)
	box[0] = BoxVersion
	box[1] = TypeSingle
	box[2] = CipherDualCurve25519
	copy(box[3:PublicKeySize+3], epub[:])
	copy(box[3+PublicKeySize:], sbox)
	return
}
Beispiel #6
0
// Seal secures and authenticates the message using the password
// to generate a key.
func Seal(password, msg []byte) (box []byte, ok bool) {
	key, salt, ok := generateKey(password)
	if !ok {
		return
	}
	boxLength := len(msg) + secretbox.Overhead + 32 + saltLength
	box = make([]byte, boxLength)
	copy(box[:saltLength], salt)
	saltTag := keccakMac(key[:saltLength], salt)
	copy(box[saltLength:saltLength*2], saltTag)

	var sbKey [secretbox.KeySize]byte
	copy(sbKey[:], key[saltLength:])
	sbox, ok := secretbox.Seal(msg, &sbKey)
	secretbox.Zero(sbKey[:])
	if !ok {
		box = nil
		return
	}
	copy(box[2*saltLength:], sbox)
	ok = true
	return
}
Beispiel #7
0
// Zero is a wrapper around the secretbox Zero function, while zeroises
// its arguments.
func Zero(in []byte) {
	secretbox.Zero(in)
}