X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fnncp%2Feblob.go;h=36b9d1f3c84fb1f0f3238ea9daa21f5e5d527520;hb=dd92823db3d72fb21a4c712a7fb052dce16443dd;hp=b25f5ab208dd9269848c42dad5d06a9c2175f1d0;hpb=b711e2e5767124b1d12fd548ad9605d77c0edbb6;p=nncp.git diff --git a/src/cypherpunks.ru/nncp/eblob.go b/src/cypherpunks.ru/nncp/eblob.go index b25f5ab..36b9d1f 100644 --- a/src/cypherpunks.ru/nncp/eblob.go +++ b/src/cypherpunks.ru/nncp/eblob.go @@ -1,11 +1,10 @@ /* NNCP -- Node to Node copy, utilities for store-and-forward data exchange -Copyright (C) 2016-2018 Sergey Matveev +Copyright (C) 2016-2019 Sergey Matveev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -21,15 +20,12 @@ package nncp import ( "bytes" "crypto/rand" - "crypto/subtle" - "errors" "hash" - "io" - "chacha20" "cypherpunks.ru/balloon" "github.com/davecgh/go-xdr/xdr2" "golang.org/x/crypto/blake2b" + "golang.org/x/crypto/chacha20poly1305" ) const ( @@ -39,7 +35,7 @@ const ( ) var ( - MagicNNCPBv2 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'B', 0, 0, 2} + MagicNNCPBv3 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'B', 0, 0, 3} ) type EBlob struct { @@ -49,7 +45,6 @@ type EBlob struct { PCost uint32 Salt *[32]byte Blob []byte - MAC *[blake2b.Size256]byte } func blake256() hash.Hash { @@ -69,46 +64,31 @@ func NewEBlob(sCost, tCost, pCost int, password, data []byte) ([]byte, error) { if _, err = rand.Read(salt[:]); err != nil { return nil, err } - key := balloon.H(blake256, password, salt[:], sCost, tCost, pCost) - kdf, err := blake2b.NewXOF(32+64, key) - if err != nil { - return nil, err - } - if _, err = kdf.Write(MagicNNCPBv2[:]); err != nil { - return nil, err - } - keyEnc := new([32]byte) - if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil { - return nil, err - } - keyAuth := make([]byte, 64) - if _, err = io.ReadFull(kdf, keyAuth); err != nil { - return nil, err - } - mac, err := blake2b.New256(keyAuth) - if err != nil { - return nil, err - } - chacha20.XORKeyStream(data, data, new([16]byte), keyEnc) - if _, err = mac.Write(data); err != nil { - return nil, err - } - macTag := new([blake2b.Size256]byte) - mac.Sum(macTag[:0]) eblob := EBlob{ - Magic: MagicNNCPBv2, + Magic: MagicNNCPBv3, SCost: uint32(sCost), TCost: uint32(tCost), PCost: uint32(pCost), Salt: salt, - Blob: data, - MAC: macTag, + Blob: nil, } - var eblobRaw bytes.Buffer - if _, err = xdr.Marshal(&eblobRaw, &eblob); err != nil { + var eblobBuf bytes.Buffer + if _, err = xdr.Marshal(&eblobBuf, &eblob); err != nil { return nil, err } - return eblobRaw.Bytes(), nil + key := balloon.H(blake256, password, salt[:], sCost, tCost, pCost) + aead, err := chacha20poly1305.New(key) + if err != nil { + return nil, err + } + buf := make([]byte, 0, len(data)+aead.Overhead()) + buf = aead.Seal(buf, make([]byte, aead.NonceSize()), data, eblobBuf.Bytes()) + eblob.Blob = buf + eblobBuf.Reset() + if _, err = xdr.Marshal(&eblobBuf, &eblob); err != nil { + return nil, err + } + return eblobBuf.Bytes(), nil } func DeEBlob(eblobRaw, password []byte) ([]byte, error) { @@ -117,7 +97,7 @@ func DeEBlob(eblobRaw, password []byte) ([]byte, error) { if _, err = xdr.Unmarshal(bytes.NewReader(eblobRaw), &eblob); err != nil { return nil, err } - if eblob.Magic != MagicNNCPBv2 { + if eblob.Magic != MagicNNCPBv3 { return nil, BadMagic } key := balloon.H( @@ -128,31 +108,25 @@ func DeEBlob(eblobRaw, password []byte) ([]byte, error) { int(eblob.TCost), int(eblob.PCost), ) - kdf, err := blake2b.NewXOF(32+64, key) + aead, err := chacha20poly1305.New(key) if err != nil { return nil, err } - if _, err = kdf.Write(MagicNNCPBv2[:]); err != nil { - return nil, err - } - keyEnc := new([32]byte) - if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil { - return nil, err - } - keyAuth := make([]byte, 64) - if _, err = io.ReadFull(kdf, keyAuth); err != nil { + + ciphertext := eblob.Blob + eblob.Blob = nil + var eblobBuf bytes.Buffer + if _, err = xdr.Marshal(&eblobBuf, &eblob); err != nil { return nil, err } - mac, err := blake2b.New256(keyAuth) + data, err := aead.Open( + ciphertext[:0], + make([]byte, aead.NonceSize()), + ciphertext, + eblobBuf.Bytes(), + ) if err != nil { return nil, err } - if _, err = mac.Write(eblob.Blob); err != nil { - return nil, err - } - if subtle.ConstantTimeCompare(mac.Sum(nil), eblob.MAC[:]) != 1 { - return nil, errors.New("Unauthenticated blob") - } - chacha20.XORKeyStream(eblob.Blob, eblob.Blob, new([16]byte), keyEnc) - return eblob.Blob, nil + return data, nil }