encrypt.go raw

   1  /*
   2   * SPDX-FileCopyrightText: © Hypermode Inc. <hello@hypermode.com>
   3   * SPDX-License-Identifier: Apache-2.0
   4   */
   5  
   6  package y
   7  
   8  import (
   9  	"bytes"
  10  	"crypto/aes"
  11  	"crypto/cipher"
  12  	"crypto/rand"
  13  	"io"
  14  )
  15  
  16  // XORBlock encrypts the given data with AES and XOR's with IV.
  17  // Can be used for both encryption and decryption. IV is of
  18  // AES block size.
  19  func XORBlock(dst, src, key, iv []byte) error {
  20  	block, err := aes.NewCipher(key)
  21  	if err != nil {
  22  		return err
  23  	}
  24  	stream := cipher.NewCTR(block, iv)
  25  	stream.XORKeyStream(dst, src)
  26  	return nil
  27  }
  28  
  29  func XORBlockAllocate(src, key, iv []byte) ([]byte, error) {
  30  	block, err := aes.NewCipher(key)
  31  	if err != nil {
  32  		return nil, err
  33  	}
  34  	stream := cipher.NewCTR(block, iv)
  35  	dst := make([]byte, len(src))
  36  	stream.XORKeyStream(dst, src)
  37  	return dst, nil
  38  }
  39  
  40  func XORBlockStream(w io.Writer, src, key, iv []byte) error {
  41  	block, err := aes.NewCipher(key)
  42  	if err != nil {
  43  		return err
  44  	}
  45  	stream := cipher.NewCTR(block, iv)
  46  	sw := cipher.StreamWriter{S: stream, W: w}
  47  	_, err = io.Copy(sw, bytes.NewReader(src))
  48  	return Wrapf(err, "XORBlockStream")
  49  }
  50  
  51  // GenerateIV generates IV.
  52  func GenerateIV() ([]byte, error) {
  53  	iv := make([]byte, aes.BlockSize)
  54  	_, err := rand.Read(iv)
  55  	return iv, err
  56  }
  57