Пример #1
1
// Chaff the data. noncePrfx is 64-bit nonce. Output data will be much
// larger: 256 bytes for each input byte.
func Chaff(authKey *[32]byte, noncePrfx, in []byte) []byte {
	out := make([]byte, len(in)*EnlargeFactor)
	keys := make([]byte, 8*64)
	nonce := make([]byte, 24)
	copy(nonce[:8], noncePrfx)
	var i int
	var v byte
	tag := new([16]byte)
	macKey := new([32]byte)
	for n, b := range in {
		binary.BigEndian.PutUint64(nonce[16:], uint64(n))
		salsa20.XORKeyStream(keys, keys, nonce, authKey)
		for i = 0; i < 8; i++ {
			v = (b >> uint8(i)) & 1
			copy(macKey[:], keys[64*i:64*i+32])
			if v == 0 {
				poly1305.Sum(tag, []byte("1"), macKey)
			} else {
				poly1305.Sum(tag, []byte("0"), macKey)
			}
			copy(out[16*(n*16+i*2):], tag[:])
			copy(macKey[:], keys[64*i+32:64*i+64])
			if v == 1 {
				poly1305.Sum(tag, []byte("1"), macKey)
			} else {
				poly1305.Sum(tag, []byte("0"), macKey)
			}
			copy(out[16*(n*16+i*2+1):], tag[:])
		}
		zero(keys)
	}
	zero(macKey[:])
	return out
}
Пример #2
0
// Winnow the data.
func Winnow(authKey *[32]byte, noncePrfx, in []byte) ([]byte, error) {
	if len(in)%EnlargeFactor != 0 {
		return nil, errors.New("Invalid data size")
	}
	out := make([]byte, len(in)/EnlargeFactor)
	keys := make([]byte, 8*64)
	nonce := make([]byte, 24)
	copy(nonce[:8], noncePrfx)
	var i int
	var v byte
	tag := new([16]byte)
	macKey := new([32]byte)
	defer zero(macKey[:])
	var is01 bool
	var is00 bool
	var is11 bool
	var is10 bool
	for n := 0; n < len(out); n++ {
		binary.BigEndian.PutUint64(nonce[16:], uint64(n))
		salsa20.XORKeyStream(keys, keys, nonce, authKey)
		v = 0
		for i = 0; i < 8; i++ {
			copy(macKey[:], keys[64*i:64*i+32])
			poly1305.Sum(tag, []byte("1"), macKey)
			is01 = subtle.ConstantTimeCompare(
				tag[:],
				in[16*(n*16+i*2):16*(n*16+i*2+1)],
			) == 1
			poly1305.Sum(tag, []byte("0"), macKey)
			is00 = subtle.ConstantTimeCompare(
				tag[:],
				in[16*(n*16+i*2):16*(n*16+i*2+1)],
			) == 1
			copy(macKey[:], keys[64*i+32:64*i+64])
			poly1305.Sum(tag, []byte("1"), macKey)
			is11 = subtle.ConstantTimeCompare(
				tag[:],
				in[16*(n*16+i*2+1):16*(n*16+i*2+2)],
			) == 1
			poly1305.Sum(tag, []byte("0"), macKey)
			is10 = subtle.ConstantTimeCompare(
				tag[:],
				in[16*(n*16+i*2+1):16*(n*16+i*2+2)],
			) == 1
			if !((is01 && is10) || (is00 && is11)) {
				zero(keys)
				return nil, errors.New("Invalid authenticator received")
			}
			if is11 {
				v = v | 1<<uint8(i)
			}
		}
		out[n] = v
		zero(keys)
	}
	return out, nil
}
Пример #3
0
func (sec *AccountSecurity) ResetPassword(kms security.KMS, password string) (*AccountSecurity, error) {
	kek := sec.SystemKey.Clone()
	if err := kms.DecryptKey(&kek); err != nil {
		return nil, fmt.Errorf("key decryption error: %s", err)
	}
	kek.IV = make([]byte, ClientKeyType.BlockSize())
	copy(kek.IV, sec.Nonce)

	clientKey := security.KeyFromPasscode([]byte(password), sec.Nonce, sec.UserKey.KeyType)
	if err := kek.Encrypt(clientKey); err != nil {
		return nil, fmt.Errorf("key encryption error: %s", err)
	}

	var (
		mac [16]byte
		key [32]byte
	)
	copy(key[:], clientKey.Plaintext)
	poly1305.Sum(&mac, sec.Nonce, &key)

	nsec := &AccountSecurity{
		Nonce:     sec.Nonce,
		MAC:       mac[:],
		SystemKey: sec.SystemKey,
		UserKey:   kek,
		KeyPair:   sec.KeyPair,
	}
	return nsec, nil
}
Пример #4
0
func (sec *AccountSecurity) ChangeClientKey(oldKey, newKey *security.ManagedKey) error {
	if oldKey.Encrypted() || newKey.Encrypted() {
		return security.ErrKeyMustBeDecrypted
	}

	// Extract decrypted UserKey and verify correctness of oldKey.
	kek, _, err := sec.unlock(oldKey)
	if err != nil {
		return err
	}

	// Encrypt new UserKey.
	if err := kek.Encrypt(newKey); err != nil {
		return err
	}

	// Update MAC and encrypted UserKey.
	var (
		mac [16]byte
		key [32]byte
	)
	copy(key[:], newKey.Plaintext)
	poly1305.Sum(&mac, sec.Nonce, &key)
	sec.MAC = mac[:]
	sec.UserKey = *kek

	return nil
}
Пример #5
0
func NewAgent(agentID []byte, accessKey *security.ManagedKey) (*Agent, error) {
	if accessKey.Encrypted() {
		return nil, security.ErrKeyMustBeDecrypted
	}

	iv := make([]byte, accessKey.KeySize())
	if _, err := rand.Read(iv); err != nil {
		return nil, err
	}

	if agentID == nil {
		agentID = make([]byte, AgentIDSize)
		if _, err := rand.Read(agentID); err != nil {
			return nil, err
		}
	}

	var (
		mac [16]byte
		key [32]byte
	)
	copy(key[:], accessKey.Plaintext)
	poly1305.Sum(&mac, iv, &key)

	agent := &Agent{
		ID:      agentID,
		IV:      iv,
		MAC:     mac[:],
		Created: time.Now(),
	}
	return agent, nil
}
Пример #6
0
Файл: pm.go Проект: logan/heim
func NewPM(kms security.KMS, client *Client, initiatorNick string, receiver UserID, receiverNick string) (
	*PM, *security.ManagedKey, error) {

	if client.Account == nil {
		return nil, nil, ErrAccessDenied
	}

	pmID, err := snowflake.New()
	if err != nil {
		return nil, nil, err
	}

	iv, err := kms.GenerateNonce(RoomMessageKeyType.BlockSize())
	if err != nil {
		return nil, nil, err
	}

	encryptedSystemKey, err := kms.GenerateEncryptedKey(RoomMessageKeyType, "pm", pmID.String())
	if err != nil {
		return nil, nil, err
	}

	pmKey := encryptedSystemKey.Clone()
	if err := kms.DecryptKey(&pmKey); err != nil {
		return nil, nil, fmt.Errorf("pm key decrypt: %s", err)
	}
	//pmKey.IV = iv

	userKey := client.Account.UserKey()
	if err := userKey.Decrypt(client.Authorization.ClientKey); err != nil {
		return nil, nil, fmt.Errorf("initiator account key decrypt: %s", err)
	}

	encryptedInitiatorKey := pmKey.Clone()
	encryptedInitiatorKey.IV = iv
	if err := encryptedInitiatorKey.Encrypt(&userKey); err != nil {
		return nil, nil, fmt.Errorf("initiator pm key encrypt: %s", err)
	}

	var (
		mac [16]byte
		key [32]byte
	)
	copy(key[:], pmKey.Plaintext)
	poly1305.Sum(&mac, []byte(receiver), &key)

	pm := &PM{
		ID:                    pmID,
		Initiator:             client.Account.ID(),
		InitiatorNick:         initiatorNick,
		Receiver:              receiver,
		ReceiverNick:          receiverNick,
		ReceiverMAC:           mac[:],
		IV:                    iv,
		EncryptedSystemKey:    encryptedSystemKey,
		EncryptedInitiatorKey: &encryptedInitiatorKey,
	}
	return pm, &pmKey, nil
}
Пример #7
0
func poly1305MAC(msg []byte, nonce []byte, key *MACKey) []byte {
	k := poly1305PrepareKey(nonce, key)

	var out [16]byte
	poly1305.Sum(&out, msg, &k)

	return out[:]
}
Пример #8
0
func handleRequest(conn net.Conn) {
	timeCookie := tool.GetTimeCookie()
	initKey := sha256.Sum256([]byte(passwd + timeCookie))
	nonce := sha512.Sum512([]byte(timeCookie + passwd))

	es, err := chacha20.NewXChaCha(initKey[:], nonce[:XNonceSize])
	ds, err := chacha20.NewXChaCha(initKey[:], nonce[:XNonceSize])
	if err != nil {
		log.Println("Error chacha20 init:  ", err)
		return
	}

	pconn, err := net.Dial("tcp", server+":"+strconv.Itoa(sport))
	if err != nil {
		log.Println("Create connection failed :", err)
		return
	}
	cconn := cipherConn.NewCipherConn(ds, es, pconn)
	defer cconn.Close()

	randomDataLen, _ := tool.ReadInt(initKey[len(initKey)-2:])
	if randomDataLen < 32767 {
		randomDataLen = randomDataLen + 2984
	}

	randomData := make([]byte, randomDataLen+poly1305.TagSize)
	randbytes.Read(randomData)

	var mac [poly1305.TagSize]byte
	poly1305.Sum(&mac, randomData[:randomDataLen], &initKey)
	copy(randomData[randomDataLen:], mac[:])

	// Start proxying
	finish := make(chan bool, 4)

	// write random data head
	_, err = cconn.Write(randomData)
	if err != nil {
		log.Println("Connection write failed :", err)
		return
	}

	go proxy(cconn, conn, finish)
	go proxy(conn, cconn, finish)

	// Wait
	select {
	case <-finish:
	}

	time.Sleep(2 * time.Second)
}
Пример #9
0
func main() {
	fmt.Println("[")

	// 5 tests
	for i := 0; i < 5; i++ {
		plaintext := make([]byte, 64)
		rand.Read(plaintext)

		key := make([]byte, 32)
		rand.Read(key)

		nonce := make([]byte, 8)
		rand.Read(nonce)

		stream, _ := chacha20.New(key[:], nonce)

		e32a := make([]byte, 32)
		var pkey [32]byte
		stream.XORKeyStream(pkey[:], e32a)

		ciphertext := make([]byte, 64)
		stream.XORKeyStream(ciphertext, plaintext)

		var tag [16]byte
		poly1305.Sum(&tag, ciphertext, &pkey)

		fmt.Printf(`	{
		key: new Buffer([
%s		]),
		nonce: new Buffer([
%s		]),
		plain: new Buffer([
%s		]),
		cipher: new Buffer([
%s		]),
		tag: new Buffer([
%s		]),
	},
`,
			hexify(key, "\t\t\t"),
			hexify(nonce, "\t\t\t"),
			hexify(plaintext, "\t\t\t"),
			hexify(ciphertext, "\t\t\t"),
			hexify(tag[:], "\t\t\t"),
		)
	}

	fmt.Println("]")
}
Пример #10
0
Файл: pm.go Проект: logan/heim
func (pm *PM) upgradeToAccountReceiver(ctx scope.Context, b Backend, kms security.KMS, client *Client) (*security.ManagedKey, error) {
	// Verify that client and receiver agent share the same account.
	_, id := pm.Receiver.Parse()
	agent, err := b.AgentTracker().Get(ctx, id)
	if err != nil {
		return nil, err
	}
	if agent.AccountID != client.Account.ID().String() {
		return nil, ErrAccessDenied
	}

	// Unlock PM and verify Receiver.
	pmKey := pm.EncryptedSystemKey.Clone()
	if err := kms.DecryptKey(&pmKey); err != nil {
		return nil, err
	}
	if err := pm.verifyKey(&pmKey); err != nil {
		return nil, err
	}

	// Re-encrypt PM key for account.
	pm.Receiver = UserID(fmt.Sprintf("account:%s", client.Account.ID()))
	var (
		mac [16]byte
		key [32]byte
	)
	copy(key[:], pmKey.Plaintext)
	poly1305.Sum(&mac, []byte(pm.Receiver), &key)
	pm.ReceiverMAC = mac[:]

	userKey := client.Account.UserKey()
	if err := userKey.Decrypt(client.Authorization.ClientKey); err != nil {
		return nil, err
	}

	encryptedReceiverKey := pmKey.Clone()
	encryptedReceiverKey.IV = pm.IV
	if err := encryptedReceiverKey.Encrypt(&userKey); err != nil {
		return nil, err
	}
	pm.EncryptedReceiverKey = &encryptedReceiverKey

	if err := pm.verifyKey(&pmKey); err != nil {
		return nil, err
	}

	return &pmKey, nil
}
Пример #11
0
// Process incoming Ethernet packet.
// ready channel is TAPListen's synchronization channel used to tell him
// that he is free to receive new packets. Encrypted and authenticated
// packets will be sent to remote Peer side immediately.
func (p *Peer) EthProcess(data []byte, ready chan struct{}) {
	p.now = time.Now()
	p.size = len(data)
	// If this heartbeat is necessary
	if p.size == 0 && !p.LastSent.Add(p.Timeout).Before(p.now) {
		return
	}
	copy(p.buf, Emptiness)
	if p.size > 0 {
		copy(p.buf[S20BS+PktSizeSize:], data)
		ready <- struct{}{}
		binary.PutUvarint(p.buf[S20BS:S20BS+PktSizeSize], uint64(p.size))
		p.BytesPayloadOut += int64(p.size)
	} else {
		p.HeartbeatSent++
	}

	p.NonceOur += 2
	copy(p.nonce, Emptiness)
	binary.PutUvarint(p.nonce, p.NonceOur)
	p.NonceCipher.Encrypt(p.nonce, p.nonce)

	salsa20.XORKeyStream(p.buf, p.buf, p.nonce, p.Key)
	copy(p.buf[S20BS-NonceSize:S20BS], p.nonce)
	copy(p.keyAuth[:], p.buf[:SSize])
	if p.NoiseEnable {
		p.frame = p.buf[S20BS-NonceSize : S20BS+MTU-NonceSize-poly1305.TagSize]
	} else {
		p.frame = p.buf[S20BS-NonceSize : S20BS+PktSizeSize+p.size]
	}
	poly1305.Sum(p.tag, p.frame, p.keyAuth)

	p.BytesOut += int64(len(p.frame) + poly1305.TagSize)
	p.FramesOut++

	if p.CPRCycle != time.Duration(0) {
		p.willSentCycle = p.LastSent.Add(p.CPRCycle)
		if p.willSentCycle.After(p.now) {
			time.Sleep(p.willSentCycle.Sub(p.now))
			p.now = p.willSentCycle
		}
	}
	p.LastSent = p.now
	p.Conn.Write(append(p.frame, p.tag[:]...))
}
Пример #12
0
// DecryptAndVerify returns the chacha20 decrypted messages.
// An error is returned when the poly1305 message authenticator (seal) could not be verified.
// Nonce should be 8 byte.
func DecryptAndVerify(key, nonce, message []byte, mac [16]byte, add []byte) ([]byte, error) {

	chacha20, err := chacha20.New(key, nonce)
	if err != nil {
		panic(err)
	}

	// poly1305 key is chacha20 over 32 zeros
	var poly1305Key [32]byte
	var chacha20KeyOut = make([]byte, 64)
	var zeros = make([]byte, 64)
	chacha20.XORKeyStream(chacha20KeyOut, zeros)
	copy(poly1305Key[:], chacha20KeyOut)

	var chacha20Out = make([]byte, len(message))
	var poly1305Out [16]byte

	// poly1305 byte order
	// - add bytes up to mod 16 (if available)
	// - message up to mod 16
	// - number of add bytes up to mod 8
	// - number of message bytes up to mod 8
	var poly1305In []byte
	if len(add) > 0 {
		poly1305In = AddBytes(poly1305In, add, 16)
	}

	poly1305In = AddBytes(poly1305In, message, 16)
	addLength := make([]byte, 8)
	msgLength := make([]byte, 8)
	binary.LittleEndian.PutUint64(addLength, uint64(len(add)))
	binary.LittleEndian.PutUint64(msgLength, uint64(len(message)))

	poly1305In = AddBytes(poly1305In, addLength, 8)
	poly1305In = AddBytes(poly1305In, msgLength, 8)

	poly1305.Sum(&poly1305Out, poly1305In, &poly1305Key)

	if poly1305.Verify(&mac, poly1305In, &poly1305Key) == false {
		return nil, errors.New("MAC not equal: " + hex.EncodeToString(poly1305Out[:]) + " != " + hex.EncodeToString(mac[:]))
	}

	chacha20.XORKeyStream(chacha20Out, message)
	return chacha20Out, nil
}
Пример #13
0
// Seal appends an encrypted and authenticated copy of message to out, which
// must not overlap message. The key and nonce pair must be unique for each
// distinct message and the output will be Overhead bytes longer than message.
func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
	var subKey [32]byte
	var counter [16]byte
	setup(&subKey, &counter, nonce, key)

	// The Poly1305 key is generated by encrypting 32 bytes of zeros. Since
	// Salsa20 works with 64-byte blocks, we also generate 32 bytes of
	// keystream as a side effect.
	var firstBlock [64]byte
	salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey)

	var poly1305Key [32]byte
	copy(poly1305Key[:], firstBlock[:])

	ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)

	// We XOR up to 32 bytes of message with the keystream generated from
	// the first block.
	firstMessageBlock := message
	if len(firstMessageBlock) > 32 {
		firstMessageBlock = firstMessageBlock[:32]
	}

	tagOut := out
	out = out[poly1305.TagSize:]
	for i, x := range firstMessageBlock {
		out[i] = firstBlock[32+i] ^ x
	}
	message = message[len(firstMessageBlock):]
	ciphertext := out
	out = out[len(firstMessageBlock):]

	// Now encrypt the rest.
	counter[8] = 1
	salsa.XORKeyStream(out, message, &counter, &subKey)

	var tag [poly1305.TagSize]byte
	poly1305.Sum(&tag, ciphertext, &poly1305Key)
	copy(tagOut, tag[:])

	return ret
}
Пример #14
0
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
	var counter [16]byte
	copy(counter[4:], nonce)

	var polyKey [32]byte
	chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)

	ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
	counter[0] = 1
	chacha20.XORKeyStream(out, plaintext, &counter, &c.key)

	polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(plaintext))+8+8)
	copy(polyInput, additionalData)
	copy(polyInput[roundTo16(len(additionalData)):], out[:len(plaintext)])
	binary.LittleEndian.PutUint64(polyInput[len(polyInput)-16:], uint64(len(additionalData)))
	binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(plaintext)))

	var tag [poly1305.TagSize]byte
	poly1305.Sum(&tag, polyInput, &polyKey)
	copy(out[len(plaintext):], tag[:])

	return ret
}
Пример #15
0
// EncryptAndSeal returns the chacha20 encrypted message and poly1305 message authentictor (also refered as seals)
// Nonce should be 8 byte
func EncryptAndSeal(key, nonce, message []byte, add []byte) ([]byte /*encrypted*/, [16]byte /*mac*/, error) {

	chacha20, err := chacha20.New(key, nonce)
	if err != nil {
		panic(err)
	}

	// poly1305 key is chacha20 over 32 zeros
	var poly1305Key [32]byte
	var chacha20KeyOut = make([]byte, 64)
	var zeros = make([]byte, 64)
	chacha20.XORKeyStream(chacha20KeyOut, zeros)
	copy(poly1305Key[:], chacha20KeyOut)

	var chacha20Out = make([]byte, len(message))
	var poly1305Out [16]byte
	chacha20.XORKeyStream(chacha20Out, message)

	var poly1305In []byte
	if len(add) > 0 {
		poly1305In = AddBytes(poly1305In, add, 16)
	}

	poly1305In = AddBytes(poly1305In, chacha20Out, 16)
	addLength := make([]byte, 8)
	msgLength := make([]byte, 8)
	binary.LittleEndian.PutUint64(addLength, uint64(len(add)))
	binary.LittleEndian.PutUint64(msgLength, uint64(len(message)))

	poly1305In = AddBytes(poly1305In, addLength, 8)
	poly1305In = AddBytes(poly1305In, msgLength, 8)

	poly1305.Sum(&poly1305Out, poly1305In, &poly1305Key)

	return chacha20Out, poly1305Out, nil
}
Пример #16
0
// Process incoming Ethernet packet.
// ready channel is TAPListen's synchronization channel used to tell him
// that he is free to receive new packets. Encrypted and authenticated
// packets will be sent to remote Peer side immediately.
func (p *Peer) EthProcess(data []byte) {
	if len(data) > p.MTU-1 { // 1 is for padding byte
		log.Println("Padded data packet size", len(data)+1, "is bigger than MTU", p.MTU, p)
		return
	}
	p.now = time.Now()
	p.BusyT.Lock()

	// Zero size is a heartbeat packet
	SliceZero(p.bufT)
	if len(data) == 0 {
		// If this heartbeat is necessary
		if !p.LastSent.Add(p.Timeout).Before(p.now) {
			p.BusyT.Unlock()
			return
		}
		p.bufT[S20BS+0] = PadByte
		p.HeartbeatSent++
	} else {
		// Copy payload to our internal buffer and we are ready to
		// accept the next one
		copy(p.bufT[S20BS:], data)
		p.bufT[S20BS+len(data)] = PadByte
		p.BytesPayloadOut += uint64(len(data))
	}

	if p.NoiseEnable && !p.Encless {
		p.frameT = p.bufT[S20BS : S20BS+p.MTU-TagSize]
	} else if p.Encless {
		p.frameT = p.bufT[S20BS : S20BS+p.MTU]
	} else {
		p.frameT = p.bufT[S20BS : S20BS+len(data)+1+NonceSize]
	}
	p.nonceOur += 2
	binary.BigEndian.PutUint64(p.frameT[len(p.frameT)-NonceSize:], p.nonceOur)
	p.NonceCipher.Encrypt(
		p.frameT[len(p.frameT)-NonceSize:],
		p.frameT[len(p.frameT)-NonceSize:],
	)
	var out []byte
	if p.Encless {
		var err error
		out, err = EnclessEncode(
			p.Key,
			p.frameT[len(p.frameT)-NonceSize:],
			p.frameT[:len(p.frameT)-NonceSize],
		)
		if err != nil {
			panic(err)
		}
		out = append(out, p.frameT[len(p.frameT)-NonceSize:]...)
	} else {
		salsa20.XORKeyStream(
			p.bufT[:S20BS+len(p.frameT)-NonceSize],
			p.bufT[:S20BS+len(p.frameT)-NonceSize],
			p.frameT[len(p.frameT)-NonceSize:],
			p.Key,
		)
		copy(p.keyAuthT[:], p.bufT[:SSize])
		poly1305.Sum(p.tagT, p.frameT, p.keyAuthT)
		atomic.AddUint64(&p.BytesOut, uint64(len(p.frameT)+TagSize))
		out = append(p.tagT[:], p.frameT...)
	}
	p.FramesOut++

	if p.CPRCycle != time.Duration(0) {
		p.willSentCycle = p.LastSent.Add(p.CPRCycle)
		if p.willSentCycle.After(p.now) {
			time.Sleep(p.willSentCycle.Sub(p.now))
			p.now = p.willSentCycle
		}
	}

	p.LastSent = p.now
	p.Conn.Write(out)
	p.BusyT.Unlock()
}
Пример #17
0
// Sum generates an authenticator for msg using a one-time key and puts the
// 16-byte result into out. Authenticating two different messages with the same
// key allows an attacker to forge messages at will.
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
	poly.Sum(out, msg, key)
}
Пример #18
0
func progd_forword(ar cmdoptS) {

	//create metadata leveldb

	dbi, err := bolt.Open(ar.out_dir+"/md", 0600, nil)

	if err != nil {
		fmt.Println(err.Error())
		os.Exit(-1)
	}
	tx, err := dbi.Begin(true)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(-1)
	}
	defer tx.Rollback()
	db, err := tx.CreateBucket([]byte("Ketv1"))

	if err != nil {
		fmt.Println(err.Error())
		os.Exit(-1)
	}

	//generate crypto nonce

	nonce, _ := GenerateRandomBytes(24)

	//store it

	err = db.Put([]byte("nonce"), nonce)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(-1)
	}

	//calc key

	keyhasher := sha3.NewShake256()

	keyhasher.Write(nonce)
	keyhasher.Write([]byte(ar.secret_key))

	xchachakey := make([]byte, 32)
	keyhasher.Read(xchachakey)

	poly1305key := make([]byte, 32)
	keyhasher.Read(poly1305key)

	//init stream

	var LimitedSizeWriteToFilei LimitedSizeWriteToFile
	LimitedSizeWriteToFilei.InitNow()
	LimitedSizeWriteToFilei.TargetPatten = ar.out_dir + "/df%X"
	if !ar.div_unitk {
		LimitedSizeWriteToFilei.BytesPerFile = int64(ar.div_at) * const_Mbyte
	} else {
		LimitedSizeWriteToFilei.BytesPerFile = int64(ar.div_at) * const_Kbyte
	}

	cryptos, err := chacha20.NewXChaCha(xchachakey, nonce)

	HashWriter := sha3.NewShake256()

	CyDWriter := io.MultiWriter(LimitedSizeWriteToFilei, HashWriter)

	Data_writer := NewEncryptedWriter(cryptos, CyDWriter)

	CompressedStream := snappy.NewWriter(Data_writer)

	TarStream := tar.NewWriter(CompressedStream)

	GenFileList(ar.in_dir)

	for id := range rfi {
		filedes, err := os.Open(ar.in_dir + "/" + rfi[id])
		if err != nil {
			fmt.Println("Failed to open file " + rfi[id] + ":" + err.Error())
		}
		filein, _ := filedes.Stat()
		hdr := &tar.Header{
			Name: rfi[id],
			Mode: 0600,
			Size: filein.Size(),
		}

		if err := TarStream.WriteHeader(hdr); err != nil {
			log.Fatalln(err)
		}

		_, err = io.Copy(TarStream, filedes)

		if err != nil {
			fmt.Println("Failed to Write file " + rfi[id] + ":" + err.Error())
		}

		filedes.Close()

	}

	if err := TarStream.Close(); err != nil {
		log.Fatalln(err)
	}

	_, _, nd := LimitedSizeWriteToFilei.Finialize()

	FileHash := make([]byte, 64)
	HashWriter.Read(FileHash)

	var poly1305sum [16]byte
	var poly1305sum_key [32]byte

	copy(poly1305sum_key[:], poly1305key)

	poly1305.Sum(&poly1305sum, FileHash, &poly1305sum_key)

	err = db.Put([]byte("poly1305sum"), poly1305sum[:])
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(-1)
	}

	bb := new(bytes.Buffer)
	binary.Write(bb, binary.LittleEndian, nd)

	err = db.Put([]byte("packagesum"), bb.Bytes())
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(-1)
	}

	//we won't use it anymore
	if err := tx.Commit(); err != nil {
		fmt.Println(err.Error())
		os.Exit(-1)
	}
	dbi.Close()

	//finially we call par2 to compute reconstruction data
	if ar.parrate != 0 {
		_, err := exec.LookPath("par2")
		if err != nil {
			fmt.Println("Unable to whereis par2, reconstruction data compute was ignored:" + err.Error())
		}

		DirIf, _ := os.Open(ar.out_dir)
		DirIfs, _ := DirIf.Readdirnames(-1)

		cmdargs := []string{"c", "-a", "mdpp", "-r" + strconv.Itoa(ar.parrate), "-v", "--"}
		cmdargs = append(cmdargs, DirIfs...)

		cmd := exec.Command("par2", cmdargs...)
		cmd.Stdout = os.Stdout
		Absp, _ := filepath.Abs(ar.out_dir)
		cmd.Dir = Absp
		err = cmd.Start()
		if err != nil {
			fmt.Println("Unable to exec par2, reconstruction data compute was ignored:" + err.Error())
		}
		err = cmd.Wait()
		if err != nil {
			fmt.Println("par2 was finished unsuccessfully, reconstruction data compute was ignored(or failed):" + err.Error())
		}
	}

	fmt.Printf("Hash: %x\n", FileHash)
	fmt.Printf("Key: %s\n", ar.secret_key)

}
Пример #19
0
func NewRoomSecurity(kms security.KMS, roomName string) (*RoomSecurity, error) {
	kpType := security.Curve25519

	// Use one KMS request to obtain all the randomness we need:
	//   - key-encrypting-key IV
	//   - private key for grants to accounts
	//   - nonce for manager grants to accounts
	randomData, err := kms.GenerateNonce(
		RoomManagerKeyType.BlockSize() + kpType.PrivateKeySize() + kpType.NonceSize())
	if err != nil {
		return nil, fmt.Errorf("rng error: %s", err)
	}
	randomReader := bytes.NewReader(randomData)

	// Generate IV with random data.
	iv := make([]byte, RoomManagerKeyType.BlockSize())
	if _, err := io.ReadFull(randomReader, iv); err != nil {
		return nil, fmt.Errorf("rng error: %s", err)
	}

	// Generate private key using randomReader.
	keyPair, err := kpType.Generate(randomReader)
	if err != nil {
		return nil, fmt.Errorf("keypair generation error: %s", err)
	}

	// Generate nonce with random data.
	nonce := make([]byte, kpType.NonceSize())
	if _, err := io.ReadFull(randomReader, nonce); err != nil {
		return nil, fmt.Errorf("rng error: %s", err)
	}

	// Generate key-encrypting-key. This will be returned encrypted, using the
	// name of the room as its context.
	encryptedKek, err := kms.GenerateEncryptedKey(RoomManagerKeyType, "room", roomName)
	if err != nil {
		return nil, fmt.Errorf("key generation error: %s", err)
	}

	// Decrypt key-encrypting-key so we can encrypt keypair.
	kek := encryptedKek.Clone()
	if err = kms.DecryptKey(&kek); err != nil {
		return nil, fmt.Errorf("key decryption error: %s", err)
	}

	// Encrypt private key.
	keyPair.IV = iv
	if err = keyPair.Encrypt(&kek); err != nil {
		return nil, fmt.Errorf("keypair encryption error: %s", err)
	}

	// Generate message authentication code, for verifying a given key-encryption-key.
	var (
		mac [16]byte
		key [32]byte
	)
	copy(key[:], kek.Plaintext)
	poly1305.Sum(&mac, iv, &key)

	sec := &RoomSecurity{
		Nonce:            nonce,
		MAC:              mac[:],
		KeyEncryptingKey: *encryptedKek,
		KeyPair:          *keyPair,
	}
	return sec, nil
}
Пример #20
0
// Process incoming Ethernet packet.
// ready channel is TAPListen's synchronization channel used to tell him
// that he is free to receive new packets. Encrypted and authenticated
// packets will be sent to remote Peer side immediately.
func (p *Peer) EthProcess(data []byte) {
	p.now = time.Now()
	p.BusyT.Lock()

	// Zero size is a heartbeat packet
	if len(data) == 0 {
		// If this heartbeat is necessary
		if !p.LastSent.Add(p.Timeout).Before(p.now) {
			p.BusyT.Unlock()
			return
		}
		p.bufT[S20BS+0] = byte(0)
		p.bufT[S20BS+1] = byte(0)
		p.HeartbeatSent++
	} else {
		// Copy payload to our internal buffer and we are ready to
		// accept the next one
		binary.BigEndian.PutUint16(
			p.bufT[S20BS:S20BS+PktSizeSize],
			uint16(len(data)),
		)
		copy(p.bufT[S20BS+PktSizeSize:], data)
		p.BytesPayloadOut += int64(len(data))
	}

	if p.NoiseEnable {
		p.frameT = p.bufT[S20BS : S20BS+MTU-TagSize]
	} else {
		p.frameT = p.bufT[S20BS : S20BS+PktSizeSize+len(data)+NonceSize]
	}
	p.nonceOur += 2
	binary.BigEndian.PutUint64(p.frameT[len(p.frameT)-NonceSize:], p.nonceOur)
	p.NonceCipher.Encrypt(
		p.frameT[len(p.frameT)-NonceSize:],
		p.frameT[len(p.frameT)-NonceSize:],
	)
	for i := 0; i < SSize; i++ {
		p.bufT[i] = byte(0)
	}
	salsa20.XORKeyStream(
		p.bufT[:S20BS+len(p.frameT)-NonceSize],
		p.bufT[:S20BS+len(p.frameT)-NonceSize],
		p.frameT[len(p.frameT)-NonceSize:],
		p.Key,
	)

	copy(p.keyAuthT[:], p.bufT[:SSize])
	poly1305.Sum(p.tagT, p.frameT, p.keyAuthT)

	atomic.AddInt64(&p.BytesOut, int64(len(p.frameT)+TagSize))
	p.FramesOut++

	if p.CPRCycle != time.Duration(0) {
		p.willSentCycle = p.LastSent.Add(p.CPRCycle)
		if p.willSentCycle.After(p.now) {
			time.Sleep(p.willSentCycle.Sub(p.now))
			p.now = p.willSentCycle
		}
	}

	p.LastSent = p.now
	p.Conn.Write(append(p.tagT[:], p.frameT...))
	p.BusyT.Unlock()
}
Пример #21
0
// NewAccountSecurity initializes the nonce and account secrets for a new account
// with the given password. Returns an encrypted key-encrypting-key, encrypted
// key-pair, nonce, and error.
func NewAccountSecurity(
	kms security.KMS, password string) (*AccountSecurity, *security.ManagedKey, error) {

	kpType := security.Curve25519

	// Use one KMS request to obtain all the randomness we need:
	//   - nonce
	//   - private key
	randomData, err := kms.GenerateNonce(kpType.NonceSize() + kpType.PrivateKeySize())
	if err != nil {
		return nil, nil, fmt.Errorf("rng error: %s", err)
	}
	randomReader := bytes.NewReader(randomData)

	// Generate nonce with random data. Use to populate IV.
	nonce := make([]byte, kpType.NonceSize())
	if _, err := io.ReadFull(randomReader, nonce); err != nil {
		return nil, nil, fmt.Errorf("rng error: %s", err)
	}
	iv := make([]byte, ClientKeyType.BlockSize())
	copy(iv, nonce)

	// Generate key-encrypting-key using KMS. This will be returned encrypted,
	// using the base64 encoding of the nonce as its context.
	nonceBase64 := base64.URLEncoding.EncodeToString(nonce)
	systemKey, err := kms.GenerateEncryptedKey(ClientKeyType, "nonce", nonceBase64)
	if err != nil {
		return nil, nil, fmt.Errorf("key generation error: %s", err)
	}

	// Generate private key using randomReader.
	keyPair, err := kpType.Generate(randomReader)
	if err != nil {
		return nil, nil, fmt.Errorf("keypair generation error: %s", err)
	}

	// Decrypt key-encrypting-key so we can encrypt keypair, and so we can re-encrypt
	// it using the user's key.
	kek := systemKey.Clone()
	if err = kms.DecryptKey(&kek); err != nil {
		return nil, nil, fmt.Errorf("key decryption error: %s", err)
	}

	// Encrypt private key.
	keyPair.IV = iv
	if err = keyPair.Encrypt(&kek); err != nil {
		return nil, nil, fmt.Errorf("keypair encryption error: %s", err)
	}

	// Clone key-encrypting-key and encrypt with client key.
	clientKey := security.KeyFromPasscode([]byte(password), nonce, ClientKeyType)
	userKey := kek.Clone()
	userKey.IV = iv
	if err := userKey.Encrypt(clientKey); err != nil {
		return nil, nil, fmt.Errorf("key encryption error: %s", err)
	}

	// Generate message authentication code, for verifying passwords.
	var (
		mac [16]byte
		key [32]byte
	)
	copy(key[:], clientKey.Plaintext)
	poly1305.Sum(&mac, nonce, &key)

	sec := &AccountSecurity{
		Nonce:     nonce,
		MAC:       mac[:],
		SystemKey: *systemKey,
		UserKey:   userKey,
		KeyPair:   *keyPair,
	}
	return sec, clientKey, nil
}