Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/crypto/chacha20: not compatible with OpenSSL #55095

Closed
pedroalbanese opened this issue Sep 15, 2022 · 6 comments
Closed

x/crypto/chacha20: not compatible with OpenSSL #55095

pedroalbanese opened this issue Sep 15, 2022 · 6 comments
Labels
FrozenDueToAge help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@pedroalbanese
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.15.3 windows/386

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=
set GOARCH=386
set GOBIN=
set GOCACHE=C:\Users\0wner\AppData\Local\go-build
set GOENV=C:\Users\0wner\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=386
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\0wner\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\0wner\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_386
set GCCGO=gccgo
set GO386=sse2
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=H:\PGMM\RSASigner\RSASigner\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m32 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\cygwin\tmp\go-build582847026=/tmp/go-build -gno-record-gcc-switches

What did you do?

	var iv []byte
	iv = make([]byte, 24)
	var nonce [24]byte
	if *vector != "" {
		iv, _ = hex.DecodeString(*vector)
		copy(nonce[:], iv)
	} else {
		fmt.Fprintf(os.Stderr, "IV= %x\n", nonce)
	}
	cypher, _ := chacha20.NewUnauthenticatedCipher(key1, nonce[:])
	cypher.XORKeyStream(buf[:n], buf[:n])

	if _, err := os.Stdout.Write(buf[:n]); err != nil {
		log.Fatal(err)
	}

What did you expect to see?

I expect it work like OpenSSL compatible.

What did you see instead?

Incompatibility, I cannot decrypt message encrypted with OpenSSL

Thanks in advance.

@seankhliao
Copy link
Member

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Sep 15, 2022
@pedroalbanese
Copy link
Author

I'm reporting a bug. CHACHA20 is not working properly. Look at https://github.com/pedroalbanese/rsasigner, it's almost full compatible with OpenSSL, except Chacha20.

@ianlancetaylor ianlancetaylor changed the title affected/package: x/crypto/chacha20: not compatible with OpenSSL Sep 15, 2022
@ianlancetaylor
Copy link
Contributor

Please show us a complete standalone test case that demonstrates the problem. Thanks.

@ianlancetaylor ianlancetaylor added this to the Unreleased milestone Sep 15, 2022
@ianlancetaylor ianlancetaylor added help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Sep 15, 2022
@seankhliao seankhliao added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Sep 15, 2022
@pedroalbanese
Copy link
Author

pedroalbanese commented Sep 20, 2022

Thanks for consideration.

package main
import (
	"crypto/rand"
	"encoding/hex"
	"flag"
	"fmt"
	"crypto/sha256"
	"golang.org/x/crypto/pbkdf2"
	"golang.org/x/crypto/chacha20"
	"io"
	"log"
	"os"
)

	var derive = flag.Bool("d", false, "Derive password-based key.")
	var iter = flag.Int("i", 1024, "Iterations. (for PBKDF2)")
	var key = flag.String("k", "", "128-bit key to Encrypt/Decrypt.")
	var pbkdf = flag.String("p", "", "PBKDF2.")
	var random = flag.Bool("r", false, "Generate random 128-bit cryptographic key.")
	var salt = flag.String("s", "", "Salt. (for PBKDF2)")
	var vector = flag.String("iv", "", "Initialization vector. (for symmetric encryption)")

func main() {
    flag.Parse()

        if (len(os.Args) < 2) {
	fmt.Println("Usage of",os.Args[0]+":")
        flag.PrintDefaults()
        os.Exit(1)
        }

        if *derive == true {
	keyRaw := pbkdf2.Key([]byte(*pbkdf), []byte(*salt), *iter, 32, sha256.New)
	fmt.Println(hex.EncodeToString(keyRaw))
        os.Exit(1)
	}
	
	if *random == true {
	var key []byte
	var err error
		key = make([]byte, 32)
		_, err = io.ReadFull(rand.Reader, key)
		if err != nil {
                        log.Fatal(err)
		}
		fmt.Println(hex.EncodeToString(key))
        	os.Exit(0)
	}

	var keyHex string
	var keyRaw []byte
	if *pbkdf != "" {
		keyRaw = pbkdf2.Key([]byte(*pbkdf), []byte(*salt), *iter, 32, sha256.New)
		keyHex = hex.EncodeToString(keyRaw)
	} else {
		keyHex = *key
	}
	var key []byte
	var err error
	if keyHex == "" {
		key = make([]byte, 32)
		_, err = io.ReadFull(rand.Reader, key)
		if err != nil {
                        log.Fatal(err)
		}
		fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
	} else {
		key, err = hex.DecodeString(keyHex)
		if err != nil {
                        log.Fatal(err)
		}
		if len(key) != 32 {
                        log.Fatal(err)
		}
	}
	var nonce []byte
	nonce = make([]byte, 12)
	var iv []byte
	iv = make([]byte, 24)
	if *vector != "" {
		iv, _ = hex.DecodeString(*vector)
		copy(nonce[:], iv)
	} else {
		fmt.Fprintf(os.Stderr, "IV= %x\n", nonce[:])
	}
	ciph, _ := chacha20.NewUnauthenticatedCipher(key, nonce)
	buf := make([]byte, 64*1<<10)
	var n int
	for {
		n, err = os.Stdin.Read(buf)
		if err != nil && err != io.EOF {
                        log.Fatal(err)
		}
		ciph.XORKeyStream(buf[:n], buf[:n])
		if _, err := os.Stdout.Write(buf[:n]); err != nil {
                        log.Fatal(err)
		}
		if err == io.EOF {
			break
		}
	}
        os.Exit(0)
}

But I don't understand how the nonce is composed in OpenSSL:
https://www.openssl.org/docs/man1.1.1/man3/EVP_chacha20_poly1305.html

@seankhliao
Copy link
Member

Your nonce size is incorrect. Please refer to the documentation for chacha20

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Sep 20, 2022
@pedroalbanese
Copy link
Author

Oh, I get it. Thanx very much.

@golang golang locked and limited conversation to collaborators Sep 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

4 participants