simplify this down

This commit is contained in:
brent s. 2023-01-08 17:31:09 -05:00
parent 8e362c72bf
commit a51f35966d
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
6 changed files with 167 additions and 3 deletions

View File

@ -23,7 +23,7 @@ I couldn't think of a better one and I wanted something notably distinct from st
* To keep code light (and thus easier to debug, audit, etc.)
* Because otherwise the module name is inaccurate
* Because OpenSSH has their own specific variant
* Which means we can handle SSH-specific functionality if needed
* Which means we can handle SSH-specific functionality if needed
* Because Golang/x/crypto has made it painfully clear that if you want something that deviates from what they think is "best practice", you need to do it yourself



View File

@ -1,8 +1,30 @@
package cc20p1305ssh

const (
// KeySize is 32, but OpenSSH generates two separate keys.
KeySize int = 32
/*
FullKeySize is 64, but OpenSSH only uses the first half for the (true) KeySize.
(Normally in ChaCha20Poly1305, the second half is used for "additional data".
OpenSSH keys do not have "additional data".)
*/
FullKeySize int = 64 // Generated by Poly1305...
KeySize int = 32 // The first 32 of which are used by ChaCha20.
// And for clarity, aliases for the above.
Poly1305KeySize int = FullKeySize
ChaCha20KeySize int = KeySize
// IvSize is 0 because OpenSSH uses a fixed internal constant (see IV).
IvSize int = 0
// NonceSize is literally the only reason I need to do this. The only reason.
NonceSize int = 16
// TagLen is the length of the Poly1305 tag.
TagLen int = 16
)

var (
// iv is the constant fixed IV.
iv []byte = []byte{
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
}
)

6
go.mod
View File

@ -1,3 +1,9 @@
module r00t2.io/cc20p1305ssh

go 1.18

require (
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a
)

6
go.sum
View File

@ -0,0 +1,6 @@
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a h1:saTgr5tMLFnmy/yg3qDTft4rE5DY2uJ/cCxCe3q0XTU=
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a/go.mod h1:Bw9BbhOJVNR+t0jCqx2GC6zv0TGBsShs56Y3gfSCvl0=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

3
notes Normal file
View File

@ -0,0 +1,3 @@
= KEY SIZES =
In ChaCha20Poly1305, a key size of 32 bytes is needed.
In OpenSSH, the KDF is used to generate a 64 byte key, and the first half is used.

127
testbin/main.go Normal file
View File

@ -0,0 +1,127 @@
package main

import (
`bytes`
`crypto/cipher`
`fmt`
`log`

`github.com/dchest/bcrypt_pbkdf`
`golang.org/x/crypto/chacha20poly1305`
)

var (
EncryptedBlob []byte = []byte{
0x21, 0xca, 0x93, 0x7d, 0x6b, 0x81, 0x5c, 0x67,
0x66, 0xc3, 0xd6, 0xa, 0xcc, 0x3a, 0xc7, 0x2d,
0x7f, 0xf7, 0xae, 0x6a, 0x41, 0x85, 0x18, 0xad,
0x37, 0x65, 0xfa, 0x8e, 0xb, 0x3b, 0x61, 0x72,
0x70, 0xaa, 0xc5, 0x0, 0xf4, 0x43, 0xb8, 0x21,
0xe6, 0x14, 0xe5, 0x7e, 0x81, 0x1f, 0x81, 0xe9,
0x66, 0xa1, 0xd0, 0x44, 0x72, 0xca, 0xaf, 0xe7,
0xbf, 0x6e, 0x95, 0x6f, 0xb3, 0x28, 0x3f, 0x92,
0x8f, 0xc, 0x61, 0xc9, 0x39, 0x69, 0x1, 0xd5,
0xe1, 0x43, 0x9b, 0xfe, 0x37, 0x7b, 0x4f, 0x9d,
0xe0, 0x73, 0x33, 0x5c, 0xc9, 0x24, 0x7, 0x9c,
0x5a, 0x96, 0x72, 0xb0, 0xe7, 0x36, 0x98, 0xc6,
0xa, 0x63, 0x9b, 0xda, 0xf0, 0x4f, 0xa, 0x74,
0xda, 0x77, 0xec, 0x8f, 0xc7, 0xdc, 0xe8, 0xa2,
0x62, 0x5c, 0x19, 0x6b, 0x83, 0x41, 0xa4, 0x71,
0x9f, 0x46, 0x78, 0x92, 0x64, 0x14, 0xc6, 0x63,
0x41, 0x91, 0x4c, 0xe9, 0xc0, 0x9f, 0x4d, 0x33,
0xb, 0x63, 0x1d, 0x96, 0x52, 0xa4, 0x68, 0x4a,
0x4e, 0x13, 0xbd, 0xff, 0x64, 0x8a, 0xa7, 0xb6,
}
UnknownData []byte = []byte{
0x9a, 0xa8, 0xaa, 0xa3,
0x73, 0x64, 0xb3, 0xaa,
0x78, 0x25, 0x23, 0x48,
0x7e, 0x79, 0x57, 0xab,
}
CombinedEncrypted = append(EncryptedBlob, UnknownData...)

// PLAIN
PrivKey []byte = []byte{
0xb9, 0x9a, 0xf2, 0xcb, 0x1e, 0xb3, 0x8c, 0xff,
0xdf, 0x76, 0x31, 0x22, 0x72, 0x56, 0xda, 0xf,
0xe3, 0xd1, 0xdb, 0x5a, 0xff, 0xea, 0x2e, 0x44,
0xc8, 0x5, 0x8d, 0xcc, 0xe0, 0x21, 0xae, 0x7e,
}
PubKey []byte = []byte{
0x9c, 0xf1, 0x14, 0x2f, 0xbb, 0x71, 0xac, 0xeb,
0xf3, 0xae, 0xa8, 0xd8, 0x9c, 0x51, 0x8c, 0x3,
0xa6, 0xd3, 0x66, 0x59, 0x4c, 0xee, 0xc5, 0x77,
0x4c, 0x4f, 0xf4, 0x7d, 0x57, 0xba, 0x26, 0x75,
}
EdKey []byte = append(PrivKey, PubKey...)
)

func main() {

var err error
var c cipher.AEAD
var kdfSalt []byte = []byte{
0xfa, 0x99, 0x09, 0xfd,
0xa2, 0xf5, 0xad, 0x42,
0xd2, 0x8e, 0x21, 0xe3,
0xb1, 0xcc, 0x6c, 0x94,
}
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.chacha20poly1305
// https://rus-cert.github.io/ssh-chacha20-poly1305-drafts/ssh-chacha20-poly1305@openssh.html
// https://datatracker.ietf.org/doc/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
// https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305
// var kdfKeyLen int = 512 / 8 // uses fixed 256 bits for chacha key, but it generates two keys...?
// var kdfKeyLen int = 256 // uses fixed 256 bits for chacha key
// var kdfKeyLen int = 32 // per golang pkg docs, 32 bytes (128 bits)...
var kdfKeyLen int = 64 // but per OpenSSH, 64
// var ivLen int = 0 // ??? per golang pkg docs, 12 bytes. per ssh package, though, 8(? or 0? seems to actually be 0). but needs 16 from...somewhere.
var ivLen int = 16
var kdfKey []byte
var subkey1, subkey2 []byte
var key []byte
var iv []byte
var nonce []byte
var plain []byte

if kdfKey, err = bcrypt_pbkdf.Key([]byte("testpassword"), kdfSalt, 16, kdfKeyLen+ivLen); err != nil {
log.Panicln(err)
}
key = kdfKey[0:kdfKeyLen]
iv = kdfKey[kdfKeyLen:(kdfKeyLen + ivLen)]
subkey1 = kdfKey[0:32]
subkey2 = kdfKey[32:]
// iv = subkey2[0:12]
nonce = []byte{
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
}

fmt.Printf("kdf key (%d bytes): %#v\n", len(key), key)
fmt.Printf("kdf iv (%d bytes): %#v\n\n", len(iv), iv)

// if c, err = chacha20poly1305.New(key); err != nil {
if c, err = chacha20poly1305.New(subkey1); err != nil {
// if c, err = chacha20poly1305.New(subkey2); err != nil {
log.Panicln(err)
}
fmt.Printf("nonce size: %d\n", c.NonceSize())

plain = make([]byte, len(EncryptedBlob))
// if plain, err = c.Open(plain, iv, EncryptedBlob, UnknownData); err != nil {
// if plain, err = c.Open(plain, iv, CombinedEncrypted, nil); err != nil {
if plain, err = c.Open(plain, nonce, EncryptedBlob, nil); err != nil {
log.Panicln(err)
}

// fmt.Printf("%#v\n", c)

fmt.Printf("Decrypted:\n%#v\n", plain)
if bytes.Compare(plain, EdKey) != 0 {
fmt.Printf("\nOriginal:\n%#v\n", EdKey)
}

_ = subkey1
_ = subkey2
}