package sshkeys import ( `crypto/aes` `crypto/cipher` `errors` // `golang.org/x/crypto/ssh/internal/bcrypt_pbkdf` Golang doesn't let you import "internal" libs. Fine. Lame language. `github.com/dchest/bcrypt_pbkdf` ) func (k *EncryptedSSHKeyV1) setCrypt() error { // First we need the KDF (Key Derivation Function). if err := k.setKDF(); err != nil { return err } // And then we set the actual cipher (the thing that does the encrypting). if err := k.setCipher(); err != nil { return err } return nil } func (k *EncryptedSSHKeyV1) setCipher() error { switch k.CipherName { case CipherAes256Ctr: if k.Crypt.Cipher, err = aes.NewCipher(k.Crypt.PrivateKey); err != nil { return err } else { k.Crypt.Stream = cipher.NewCTR(k.Crypt.Cipher, k.Crypt.CryptSalt) // Can then be used as k.Crypt.Stream.XORKeyStream(dst []byte, src []byte) } default: return errors.New("could not find Cipher") } return nil } func (k *EncryptedSSHKeyV1) setKDF() error { // Upstream only currently supports bcrypt_pbkdf ("bcrypt"). // This should always eval to true, but is here for future planning in case other KDF are implemented. switch k.KDFName { case KdfBcrypt: if k.Crypt.CryptKey, err = bcrypt_pbkdf.Key(k.Passphrase, k.KDFOpts.Salt, int(k.KDFOpts.Rounds), kdfKeyLen + len(k.KDFOpts.Salt), ); err != nil { return err } else { k.Crypt.PrivateKey = k.Crypt.CryptKey[0:kdfSplit] k.Crypt.CryptSalt = k.Crypt.CryptKey[kdfSplit:] } default: return errors.New("could not find KDF") } }