Advertisement
Guest User

Untitled

a guest
Feb 27th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.53 KB | None | 0 0
  1. // Package goenc contains functions for working with encryption
  2. package goenc
  3.  
  4. // work is derived from many sources:
  5. //
  6. // http://stackoverflow.com/questions/21151714/go-generate-an-ssh-public-key
  7. // https://golang.org/pkg/crypto/cipher/
  8. // https://leanpub.com/gocrypto/read#leanpub-auto-aes-cbc
  9. // https://github.com/hashicorp/memberlist/blob/master/security.go
  10.  
  11. import (
  12. "crypto/rand"
  13. "encoding/binary"
  14. "io"
  15.  
  16. "io/ioutil"
  17.  
  18. "os"
  19.  
  20. "github.com/alistanis/goenc/aes/cbc"
  21. "github.com/alistanis/goenc/aes/cfb"
  22. "github.com/alistanis/goenc/aes/ctr"
  23. "github.com/alistanis/goenc/aes/gcm"
  24. "github.com/alistanis/goenc/encerrors"
  25. "github.com/alistanis/goenc/generate"
  26. "github.com/alistanis/goenc/nacl"
  27. "golang.org/x/crypto/nacl/box"
  28. "golang.org/x/crypto/nacl/secretbox"
  29. "golang.org/x/crypto/scrypt"
  30. )
  31.  
  32. /*
  33. TODO(cmc): Verify this isn't horrifically insecure and have this reviewed by a(n) expert(s) before publishing
  34. */
  35.  
  36. // BlockCipher represents a cipher that encodes and decodes chunks of data at a time
  37. type BlockCipher interface {
  38. Encrypt(key, plaintext []byte) ([]byte, error)
  39. Decrypt(key, ciphertext []byte) ([]byte, error)
  40. KeySize() int
  41. }
  42.  
  43. //---------------------------------------------------------------------------
  44. // BlockCipherInterface Functions - these should not be used with large files
  45. //--------------------------------------------------------------------------------
  46.  
  47. // EncryptAndSaveWithPerms encrypts data and saves it to a file with the given permissions using the given key
  48. func EncryptAndSaveWithPerms(cipher BlockCipher, key, plaintext []byte, path string, perm os.FileMode) error {
  49. data, err := cipher.Encrypt(key, plaintext)
  50. if err != nil {
  51. return err
  52. }
  53. return ioutil.WriteFile(path, data, perm)
  54. }
  55.  
  56. // EncryptAndSave encrypts data and saves it to a file with the permissions 0644
  57. func EncryptAndSave(cipher BlockCipher, key, plaintext []byte, path string) error {
  58. return EncryptAndSaveWithPerms(cipher, key, plaintext, path, 0644)
  59. }
  60.  
  61. // ReadEncryptedFile reads a file a path and attempts to decrypt the data there with the given key
  62. func ReadEncryptedFile(cipher BlockCipher, key []byte, path string) ([]byte, error) {
  63. ciphertext, err := ioutil.ReadFile(path)
  64. if err != nil {
  65. return nil, err
  66. }
  67. plaintext, err := cipher.Decrypt(key, ciphertext)
  68. return plaintext, err
  69. }
  70.  
  71. // CipherKind represents what kind of cipher to use
  72. type CipherKind int
  73.  
  74. // CipherKind constants
  75. const (
  76. CBC CipherKind = iota
  77. CFB
  78. CTR
  79. GCM
  80. NaCL
  81.  
  82. Mock
  83. )
  84.  
  85. const (
  86. // SaltSize sets a generic salt size
  87. SaltSize = 64
  88. )
  89.  
  90. // Cipher is a struct that contains a BlockCipher interface and stores a DerivedKey Complexity number
  91. type Cipher struct {
  92. BlockCipher
  93. DerivedKeyN int
  94. }
  95.  
  96. // NewCipher returns a new Cipher containing a BlockCipher interface based on the CipherKind
  97. func NewCipher(kind CipherKind, derivedKeyN int, args ...[]byte) (*Cipher, error) {
  98. c := &Cipher{DerivedKeyN: derivedKeyN}
  99. switch kind {
  100. case GCM:
  101. c.BlockCipher = gcm.New()
  102. case NaCL:
  103. // special case, we need to define a pad for nacl
  104. if len(args) == 0 {
  105. return nil, encerrors.ErrNoPadProvided
  106. }
  107. n := &nacl.Cipher{}
  108. n.Pad = args[0]
  109. c.BlockCipher = n
  110. case CFB:
  111. c.BlockCipher = cfb.New()
  112. case CBC:
  113. c.BlockCipher = cbc.New()
  114. case CTR:
  115. c.BlockCipher = ctr.New()
  116. case Mock:
  117. c.BlockCipher = &MockBlockCipher{}
  118. default:
  119. return nil, encerrors.ErrInvalidCipherKind
  120. }
  121. return c, nil
  122. }
  123.  
  124. // Encrypt takes a password, plaintext, and derives a key based on that password,
  125. // then encrypting that data with the underlying block cipher
  126. func (c *Cipher) Encrypt(password, plaintext []byte) ([]byte, error) {
  127. salt, err := generate.RandBytes(SaltSize)
  128. if err != nil {
  129. return nil, err
  130. }
  131.  
  132. key, err := DeriveKey(password, salt, c.DerivedKeyN, c.BlockCipher.KeySize())
  133. if err != nil {
  134. return nil, err
  135. }
  136.  
  137. out, err := c.BlockCipher.Encrypt(key, plaintext)
  138. Zero(key)
  139. if err != nil {
  140. return nil, err
  141. }
  142.  
  143. out = append(salt, out...)
  144. return out, nil
  145. }
  146.  
  147. // Overhead is the amount of Overhead contained in the ciphertext
  148. const Overhead = SaltSize + secretbox.Overhead + generate.NonceSize
  149.  
  150. // Decrypt takes a password and ciphertext, derives a key, and attempts to decrypt that data
  151. func (c *Cipher) Decrypt(password, ciphertext []byte) ([]byte, error) {
  152. if len(ciphertext) < Overhead {
  153. return nil, encerrors.ErrInvalidMessageLength
  154. }
  155.  
  156. key, err := DeriveKey(password, ciphertext[:SaltSize], c.DerivedKeyN, c.KeySize())
  157. if err != nil {
  158. return nil, err
  159. }
  160.  
  161. out, err := c.BlockCipher.Decrypt(key, ciphertext[SaltSize:])
  162. Zero(key)
  163. if err != nil {
  164. return nil, err
  165. }
  166.  
  167. return out, nil
  168. }
  169.  
  170. // MockBlockCipher implements BlockCipher but does nothing
  171. type MockBlockCipher struct{}
  172.  
  173. // Encrypt in this case is only implementing the BlockCipher interface, it doesn't do anything
  174. func (m *MockBlockCipher) Encrypt(key, plaintext []byte) ([]byte, error) {
  175. return plaintext, nil
  176. }
  177.  
  178. // Decrypt in this case is only implementing the BlockCipher interface, it doesn't do anything
  179. func (m *MockBlockCipher) Decrypt(key, ciphertext []byte) ([]byte, error) {
  180. return ciphertext, nil
  181. }
  182.  
  183. // KeySize is a mock key size to use with the mock cipher
  184. func (m *MockBlockCipher) KeySize() int {
  185. return 32
  186. }
  187.  
  188. // Message represents a message being passed, and contains its contents and a sequence number
  189. type Message struct {
  190. Number uint32
  191. Contents []byte
  192. }
  193.  
  194. // NewMessage returns a new message
  195. func NewMessage(in []byte, num uint32) *Message {
  196. return &Message{Contents: in, Number: num}
  197. }
  198.  
  199. // Marshal encodes a sequence number into the data that we wish to send
  200. func (m *Message) Marshal() []byte {
  201. out := make([]byte, 4, len(m.Contents)+4)
  202. binary.BigEndian.PutUint32(out[:4], m.Number)
  203. return append(out, m.Contents...)
  204. }
  205.  
  206. // UnmarshalMessage decodes bytes into a message pointer
  207. func UnmarshalMessage(in []byte) (*Message, error) {
  208. m := &Message{}
  209. if len(in) <= 4 {
  210. return m, encerrors.ErrInvalidMessageLength
  211. }
  212.  
  213. m.Number = binary.BigEndian.Uint32(in[:4])
  214. m.Contents = in[4:]
  215. return m, nil
  216. }
  217.  
  218. // Channel is a typed io.ReadWriter used for communicating securely
  219. type Channel io.ReadWriter
  220.  
  221. // Session represents a session that can be used to pass messages over a secure channel
  222. type Session struct {
  223. Cipher *Cipher
  224. Channel
  225. lastSent uint32
  226. lastRecv uint32
  227. sendKey *[32]byte
  228. recvKey *[32]byte
  229. }
  230.  
  231. // LastSent returns the last sent message id
  232. func (s *Session) LastSent() uint32 {
  233. return s.lastSent
  234. }
  235.  
  236. // LastRecv returns the last received message id
  237. func (s *Session) LastRecv() uint32 {
  238. return s.lastRecv
  239. }
  240.  
  241. // Encrypt encrypts a message with an embedded message id
  242. func (s *Session) Encrypt(message []byte) ([]byte, error) {
  243. if len(message) == 0 {
  244. return nil, encerrors.ErrInvalidMessageLength
  245. }
  246.  
  247. s.lastSent++
  248. m := NewMessage(message, s.lastSent)
  249. return s.Cipher.Encrypt(s.sendKey[:], m.Marshal())
  250. }
  251.  
  252. // Decrypt decrypts a message and checks that its message id is valid
  253. func (s *Session) Decrypt(message []byte) ([]byte, error) {
  254. out, err := s.Cipher.Decrypt(s.recvKey[:], message)
  255. if err != nil {
  256. return nil, err
  257. }
  258.  
  259. m, err := UnmarshalMessage(out)
  260. if err != nil {
  261. return nil, err
  262. }
  263.  
  264. // if this number is less than or equal to the last received message, this is a replay and we bail
  265. if m.Number <= s.lastRecv {
  266. return nil, encerrors.ErrInvalidMessageID
  267. }
  268.  
  269. s.lastRecv = m.Number
  270.  
  271. return m.Contents, nil
  272. }
  273.  
  274. // Send encrypts the message and sends it out over the channel.
  275. func (s *Session) Send(message []byte) error {
  276. m, err := s.Encrypt(message)
  277. if err != nil {
  278. return err
  279. }
  280.  
  281. err = binary.Write(s.Channel, binary.BigEndian, uint32(len(m)))
  282. if err != nil {
  283. return err
  284. }
  285.  
  286. _, err = s.Channel.Write(m)
  287. return err
  288. }
  289.  
  290. // Receive listens for a new message on the channel.
  291. func (s *Session) Receive() ([]byte, error) {
  292. var mlen uint32
  293. err := binary.Read(s.Channel, binary.BigEndian, &mlen)
  294. if err != nil {
  295. return nil, err
  296. }
  297.  
  298. message := make([]byte, int(mlen))
  299. _, err = io.ReadFull(s.Channel, message)
  300. if err != nil {
  301. return nil, err
  302. }
  303.  
  304. return s.Decrypt(message)
  305. }
  306.  
  307. // GenerateKeyPair generates a new key pair. This can be used to get a
  308. // new key pair for setting up a rekeying operation during the session.
  309. func GenerateKeyPair() (pub *[64]byte, priv *[64]byte, err error) {
  310. pub = new([64]byte)
  311. priv = new([64]byte)
  312.  
  313. recvPub, recvPriv, err := box.GenerateKey(rand.Reader)
  314. if err != nil {
  315. return nil, nil, err
  316. }
  317. copy(pub[:], recvPub[:])
  318. copy(priv[:], recvPriv[:])
  319.  
  320. sendPub, sendPriv, err := box.GenerateKey(rand.Reader)
  321. if err != nil {
  322. return nil, nil, err
  323. }
  324. copy(pub[32:], sendPub[:])
  325. copy(priv[32:], sendPriv[:])
  326. return pub, priv, err
  327. }
  328.  
  329. // Close zeroises the keys in the session. Once a session is closed,
  330. // the traffic that was sent over the channel can no longer be decrypted
  331. // and any attempts at sending or receiving messages over the channel
  332. // will fail.
  333. func (s *Session) Close() error {
  334. Zero(s.sendKey[:])
  335. Zero(s.recvKey[:])
  336. return nil
  337. }
  338.  
  339. // keyExchange is a convenience function that takes keys as byte slices,
  340. // copying them into the appropriate arrays.
  341. func keyExchange(shared *[32]byte, priv, pub []byte) {
  342. // Copy the private key and wipe it, as it will no longer be needed.
  343. var kexPriv [32]byte
  344. copy(kexPriv[:], priv)
  345. Zero(priv)
  346.  
  347. var kexPub [32]byte
  348. copy(kexPub[:], pub)
  349.  
  350. box.Precompute(shared, &kexPub, &kexPriv)
  351. Zero(kexPriv[:])
  352. }
  353.  
  354. // NewSession returns a new *Session
  355. func NewSession(ch Channel, c *Cipher) *Session {
  356. return &Session{
  357. Cipher: c,
  358. Channel: ch,
  359. recvKey: new([32]byte),
  360. sendKey: new([32]byte),
  361. }
  362. }
  363.  
  364. // Dial sets up a new session over the channel by generating a new pair
  365. // of Curve25519 keypairs, sending its public keys to the peer, and
  366. // reading the peer's public keys back.
  367. func Dial(ch Channel, c *Cipher) (*Session, error) {
  368. var peer [64]byte
  369. pub, priv, err := GenerateKeyPair()
  370. if err != nil {
  371. return nil, err
  372. }
  373.  
  374. _, err = ch.Write(pub[:])
  375. if err != nil {
  376. return nil, err
  377. }
  378.  
  379. // Make sure the entire public key is read.
  380. _, err = io.ReadFull(ch, peer[:])
  381. if err != nil {
  382. return nil, err
  383. }
  384.  
  385. s := NewSession(ch, c)
  386.  
  387. s.KeyExchange(priv, &peer, true)
  388. return s, nil
  389. }
  390.  
  391. // Listen waits for a peer to Dial in, then sets up a key exchange
  392. // and session.
  393. func Listen(ch Channel, c *Cipher) (*Session, error) {
  394. var peer [64]byte
  395. pub, priv, err := GenerateKeyPair()
  396. if err != nil {
  397. return nil, err
  398. }
  399.  
  400. // Ensure the entire peer key is read.
  401. _, err = io.ReadFull(ch, peer[:])
  402. if err != nil {
  403. return nil, err
  404. }
  405.  
  406. _, err = ch.Write(pub[:])
  407. if err != nil {
  408. return nil, err
  409. }
  410.  
  411. s := NewSession(ch, c)
  412.  
  413. s.KeyExchange(priv, &peer, false)
  414. return s, nil
  415. }
  416.  
  417. // KeyExchange - Rekey is used to perform the key exchange once both sides have
  418. // exchanged their public keys. The underlying message protocol will
  419. // need to actually initiate and carry out the key exchange, and call
  420. // this once that is finished. The private key will be zeroised after
  421. // calling this function. If the session is on the side that initiated
  422. // the key exchange (e.g. by calling Dial), it should set the dialer
  423. // argument to true. This will also reset the message counters for the
  424. // session, as it will cause the session to use a new key.
  425. func (s *Session) KeyExchange(priv, peer *[64]byte, dialer bool) {
  426. // This function denotes the dialer, who initiates the session,
  427. // as A. The listener is denoted as B. A is started using Dial,
  428. // and B is started using Listen.
  429. if dialer {
  430. // The first 32 bytes are the A->B link, where A is the
  431. // dialer. This key material should be used to set up the
  432. // A send key.
  433. keyExchange(s.sendKey, priv[:32], peer[:32])
  434.  
  435. // The last 32 bytes are the B->A link, where A is the
  436. // dialer. This key material should be used to set up the A
  437. // receive key.
  438. keyExchange(s.recvKey, priv[32:], peer[32:])
  439. } else {
  440. // The first 32 bytes are the A->B link, where A is the
  441. // dialer. This key material should be used to set up the
  442. // B receive key.
  443. keyExchange(s.recvKey, priv[:32], peer[:32])
  444.  
  445. // The last 32 bytes are the B->A link, where A is the
  446. // dialer. This key material should be used to set up the
  447. // B send key.
  448. keyExchange(s.sendKey, priv[32:], peer[32:])
  449. }
  450. s.lastSent = 0
  451. s.lastRecv = 0
  452. }
  453.  
  454. const (
  455. // testComplexity is unexported because we don't want to use such a weak key in the wild
  456. testComplexity = 1 << (iota + 7)
  457. )
  458.  
  459. const (
  460. // N Complexity in powers of 2 for key Derivation
  461.  
  462. // InteractiveComplexity - recommended complexity for interactive sessions
  463. InteractiveComplexity = 1 << (iota + 14)
  464. // Complexity15 is 2^15
  465. Complexity15
  466. // Complexity16 is 2^16
  467. Complexity16
  468. // Complexity17 is 2^17
  469. Complexity17
  470. // Complexity18 is 2^18
  471. Complexity18
  472. // Complexity19 is 2^19
  473. Complexity19
  474. // AggressiveComplexity is 2^20 (don't use this unless you have incredibly strong CPU power
  475. AggressiveComplexity
  476. )
  477.  
  478. // DeriveKey generates a new NaCl key from a passphrase and salt.
  479. // This is a costly operation.
  480. func DeriveKey(pass, salt []byte, N, keySize int) ([]byte, error) {
  481. var naclKey = make([]byte, keySize)
  482. key, err := scrypt.Key(pass, salt, N, 8, 1, keySize)
  483. if err != nil {
  484. return nil, err
  485. }
  486.  
  487. copy(naclKey, key)
  488. Zero(key)
  489. return naclKey, nil
  490. }
  491.  
  492. // Zero zeroes out bytes of data so that it does not stay in memory any longer than necessary
  493. func Zero(data []byte) {
  494. for i := 0; i < len(data); i++ {
  495. data[i] = 0
  496. }
  497. }
  498.  
  499. // Package cbc supports cbc encryption
  500. package cbc
  501.  
  502. // https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29
  503.  
  504. import (
  505. "crypto/aes"
  506. "crypto/cipher"
  507. "crypto/hmac"
  508. "crypto/rand"
  509. "crypto/sha256"
  510.  
  511. "io"
  512.  
  513. "github.com/alistanis/goenc/encerrors"
  514. "github.com/alistanis/goenc/generate"
  515. )
  516.  
  517. const (
  518. // NonceSize to use for nonces
  519. NonceSize = aes.BlockSize
  520. // MACSize is the output size of HMAC-SHA-256
  521. MACSize = 32
  522. // CKeySize - Cipher key size - AES-256
  523. CKeySize = 32
  524. // MKeySize - HMAC key size - HMAC-SHA-256
  525. MKeySize = 32
  526. // KeySize is the key size for CBC
  527. KeySize = CKeySize + MKeySize
  528. )
  529.  
  530. // pad pads input to match the correct size
  531. func pad(in []byte) []byte {
  532. padding := 16 - (len(in) % 16)
  533. for i := 0; i < padding; i++ {
  534. in = append(in, byte(padding))
  535. }
  536. return in
  537. }
  538.  
  539. // unpad removes unnecessary bytes that were added during initial padding
  540. func unpad(in []byte) []byte {
  541. if len(in) == 0 {
  542. return nil
  543. }
  544.  
  545. padding := in[len(in)-1]
  546. if int(padding) > len(in) || padding > aes.BlockSize {
  547. return nil
  548. } else if padding == 0 {
  549. return nil
  550. }
  551.  
  552. for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
  553. if in[i] != padding {
  554. return nil
  555. }
  556. }
  557. return in[:len(in)-int(padding)]
  558. }
  559.  
  560. // Cipher implements the BlockCipher interface
  561. type Cipher struct{}
  562.  
  563. // Encrypt implements the BlockCipher interface
  564. func (c *Cipher) Encrypt(key, plaintext []byte) ([]byte, error) {
  565. return Encrypt(key, plaintext)
  566. }
  567.  
  568. // Decrypt implements the BlockCipher interface
  569. func (c *Cipher) Decrypt(key, ciphertext []byte) ([]byte, error) {
  570. return Decrypt(key, ciphertext)
  571. }
  572.  
  573. // KeySize returns CBC KeySize and implements the BlockCipher interface
  574. func (c *Cipher) KeySize() int {
  575. return KeySize
  576. }
  577.  
  578. // New returns a new cbc cipher
  579. func New() *Cipher {
  580. return &Cipher{}
  581. }
  582.  
  583. // Key returns a random key as a pointer to an array of bytes specified by KeySize
  584. func Key() (*[KeySize]byte, error) {
  585. key := new([KeySize]byte)
  586. _, err := io.ReadFull(rand.Reader, key[:])
  587. return key, err
  588. }
  589.  
  590. // Encrypt encrypts plaintext using the given key with CBC encryption
  591. func Encrypt(key, plaintext []byte) ([]byte, error) {
  592. if len(key) != KeySize {
  593. return nil, encerrors.ErrInvalidKeyLength
  594. }
  595.  
  596. iv, err := generate.RandBytes(NonceSize)
  597. if err != nil {
  598. return nil, err
  599. }
  600.  
  601. pmessage := pad(plaintext)
  602. ct := make([]byte, len(pmessage))
  603.  
  604. // NewCipher only returns an error with an invalid key size,
  605. // but the key size was checked at the beginning of the function.
  606. c, _ := aes.NewCipher(key[:CKeySize])
  607. ctr := cipher.NewCBCEncrypter(c, iv)
  608. ctr.CryptBlocks(ct, pmessage)
  609.  
  610. h := hmac.New(sha256.New, key[CKeySize:])
  611. ct = append(iv, ct...)
  612. h.Write(ct)
  613. ct = h.Sum(ct)
  614. return ct, nil
  615. }
  616.  
  617. // Decrypt decrypts ciphertext using the given key
  618. func Decrypt(key, ciphertext []byte) ([]byte, error) {
  619. if len(key) != KeySize {
  620. return nil, encerrors.ErrInvalidKeyLength
  621. }
  622.  
  623. // HMAC-SHA-256 returns a MAC that is also a multiple of the
  624. // block size.
  625. if (len(ciphertext) % aes.BlockSize) != 0 {
  626. return nil, encerrors.ErrInvalidMessageLength
  627. }
  628.  
  629. // A ciphertext must have at least an IV block, a ciphertext block,
  630. // and two blocks of HMAC.
  631. if len(ciphertext) < (4 * aes.BlockSize) {
  632. return nil, encerrors.ErrInvalidMessageLength
  633. }
  634.  
  635. macStart := len(ciphertext) - MACSize
  636. tag := ciphertext[macStart:]
  637. out := make([]byte, macStart-NonceSize)
  638. ciphertext = ciphertext[:macStart]
  639.  
  640. h := hmac.New(sha256.New, key[CKeySize:])
  641. h.Write(ciphertext)
  642. mac := h.Sum(nil)
  643. if !hmac.Equal(mac, tag) {
  644. return nil, encerrors.ErrInvalidSum
  645. }
  646.  
  647. // NewCipher only returns an error with an invalid key size,
  648. // but the key size was checked at the beginning of the function.
  649. c, _ := aes.NewCipher(key[:CKeySize])
  650. ctr := cipher.NewCBCDecrypter(c, ciphertext[:NonceSize])
  651. ctr.CryptBlocks(out, ciphertext[NonceSize:])
  652.  
  653. pt := unpad(out)
  654. if pt == nil {
  655. return nil, encerrors.ErrInvalidPadding
  656. }
  657.  
  658. return pt, nil
  659. }
  660.  
  661. // Package cfb supports basic cfb encryption with NO HMAC
  662. package cfb
  663.  
  664. // https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Feedback_.28CFB.29
  665.  
  666. import (
  667. "crypto/aes"
  668. "crypto/cipher"
  669. "crypto/rand"
  670. "io"
  671.  
  672. "github.com/alistanis/goenc/encerrors"
  673. "github.com/alistanis/goenc/generate"
  674. )
  675.  
  676. // KeySize for CFB uses the generic key size
  677. const KeySize = generate.KeySize
  678.  
  679. // Cipher to use for implementing the BlockCipher interface
  680. type Cipher struct {
  681. }
  682.  
  683. // New returns a new cfb cipher
  684. func New() *Cipher {
  685. return &Cipher{}
  686. }
  687.  
  688. // Encrypt implements the BlockCipher interface
  689. func (c *Cipher) Encrypt(key, plaintext []byte) ([]byte, error) {
  690. return Encrypt(key, plaintext)
  691. }
  692.  
  693. // Decrypt implements the BlockCipher interface
  694. func (c *Cipher) Decrypt(key, ciphertext []byte) ([]byte, error) {
  695. return Decrypt(key, ciphertext)
  696. }
  697.  
  698. // KeySize implements the BlockCipher interface
  699. func (c *Cipher) KeySize() int {
  700. return KeySize
  701. }
  702.  
  703. // Decrypt decrypts ciphertext using the given key
  704. func Decrypt(key, ciphertext []byte) ([]byte, error) {
  705.  
  706. // Create the AES cipher
  707. block, err := aes.NewCipher(key)
  708. if err != nil {
  709. return nil, err
  710. }
  711.  
  712. if len(ciphertext) < aes.BlockSize {
  713. return nil, encerrors.ErrInvalidMessageLength
  714. }
  715.  
  716. // get first 16 bytes from ciphertext
  717. iv := ciphertext[:aes.BlockSize]
  718.  
  719. // Remove the IV from the ciphertext
  720. ciphertext = ciphertext[aes.BlockSize:]
  721.  
  722. // Return a decrypted stream
  723. stream := cipher.NewCFBDecrypter(block, iv)
  724.  
  725. // SimpleDecrypt bytes from ciphertext
  726. stream.XORKeyStream(ciphertext, ciphertext)
  727.  
  728. return ciphertext, nil
  729. }
  730.  
  731. // Encrypt encrypts ciphertext using the given key.
  732. // NOTE: This is not secure without being authenticated (crypto/hmac)
  733. func Encrypt(key, plaintext []byte) ([]byte, error) {
  734. // Create the AES cipher
  735. block, err := aes.NewCipher(key)
  736. if err != nil {
  737. return nil, err
  738. }
  739.  
  740. // Empty array of 16 + plaintext length
  741. // Include the IV at the beginning
  742. ciphertext := make([]byte, aes.BlockSize+len(plaintext))
  743.  
  744. // Slice of first 16 bytes
  745. iv := ciphertext[:aes.BlockSize]
  746.  
  747. // Write 16 rand bytes to fill iv
  748. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  749. return nil, err
  750. }
  751.  
  752. // Return an encrypted stream
  753. stream := cipher.NewCFBEncrypter(block, iv)
  754.  
  755. // SimpleEncrypt bytes from plaintext to ciphertext
  756. stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
  757. return ciphertext, nil
  758. }
  759.  
  760. // DecryptString decrypts ciphertext using the given key
  761. func DecryptString(key, ciphertext string) (string, error) {
  762. b, err := Decrypt([]byte(key), []byte(ciphertext))
  763. return string(b), err
  764. }
  765.  
  766. // EncryptString encrypts ciphertext using the given key
  767. func EncryptString(key, plaintext string) (string, error) {
  768. b, err := Encrypt([]byte(key), []byte(plaintext))
  769. return string(b), err
  770. }
  771.  
  772. // Package ctr supports ctr encryption
  773. package ctr
  774.  
  775. // https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29
  776.  
  777. import (
  778. "crypto/aes"
  779. "crypto/cipher"
  780. "crypto/hmac"
  781. "crypto/rand"
  782. "crypto/sha256"
  783.  
  784. "io"
  785.  
  786. "github.com/alistanis/goenc/encerrors"
  787. "github.com/alistanis/goenc/generate"
  788. )
  789.  
  790. const (
  791. // NonceSize to use for nonces
  792. NonceSize = aes.BlockSize
  793. // MACSize is the output size of HMAC-SHA-256
  794. MACSize = 32
  795. // CKeySize - Cipher key size - AES-256
  796. CKeySize = 32
  797. // MKeySize - HMAC key size - HMAC-SHA-256
  798. MKeySize = 32
  799. // KeySize to use for keys, 64 bytes
  800. KeySize = CKeySize + MKeySize
  801. )
  802.  
  803. // Cipher to implement the BlockCipher interface
  804. type Cipher struct {
  805. }
  806.  
  807. // New returns a new ctr cipher
  808. func New() *Cipher {
  809. return &Cipher{}
  810. }
  811.  
  812. // Encrypt implements the BlockCipher interface
  813. func (c *Cipher) Encrypt(key, plaintext []byte) ([]byte, error) {
  814. return Encrypt(key, plaintext)
  815. }
  816.  
  817. // Decrypt implements the BlockCipher interface
  818. func (c *Cipher) Decrypt(key, ciphertext []byte) ([]byte, error) {
  819. return Decrypt(key, ciphertext)
  820. }
  821.  
  822. // KeySize implements the BlockCipher interface
  823. func (c *Cipher) KeySize() int {
  824. return KeySize
  825. }
  826.  
  827. // Key returns a pointer to an array of bytes with the given KeySize
  828. func Key() (*[KeySize]byte, error) {
  829. key := new([KeySize]byte)
  830. _, err := io.ReadFull(rand.Reader, key[:])
  831. return key, err
  832. }
  833.  
  834. // Encrypt encrypts plaintext using the given key with CTR encryption
  835. func Encrypt(key, plaintext []byte) ([]byte, error) {
  836. if len(key) != KeySize {
  837. return nil, encerrors.ErrInvalidKeyLength
  838. }
  839.  
  840. nonce, err := generate.RandBytes(NonceSize)
  841. if err != nil {
  842. return nil, err
  843. }
  844.  
  845. ct := make([]byte, len(plaintext))
  846.  
  847. // NewCipher only returns an error with an invalid key size,
  848. // but the key size was checked at the beginning of the function.
  849. c, _ := aes.NewCipher(key[:CKeySize])
  850. ctr := cipher.NewCTR(c, nonce)
  851. ctr.XORKeyStream(ct, plaintext)
  852.  
  853. h := hmac.New(sha256.New, key[CKeySize:])
  854. ct = append(nonce, ct...)
  855. h.Write(ct)
  856. ct = h.Sum(ct)
  857. return ct, nil
  858. }
  859.  
  860. // Decrypt decrypts ciphertext using the given key
  861. func Decrypt(key, ciphertext []byte) ([]byte, error) {
  862. if len(key) != KeySize {
  863. return nil, encerrors.ErrInvalidKeyLength
  864. }
  865.  
  866. if len(ciphertext) <= (NonceSize + MACSize) {
  867. return nil, encerrors.ErrInvalidMessageLength
  868. }
  869.  
  870. macStart := len(ciphertext) - MACSize
  871. tag := ciphertext[macStart:]
  872. out := make([]byte, macStart-NonceSize)
  873. ciphertext = ciphertext[:macStart]
  874.  
  875. h := hmac.New(sha256.New, key[CKeySize:])
  876. h.Write(ciphertext)
  877. mac := h.Sum(nil)
  878. if !hmac.Equal(mac, tag) {
  879. return nil, encerrors.ErrInvalidSum
  880. }
  881.  
  882. c, _ := aes.NewCipher(key[:CKeySize])
  883. ctr := cipher.NewCTR(c, ciphertext[:NonceSize])
  884. ctr.XORKeyStream(out, ciphertext[NonceSize:])
  885. return out, nil
  886. }
  887.  
  888. // Package gcm supports gcm encryption
  889. package gcm
  890.  
  891. // https://en.wikipedia.org/wiki/Galois/Counter_Mode
  892.  
  893. import (
  894. "crypto/aes"
  895. "crypto/cipher"
  896. "encoding/binary"
  897.  
  898. "github.com/alistanis/goenc/encerrors"
  899. "github.com/alistanis/goenc/generate"
  900. )
  901.  
  902. // NonceSize // generic NonceSize
  903. const NonceSize = generate.NonceSize
  904.  
  905. // KeySize // generic KeySize
  906. const KeySize = generate.KeySize
  907.  
  908. // Cipher to implement the BlockCipher interface
  909. type Cipher struct {
  910. }
  911.  
  912. // New returns a new GCM cipher
  913. func New() *Cipher {
  914. return &Cipher{}
  915. }
  916.  
  917. // Encrypt implements the BlockCipher interface
  918. func (c *Cipher) Encrypt(key, plaintext []byte) ([]byte, error) {
  919. return Encrypt(key, plaintext)
  920. }
  921.  
  922. // Decrypt implements the BlockCipher interface
  923. func (c *Cipher) Decrypt(key, ciphertext []byte) ([]byte, error) {
  924. return Decrypt(key, ciphertext)
  925. }
  926.  
  927. // KeySize returns the GCM key size
  928. func (c *Cipher) KeySize() int {
  929. return KeySize
  930. }
  931.  
  932. // Encrypt secures a message using AES-GCM.
  933. func Encrypt(key, plaintext []byte) ([]byte, error) {
  934. c, err := aes.NewCipher(key)
  935. if err != nil {
  936. return nil, err
  937. }
  938.  
  939. gcm, err := cipher.NewGCMWithNonceSize(c, NonceSize)
  940. if err != nil {
  941. return nil, err
  942. }
  943.  
  944. nonce, err := generate.Nonce()
  945. if err != nil {
  946. return nil, err
  947. }
  948.  
  949. // Seal will append the output to the first argument; the usage
  950. // here appends the ciphertext to the nonce. The final parameter
  951. // is any additional data to be authenticated.
  952. out := gcm.Seal(nonce[:], nonce[:], plaintext, nil)
  953. return out, nil
  954. }
  955.  
  956. // EncryptString is a convenience function for working with strings
  957. func EncryptString(key, plaintext string) (string, error) {
  958. data, err := Encrypt([]byte(key), []byte(plaintext))
  959. return string(data), err
  960. }
  961.  
  962. // Decrypt decrypts data using AES-GCM
  963. func Decrypt(key, ciphertext []byte) ([]byte, error) {
  964. // Create the AES cipher
  965. block, err := aes.NewCipher(key)
  966. if err != nil {
  967. return nil, err
  968. }
  969. gcm, err := cipher.NewGCMWithNonceSize(block, NonceSize)
  970. if err != nil {
  971. return nil, err
  972. }
  973. nonce := make([]byte, NonceSize)
  974. copy(nonce, ciphertext)
  975. return gcm.Open(nil, nonce[:], ciphertext[NonceSize:], nil)
  976. }
  977.  
  978. // DecryptString is a convenience function for working with strings
  979. func DecryptString(key, ciphertext string) (string, error) {
  980. data, err := Decrypt([]byte(key), []byte(ciphertext))
  981. return string(data), err
  982. }
  983.  
  984. //---------------------------------------------
  985. // For use with more complex encryption schemes
  986. //---------------------------------------------
  987.  
  988. // EncryptWithID secures a message and prepends a 4-byte sender ID
  989. // to the message. The end bit is tricky, because gcm.Seal modifies buf, and this is necessary
  990. func EncryptWithID(key, message []byte, sender uint32) ([]byte, error) {
  991. buf := make([]byte, 4)
  992. binary.BigEndian.PutUint32(buf, sender)
  993.  
  994. c, err := aes.NewCipher(key)
  995. if err != nil {
  996. return nil, err
  997. }
  998.  
  999. gcm, err := cipher.NewGCMWithNonceSize(c, NonceSize)
  1000. if err != nil {
  1001. return nil, err
  1002. }
  1003.  
  1004. nonce, err := generate.Nonce()
  1005. if err != nil {
  1006. return nil, err
  1007. }
  1008.  
  1009. buf = append(buf, nonce[:]...)
  1010. return gcm.Seal(buf, nonce[:], message, buf[:4]), nil
  1011. }
  1012.  
  1013. // EncryptStringWithID is a helper function to work with strings instead of bytes
  1014. func EncryptStringWithID(key, message string, sender uint32) (string, error) {
  1015. data, err := EncryptWithID([]byte(key), []byte(message), sender)
  1016. return string(data), err
  1017. }
  1018.  
  1019. // DecryptWithID takes an encrypted message and a KeyForID function (to get a key from a cache or a database perhaps)
  1020. // It checks the first 4 bytes for prepended header data, in this case, a sender ID
  1021. func DecryptWithID(message []byte, k KeyRetriever) ([]byte, error) {
  1022.  
  1023. if len(message) <= NonceSize+4 {
  1024. return nil, encerrors.ErrInvalidMessageLength
  1025. }
  1026.  
  1027. id := binary.BigEndian.Uint32(message[:4])
  1028. key, err := k.KeyForID(id)
  1029. if err != nil {
  1030. return nil, err
  1031. }
  1032. c, err := aes.NewCipher(key)
  1033. if err != nil {
  1034. return nil, err
  1035. }
  1036.  
  1037. gcm, err := cipher.NewGCMWithNonceSize(c, NonceSize)
  1038. if err != nil {
  1039. return nil, err
  1040. }
  1041.  
  1042. nonce := make([]byte, NonceSize)
  1043. copy(nonce, message[4:])
  1044.  
  1045. ciphertext := message[4+NonceSize:]
  1046.  
  1047. // Decrypt the message, using the sender ID as the additional
  1048. // data requiring authentication.
  1049. out, err := gcm.Open(nil, nonce, ciphertext, message[:4])
  1050. if err != nil {
  1051. return nil, err
  1052. }
  1053.  
  1054. return out, nil
  1055. }
  1056.  
  1057. // DecryptStringWithID is a helper function to work with strings instead of bytes
  1058. func DecryptStringWithID(message string, k KeyRetriever) (string, error) {
  1059. data, err := DecryptWithID([]byte(message), k)
  1060. return string(data), err
  1061. }
  1062.  
  1063. // KeyRetriever represents a type that should be used in order to retrieve a key from a datastore
  1064. type KeyRetriever interface {
  1065. KeyForID(uint32) ([]byte, error)
  1066. }
  1067.  
  1068. // GCMHelper is designed to make it easy to call EncryptWithID and DecryptWithID by assigning the KeyForIDFunc
  1069. // it implements KeyRetriever and provides convenience functions
  1070. // It also serves as an example for how to use KeyRetriever
  1071. type GCMHelper struct {
  1072. KeyForIDFunc func(uint32) ([]byte, error)
  1073. }
  1074.  
  1075. // NewGCMHelper returns a new helper
  1076. func NewGCMHelper(f func(uint32) ([]byte, error)) *GCMHelper {
  1077. return &GCMHelper{f}
  1078. }
  1079.  
  1080. // KeyForID implements the KeyRetriever interface, it should be used to get a Key for the given ID
  1081. func (h *GCMHelper) KeyForID(u uint32) ([]byte, error) {
  1082. return h.KeyForIDFunc(u)
  1083. }
  1084.  
  1085. // Package nacl provides encryption by salting a key with a pad
  1086. package nacl
  1087.  
  1088. // https://en.wikipedia.org/wiki/NaCl_(software)
  1089. // work is derived from:
  1090. //
  1091. // https://github.com/andmarios/golang-nacl-secretbox
  1092.  
  1093. import (
  1094. "crypto/rand"
  1095. "errors"
  1096. "fmt"
  1097.  
  1098. "github.com/alistanis/goenc/generate"
  1099. "golang.org/x/crypto/nacl/secretbox"
  1100. )
  1101.  
  1102. const (
  1103. keySize = 32
  1104. nonceSize = 24
  1105. )
  1106.  
  1107. // Cipher to implmement the BlockCipher interface
  1108. type Cipher struct {
  1109. Pad []byte
  1110. }
  1111.  
  1112. // Encrypt implements the BlockCipher interface
  1113. func (c *Cipher) Encrypt(key, plaintext []byte) ([]byte, error) {
  1114. return Encrypt(c.Pad, key, plaintext)
  1115. }
  1116.  
  1117. // Decrypt implements the BlockCipher interface
  1118. func (c *Cipher) Decrypt(key, ciphertext []byte) ([]byte, error) {
  1119. return Decrypt(c.Pad, key, ciphertext)
  1120. }
  1121.  
  1122. // KeySize returns the NaCL keysize
  1123. func (c *Cipher) KeySize() int {
  1124. return keySize
  1125. }
  1126.  
  1127. // Encrypt salts a key using pad and encrypts a message
  1128. func Encrypt(pad, key, message []byte) (out []byte, err error) {
  1129. if len(pad) < 32 {
  1130. return nil, fmt.Errorf("pad had a length of %d, it must be at least 32 bytes", len(pad))
  1131. }
  1132. // NaCl's key has a constant size of 32 bytes.
  1133. // The user provided key probably is less than that. We pad it with
  1134. // a long enough string and truncate anything we don't need later on.
  1135. key = append(key, pad...)
  1136.  
  1137. // NaCl's key should be of type [32]byte.
  1138. // Here we create it and truncate key bytes beyond 32
  1139. naclKey := new([keySize]byte)
  1140. copy(naclKey[:], key[:keySize])
  1141.  
  1142. nonce, err := generate.Nonce()
  1143. if err != nil {
  1144. return nil, err
  1145. }
  1146. // out will hold the nonce and the encrypted message (ciphertext)
  1147. out = make([]byte, nonceSize)
  1148. // Copy the nonce to the start of out
  1149. copy(out, nonce[:])
  1150. // SimpleEncrypt the message and append it to out, assign the result to out
  1151. out = secretbox.Seal(out, message, nonce, naclKey)
  1152. return out, err
  1153. }
  1154.  
  1155. // Decrypt salts a key using pad and decrypts a message
  1156. func Decrypt(pad, key, data []byte) (out []byte, err error) {
  1157. key = append(key, pad...)
  1158.  
  1159. // NaCl's key should be of type [32]byte.
  1160. // Here we create it and truncate key bytes beyond 32
  1161. naclKey := new([keySize]byte)
  1162. copy(naclKey[:], key[:keySize])
  1163.  
  1164. // The nonce is of type [24]byte and part of the data we will receive
  1165. nonce := new([nonceSize]byte)
  1166.  
  1167. // Read the nonce from in, it is in the first 24 bytes
  1168. copy(nonce[:], data[:nonceSize])
  1169.  
  1170. // SimpleDecrypt the output of secretbox.Seal which contains the nonce and
  1171. // the encrypted message
  1172. message, ok := secretbox.Open(nil, data[nonceSize:], nonce, naclKey)
  1173. if ok {
  1174. return message, nil
  1175. }
  1176. return nil, errors.New("Decryption failed")
  1177. }
  1178.  
  1179. // RandomPadEncrypt generates a random pad and returns the encrypted data, the pad, and an error if any
  1180. func RandomPadEncrypt(key, message []byte) (pad, out []byte, err error) {
  1181. pad = make([]byte, 32)
  1182. _, err = rand.Read(pad)
  1183. if err != nil {
  1184. return
  1185. }
  1186. out, err = Encrypt(pad, key, message)
  1187. return
  1188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement