// 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 }
// 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 }
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 }
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 }
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 }
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 }
func poly1305MAC(msg []byte, nonce []byte, key *MACKey) []byte { k := poly1305PrepareKey(nonce, key) var out [16]byte poly1305.Sum(&out, msg, &k) return out[:] }
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) }
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("]") }
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 }
// 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[:]...)) }
// 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 }
// 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 }
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 }
// 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 }
// 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() }
// 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) }
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) }
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 }
// 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() }
// 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 }