Example #1
0
func main() {
	plainText := []byte("Bob loves Alice. But Alice hate Bob...")
	key := []byte("passw0rdpassw0rdpassw0rdpassw0rd")

	// Create new AES cipher block
	block, err := aes.NewCipher(key)
	if err != nil {
		fmt.Printf("err: %s\n", err)
	}

	// The IV (Initialization Vector) need to be unique, but not secure.
	// Therefore, it's common to include it at the beginning of the cipher text.
	cipherText := make([]byte, aes.BlockSize+len(plainText))

	// Create IV
	iv := cipherText[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		fmt.Printf("err: %s\n", err)
	}

	// Encrypt
	encryptStream := cipher.NewCTR(block, iv)
	encryptStream.XORKeyStream(cipherText[aes.BlockSize:], plainText)
	fmt.Printf("Cipher text: %x \n", cipherText)

	// Decrpt
	decryptedText := make([]byte, len(cipherText[aes.BlockSize:]))
	decryptStream := cipher.NewCTR(block, cipherText[:aes.BlockSize])
	decryptStream.XORKeyStream(decryptedText, cipherText[aes.BlockSize:])
	fmt.Printf("Decrypted text: %s\n", string(decryptedText))
}
Example #2
0
func TestCTR_AES(t *testing.T) {
	for _, tt := range ctrAESTests {
		test := tt.name

		c, err := aes.NewCipher(tt.key)
		if err != nil {
			t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
			continue
		}

		for j := 0; j <= 5; j += 5 {
			in := tt.in[0 : len(tt.in)-j]
			ctr := cipher.NewCTR(c, tt.iv)
			encrypted := make([]byte, len(in))
			ctr.XORKeyStream(encrypted, in)
			if out := tt.out[0:len(in)]; !bytes.Equal(out, encrypted) {
				t.Errorf("%s/%d: CTR\ninpt %x\nhave %x\nwant %x", test, len(in), in, encrypted, out)
			}
		}

		for j := 0; j <= 7; j += 7 {
			in := tt.out[0 : len(tt.out)-j]
			ctr := cipher.NewCTR(c, tt.iv)
			plain := make([]byte, len(in))
			ctr.XORKeyStream(plain, in)
			if out := tt.in[0:len(in)]; !bytes.Equal(out, plain) {
				t.Errorf("%s/%d: CTRReader\nhave %x\nwant %x", test, len(out), plain, out)
			}
		}

		if t.Failed() {
			break
		}
	}
}
Example #3
0
func ExampleNewCTR() {
	key := []byte("example key 1234")
	plaintext := []byte("some plaintext")

	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}

	// The IV needs to be unique, but not secure. Therefore it's common to
	// include it at the beginning of the ciphertext.
	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		panic(err)
	}

	stream := cipher.NewCTR(block, iv)
	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)

	// It's important to remember that ciphertexts must be authenticated
	// (i.e. by using crypto/hmac) as well as being encrypted in order to
	// be secure.

	// CTR mode is the same for both encryption and decryption, so we can
	// also decrypt that ciphertext with NewCTR.

	plaintext2 := make([]byte, len(plaintext))
	stream = cipher.NewCTR(block, iv)
	stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])

	fmt.Printf("%s\n", plaintext2)
	// Output: some plaintext
}
Example #4
0
func (conn *obfs3Conn) kdf(sharedSecret []byte) error {
	// Using that shared-secret each party derives its encryption keys as
	// follows:
	//
	//   INIT_SECRET = HMAC(SHARED_SECRET, "Initiator obfuscated data")
	//   RESP_SECRET = HMAC(SHARED_SECRET, "Responder obfuscated data")
	//   INIT_KEY = INIT_SECRET[:KEYLEN]
	//   INIT_COUNTER = INIT_SECRET[KEYLEN:]
	//   RESP_KEY = RESP_SECRET[:KEYLEN]
	//   RESP_COUNTER = RESP_SECRET[KEYLEN:]
	initHmac := hmac.New(sha256.New, sharedSecret)
	initHmac.Write([]byte(initiatorKdfString))
	initSecret := initHmac.Sum(nil)
	initHmac.Reset()
	initHmac.Write([]byte(initiatorMagicString))
	initMagic := initHmac.Sum(nil)

	respHmac := hmac.New(sha256.New, sharedSecret)
	respHmac.Write([]byte(responderKdfString))
	respSecret := respHmac.Sum(nil)
	respHmac.Reset()
	respHmac.Write([]byte(responderMagicString))
	respMagic := respHmac.Sum(nil)

	// The INIT_KEY value keys a block cipher (in CTR mode) used to
	// encrypt values from initiator to responder thereafter.  The counter
	// mode's initial counter value is INIT_COUNTER.  The RESP_KEY value
	// keys a block cipher (in CTR mode) used to encrypt values from
	// responder to initiator thereafter.  That counter mode's initial
	// counter value is RESP_COUNTER.
	//
	// Note: To have this be the last place where the shared secret is used,
	// also generate the magic value to send/scan for here.
	initBlock, err := aes.NewCipher(initSecret[:keyLen])
	if err != nil {
		return err
	}
	initStream := cipher.NewCTR(initBlock, initSecret[keyLen:])

	respBlock, err := aes.NewCipher(respSecret[:keyLen])
	if err != nil {
		return err
	}
	respStream := cipher.NewCTR(respBlock, respSecret[keyLen:])

	if conn.isInitiator {
		conn.tx = &cipher.StreamWriter{S: initStream, W: conn.Conn}
		conn.rx = &cipher.StreamReader{S: respStream, R: conn.rxBuf}
		conn.txMagic = initMagic
		conn.rxMagic = respMagic
	} else {
		conn.tx = &cipher.StreamWriter{S: respStream, W: conn.Conn}
		conn.rx = &cipher.StreamReader{S: initStream, R: conn.rxBuf}
		conn.txMagic = respMagic
		conn.rxMagic = initMagic
	}

	return nil
}
Example #5
0
func encrypt_data(plain, keys []byte) ([]byte, error) {
	var iv, key []byte
	var block cipher.Block
	var stream cipher.Stream

	iv_offset := TotalIVLen
	res := make([]byte, len(plain)+iv_offset)

	iv = res[iv_offset-SalsaIVLen : iv_offset]
	_, err := rand.Read(iv)
	if err != nil {
		return nil, err
	}
	// For some reason salsa20 API is different
	key_array := new([32]byte)
	copy(key_array[:], keys[cipherKeyLen*2:])
	salsa20.XORKeyStream(res[iv_offset:], plain, iv, key_array)
	iv_offset -= SalsaIVLen

	iv = res[iv_offset-IVLen : iv_offset]
	_, err = rand.Read(iv)
	if err != nil {
		return nil, err
	}
	key = keys[cipherKeyLen : cipherKeyLen*2]
	block, err = twofish.NewCipher(key)
	if err != nil {
		return nil, err
	}
	stream = cipher.NewCTR(block, iv)
	stream.XORKeyStream(res[iv_offset:], res[iv_offset:])
	iv_offset -= IVLen

	iv = res[iv_offset-IVLen : iv_offset]
	_, err = rand.Read(iv)
	if err != nil {
		return nil, err
	}
	key = keys[:cipherKeyLen]
	block, err = aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	stream = cipher.NewCTR(block, iv)
	stream.XORKeyStream(res[iv_offset:], res[iv_offset:])
	iv_offset -= IVLen

	if iv_offset != 0 {
		panic(fmt.Errorf("something went terribly wrong: iv_offset final value non-zero"))
	}

	return res, nil
}
Example #6
0
// decode uses the given block cipher (in CTR mode) to decrypt the
// data, and validate the hash.  If hash validation fails, an error is
// returned.
func decode(block cipher.Block, hmac hash.Hash, ciphertext []byte) ([]byte, error) {
	if len(ciphertext) < 2*block.BlockSize()+hmac.Size() {
		return nil, LenError
	}

	receivedHmac := ciphertext[len(ciphertext)-hmac.Size():]
	ciphertext = ciphertext[:len(ciphertext)-hmac.Size()]

	hmac.Write(ciphertext)
	if subtle.ConstantTimeCompare(hmac.Sum(nil), receivedHmac) != 1 {
		return nil, HashError
	}

	// split the iv and session bytes
	iv := ciphertext[len(ciphertext)-block.BlockSize():]
	session := ciphertext[:len(ciphertext)-block.BlockSize()]

	stream := cipher.NewCTR(block, iv)
	stream.XORKeyStream(session, session)

	// skip past the iv
	session = session[block.BlockSize():]

	return session, nil
}
Example #7
0
func streamCipherReaderForKeyData(keyType byte, keyData []byte, r io.ReadCloser) (io.ReadCloser, error) {

	switch keyType {
	case keyTypeAES:
		if len(keyData) != keyTypeAESKeySize {
			return nil, ErrInvalidKey
		}
		// Ignore error below, aes will fail only if the size of key is
		// invalid. We fully control it and pass valid value.
		block, _ := aes.NewCipher(keyData)
		var iv [aes.BlockSize]byte
		stream := cipher.NewCTR(block, iv[:])
		return &streamReader{cipher.StreamReader{S: stream, R: r}}, nil

	case keyTypeChaCha20:
		if len(keyData) != chacha20.KeySize {
			return nil, ErrInvalidKey
		}
		var nonce [chacha20.NonceSize]byte
		// Ignore error below, chacha20 will fail only if the size of key or
		// nonce are invalid. We fully control those and pass valid values.
		stream, _ := chacha20.NewCipher(keyData, nonce[:])
		return &streamReader{cipher.StreamReader{S: stream, R: r}}, nil

	default:
		return nil, ErrInvalidKey
	}
}
Example #8
0
func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) {
	if len(encrypted) < aes.BlockSize+sha256.Size {
		return nil, false
	}

	iv := encrypted[:aes.BlockSize]
	macBytes := encrypted[len(encrypted)-sha256.Size:]

	mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32])
	mac.Write(encrypted[:len(encrypted)-sha256.Size])
	expected := mac.Sum(nil)

	if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
		return nil, false
	}

	block, err := aes.NewCipher(c.config.SessionTicketKey[:16])
	if err != nil {
		return nil, false
	}
	ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
	plaintext := make([]byte, len(ciphertext))
	cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)

	state := new(sessionState)
	ok := state.unmarshal(plaintext)
	return state, ok
}
// encrypt encrypts a value using the given Block in CTR mode.
//
// A random initialization vector is generated and prepended to the resulting
// ciphertext to be available for decryption. Also, a random salt with the
// length of the block size is prepended to the value before encryption.
func encrypt(block cipher.Block, value []byte) (rv []byte, err error) {
	// Recover in case block has an invalid key.
	defer func() {
		if r := recover(); r != nil {
			err = r.(error)
		}
	}()
	size := block.BlockSize()
	// Generate an initialization vector suitable for encryption.
	// http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Initialization_vector_.28IV.29
	iv := make([]byte, size)
	if _, err = rand.Read(iv); err != nil {
		return
	}
	// Create a salt.
	salt := make([]byte, size)
	if _, err = rand.Read(salt); err != nil {
		return
	}
	value = append(salt, value...)
	// Encrypt it.
	stream := cipher.NewCTR(block, iv)
	stream.XORKeyStream(value, value)
	// Return iv + ciphertext.
	rv = append(iv, value...)
	return
}
Example #10
0
// Unseal reverses the operations in Seal to decrypt the enclosed data, verify its integrity and checks timeliness against time.Now().  The error
// result MUST BE CHECKED in all cases, as Unseal will always return what it believes to be the decrypted but not authenticated data.
func Unseal(auth, key, seal []byte) ([]byte, error) {
	if len(seal) < 56 {
		return seal, SEAL_UNDERFLOW
	}

	// We copy off the seal because we're about to manipulate it destructively.
	seal = append(make([]byte, 0, len(seal)), seal...)
	hash := hmac.New(sha256.New, auth)

	// Decrypt our HMAC and PLAINTEXT
	b, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	cipher.NewCTR(b, seal[:16]).XORKeyStream(seal[16:], seal[16:])

	// Extract our Timestamp
	expiry := binary.LittleEndian.Uint64(seal[16:24])

	// Compare our HMAC
	hash.Write(seal[0:24])
	hash.Write(seal[56:])
	if bytes.Compare(seal[24:56], hash.Sum(nil)) != 0 {
		return nil, SEAL_MISMATCH
	}

	// Compare our expiry
	if time.Now().After(time.Unix(int64(expiry), 0)) {
		return nil, SEAL_EXPIRED
	}

	return seal[56:], nil
}
Example #11
0
// Seal uses SHA256 in a HMAC configuration to authenticate data, and then encrypts it using AES-CTR with a random IV.  This protects the
// sealed data from modification or analysis by the recipient.  An expiry time is also sealed into the data structure, limiting the viability
// of the seal.
func Seal(auth, key, data []byte, exp time.Time) ([]byte, error) {
	hash := hmac.New(sha256.New, auth)
	seal := make([]byte, len(data)+56)

	// Read our IV
	_, err := rand.Read(seal[:16])
	if err != nil {
		return nil, err
	}

	// Apply our Stamp
	binary.LittleEndian.PutUint64(seal[16:], uint64(exp.Unix()))

	// Copy in our plaintext.
	copy(seal[56:], data)

	// HMAC everything before and after the HMAC field.
	hash.Write(seal[0:24])
	hash.Write(seal[56:])
	copy(seal[24:56], hash.Sum(nil))

	// Encrypt our HMAC and PLAINTEXT
	b, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	cipher.NewCTR(b, seal[:16]).XORKeyStream(seal[16:], seal[16:])

	return seal, nil
}
Example #12
0
func decryptNym(key, encNym []byte) []byte {
	block, _ := aes.NewCipher(key)                              // Keysize is ok, so no error should occur
	stream := cipher.NewCTR(block, make([]byte, aes.BlockSize)) // This is not very secure, but good enough since key should change a lot
	stream.XORKeyStream(encNym, encNym)                         // Decrypt
	l := int(encNym[0])
	return encNym[1 : l+1] // cut nym from cleartext
}
Example #13
0
// Assembles the crypto primitives needed for a one way communication channel:
// the stream cipher for encryption and the mac for authentication.
func makeHalfDuplex(hkdf io.Reader) (cipher.Stream, hash.Hash) {
	// Extract the symmetric key and create the block cipher
	key := make([]byte, config.SessionCipherBits/8)
	n, err := io.ReadFull(hkdf, key)
	if n != len(key) || err != nil {
		panic(fmt.Sprintf("Failed to extract session key: %v", err))
	}
	block, err := config.SessionCipher(key)
	if err != nil {
		panic(fmt.Sprintf("Failed to create session cipher: %v", err))
	}
	// Extract the IV for the counter mode and create the stream cipher
	iv := make([]byte, block.BlockSize())
	n, err = io.ReadFull(hkdf, iv)
	if n != len(iv) || err != nil {
		panic(fmt.Sprintf("Failed to extract session IV: %v", err))
	}
	stream := cipher.NewCTR(block, iv)

	// Extract the HMAC key and create the session MACer
	salt := make([]byte, config.SessionHash().Size())
	n, err = io.ReadFull(hkdf, salt)
	if n != len(salt) || err != nil {
		panic(fmt.Sprintf("Failed to extract session mac salt: %v", err))
	}
	mac := hmac.New(config.SessionHash, salt)

	return stream, mac
}
Example #14
0
func Decode(key []byte, rvalue string) ([]byte, error) {
	if len(rvalue) == 0 {
		return nil, nil
	}
	if len(key) == 0 {
		return []byte(rvalue), nil
	}
	// NOTE: using the URLEncoding.Decode(...) seems to muck with the
	// returned value. Using string, which wants to return a cleaner
	// version.
	value, err := base64.URLEncoding.DecodeString(rvalue)
	if err != nil {
		return nil, err
	}

	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	if len(value) < blockSize {
		return nil, ValueSizeError(len(value))
	}
	iv := value[:blockSize]
	value = value[blockSize:]

	stream := cipher.NewCTR(block, iv)
	stream.XORKeyStream(value, value)
	return value, nil
}
Example #15
0
//given a blob of text to decode, checks a few things and returns either
//the originally given unique id and true or "" and false.
func decryptSessionId(encryptedHex string, block cipher.Block) (string, bool) {
	ciphertext := make([]byte, len(encryptedHex)/2)
	l, err := hex.Decode(ciphertext, []byte(encryptedHex))
	if err != nil {
		log.Printf("unable to decode the hex bytes of session id (%s,%d): %v", encryptedHex, len(encryptedHex), err)
		return "", false
	}
	iv := ciphertext[:aes.BlockSize]
	stream := cipher.NewCTR(block, iv)

	cleartext := make([]byte, l-len(iv))
	stream.XORKeyStream(cleartext, ciphertext[aes.BlockSize:])
	s := string(cleartext)
	if !strings.HasPrefix(s, s5CookiePrefix) {
		log.Printf("No cookie prefix found, probably keys changed")
		return "", false
	}
	s = strings.TrimPrefix(s, s5CookiePrefix+":")
	parts := strings.Split(s, ",")
	if len(parts) != 2 {
		log.Printf("Failed to understand parts of session id: %s", s)
		return "", false
	}
	t, err := strconv.ParseInt(parts[1], 10, 64)
	if err != nil {
		log.Printf("Could not understand expiration time in session id: %s", s)
		return "", false
	}
	expires := time.Unix(t, 0)
	if expires.Before(time.Now()) {
		return "", false
	}
	return parts[0], true
}
Example #16
0
// Encrypt encrypts plaintext into ciphertext and protects ciphertext integrity
// with a MAC.
func (c *Crypter) Encrypt(data []byte) ([]byte, error) {
	block, err := aes.NewCipher(c.aesKey)
	if err != nil {
		return nil, err
	}

	ch, err := c.CreateHeader()
	if err != nil {
		return nil, err
	}

	// A ciphertext consists of an IV, encrypted bytes, and the output of
	// HMAC-SHA256.
	ciphertext := make([]byte, aes.BlockSize+len(data))
	iv := ciphertext[:aes.BlockSize]
	if _, err := rand.Read(iv); err != nil {
		return nil, err
	}

	s := cipher.NewCTR(block, iv)
	s.XORKeyStream(ciphertext[aes.BlockSize:], data)

	mac := hmac.New(sha256.New, c.hmacKey)
	mac.Write(ciphertext)
	m := mac.Sum(nil)

	ed := &EncryptedData{
		Header:     ch,
		Iv:         iv,
		Ciphertext: ciphertext[aes.BlockSize:],
		Mac:        m,
	}

	return proto.Marshal(ed)
}
Example #17
0
// Decrypt checks the MAC then decrypts ciphertext into plaintext.
func (c *Crypter) Decrypt(ciphertext []byte) ([]byte, error) {
	var ed EncryptedData
	if err := proto.Unmarshal(ciphertext, &ed); err != nil {
		return nil, err
	}

	// TODO(tmroeder): we're currently mostly ignoring the CryptoHeader,
	// since we only have one key.
	if *ed.Header.Version != CryptoVersion_CRYPTO_VERSION_1 {
		return nil, newError("bad version")
	}

	// Check the HMAC before touching the ciphertext.
	fullCiphertext := make([]byte, len(ed.Iv)+len(ed.Ciphertext))
	copy(fullCiphertext, ed.Iv)
	copy(fullCiphertext[len(ed.Iv):], ed.Ciphertext)

	mac := hmac.New(sha256.New, c.hmacKey)
	mac.Write(fullCiphertext)
	m := mac.Sum(nil)
	if !hmac.Equal(m, ed.Mac) {
		return nil, newError("bad HMAC")
	}

	block, err := aes.NewCipher(c.aesKey)
	if err != nil {
		return nil, err
	}

	s := cipher.NewCTR(block, ed.Iv)
	data := make([]byte, len(ed.Ciphertext))
	s.XORKeyStream(data, ed.Ciphertext)
	return data, nil
}
Example #18
0
// Encrypts a plaintext message with a temporary key and IV.
func (m *Message) Encrypt() error {
	// Generate a new temporary key and the associated block cipher
	key := make([]byte, config.PacketCipherBits/8)
	if n, err := io.ReadFull(rand.Reader, key); n != len(key) || err != nil {
		return err
	}
	block, err := config.PacketCipher(key)
	if err != nil {
		return err
	}
	// Generate a new random counter mode IV and the associated stream cipher
	iv := make([]byte, block.BlockSize())
	if n, err := io.ReadFull(rand.Reader, iv); n != len(iv) || err != nil {
		return err
	}
	stream := cipher.NewCTR(block, iv)

	// Encrypt the message, save the nonces and return
	stream.XORKeyStream(m.Data, m.Data)
	m.Head.Key = key
	m.Head.Iv = iv

	m.secure = true
	return nil
}
// decrypt decrypts a value using the given Block in CTR mode.
//
// The value to be decrypted must have a length greater than the block size,
// because the initialization vector is expected to prepend it. Also, a salt
// with the length of the block size is expected to prepend the plain value.
func decrypt(block cipher.Block, value []byte) (b []byte, err error) {
	// Recover in case block has an invalid key.
	defer func() {
		if r := recover(); r != nil {
			err = r.(error)
		}
	}()
	size := block.BlockSize()
	if len(value) > size {
		// Extract iv.
		iv := value[:size]
		// Extract ciphertext.
		value = value[size:]
		// Decrypt it.
		stream := cipher.NewCTR(block, iv)
		stream.XORKeyStream(value, value)
		if len(value) > size {
			// Return value without the salt.
			b = value[size:]
			return
		}
	}
	err = ErrDecryption
	return
}
Example #20
0
func AesEncryptData(data, key []byte, ctp string) []byte {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil
	}

	// The IV needs to be unique, but not secure. Therefore it's common to
	// include it at the beginning of the ciphertext.
	data_enc := make([]byte, aes.BlockSize+len(data))
	iv := data_enc[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return nil
	}

	var stream cipher.Stream
	switch ctp {
	case "cfb":
		stream = cipher.NewCFBEncrypter(block, iv)
	case "ctr":
		stream = cipher.NewCTR(block, iv)
	default:
		stream = cipher.NewOFB(block, iv)
	}
	stream.XORKeyStream(data_enc[aes.BlockSize:], data)

	// It's important to remember that ciphertexts must be authenticated
	// (i.e. by using crypto/hmac) as well as being encrypted in order to
	// be secure.

	return data_enc
}
Example #21
0
// Extracts a usable sized symmetric key and IV for the stream cipher from the huge master key, and
// creates a CTR stream cipher.
func (s *Session) makeCipher() (cipher.Stream, error) {
	// Create the key derivation function
	hasher := func() hash.Hash { return s.hash.New() }
	hkdf := hkdf.New(hasher, s.secret.Bytes(), hkdfSalt, hkdfInfo)

	// Extract the symmetric key
	key := make([]byte, s.keybits/8)
	n, err := io.ReadFull(hkdf, key)
	if n != len(key) || err != nil {
		return nil, err
	}
	// Create the block cipher
	block, err := s.crypter(key)
	if err != nil {
		return nil, err
	}
	// Extract the IV for the counter mode
	iv := make([]byte, block.BlockSize())
	n, err = io.ReadFull(hkdf, iv)
	if n != len(iv) || err != nil {
		return nil, err
	}
	// Create the stream cipher
	return cipher.NewCTR(block, iv), nil
}
Example #22
0
func AesDecryptData(data, key []byte, ctp string) []byte {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil
	}

	if len(data) < aes.BlockSize {
		return nil
	}

	iv := data[:aes.BlockSize]
	data_dec := data[aes.BlockSize:]

	var stream cipher.Stream
	switch ctp {
	case "cfb":
		stream = cipher.NewCFBDecrypter(block, iv)
	case "ctr":
		stream = cipher.NewCTR(block, iv)
	default:
		stream = cipher.NewOFB(block, iv)
	}

	// XORKeyStream can work in-place if the two arguments are the same.
	stream.XORKeyStream(data_dec, data_dec)
	return data_dec
}
Example #23
0
func newAESCTR(key, iv []byte) (cipher.Stream, error) {
	c, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	return cipher.NewCTR(c, iv), nil
}
Example #24
0
func AesDecryptFd(inFile, outFile *os.File, key, iv []byte, ctp int) error {
	block, err := aes.NewCipher(key)
	if err != nil {
		return err
	}

	var stream cipher.Stream
	switch ctp {
	case 1:
		stream = cipher.NewCFBDecrypter(block, iv[:])
	case 2:
		stream = cipher.NewCTR(block, iv[:])
	default:
		stream = cipher.NewOFB(block, iv[:])
	}

	reader := &cipher.StreamReader{S: stream, R: inFile}
	// Copy the input file to the output file, decrypting as we go.
	if _, err := io.Copy(outFile, reader); err != nil {
		return err
	}

	// Note that this example is simplistic in that it omits any
	// authentication of the encrypted data. If you were actually to use
	// StreamReader in this manner, an attacker could flip arbitrary bits in
	// the output.
	return nil
}
Example #25
0
// Decrypt decrypts a value using the given key with AES.
//
// The value to be decrypted must be prepended by a initialization vector
// (http://goo.gl/zF67k) with the length of the block size.
func Decrypt(blockKey []byte, value []byte) ([]byte, error) {

	block, err := aes.NewCipher(blockKey)
	if err != nil {
		return nil, err
	}

	size := block.BlockSize()
	if len(value) > size {
		// Extract iv.
		iv := value[:size]

		// Extract ciphertext.
		value = value[size:]

		// Decrypt it.
		stream := cipher.NewCTR(block, iv)
		stream.XORKeyStream(value, value)

		// Return on success
		return value, nil
	}

	return nil, errors.New("the value could not be decrypted")
}
Example #26
0
func secureInProxy(in <-chan []byte, secureIn chan<- []byte, hashType string, tIV, tCKey, tMKey []byte) {
	theirBlock, _ := aes.NewCipher(tCKey)
	theirCipher := cipher.NewCTR(theirBlock, tIV)

	theirMac, macSize := makeMac(hashType, tMKey)

	for {
		data, ok := <-in
		if !ok {
			close(secureIn)
			return
		}

		if len(data) <= macSize {
			continue
		}

		mark := len(data) - macSize
		buff := make([]byte, mark)

		theirCipher.XORKeyStream(buff, data[0:mark])

		theirMac.Write(data[0:mark])
		expected := theirMac.Sum(nil)
		theirMac.Reset()

		hmacOk := hmac.Equal(data[mark:], expected)

		if hmacOk {
			secureIn <- buff
		} else {
			secureIn <- nil
		}
	}
}
Example #27
0
func (c *Conversation) generateDHCommit() []byte {
	_, err := io.ReadFull(c.rand(), c.r[:])
	if err != nil {
		panic("otr: short read from random source")
	}

	var xBytes [dhPrivateBytes]byte
	c.x = c.randMPI(xBytes[:])
	c.gx = new(big.Int).Exp(g, c.x, p)
	c.gy = nil
	c.gxBytes = appendMPI(nil, c.gx)

	h := sha256.New()
	h.Write(c.gxBytes)
	h.Sum(c.digest[:0])

	aesCipher, err := aes.NewCipher(c.r[:])
	if err != nil {
		panic(err.Error())
	}

	var iv [aes.BlockSize]byte
	ctr := cipher.NewCTR(aesCipher, iv[:])
	ctr.XORKeyStream(c.gxBytes, c.gxBytes)

	return c.serializeDHCommit()
}
Example #28
0
func secureOutProxy(out chan<- []byte, secureOut <-chan []byte, hashType string, mIV, mCKey, mMKey []byte) {
	myBlock, _ := aes.NewCipher(mCKey)
	myCipher := cipher.NewCTR(myBlock, mIV)

	myMac, macSize := makeMac(hashType, mMKey)

	for {
		data, ok := <-secureOut
		if !ok {
			close(out)
			return
		}

		if len(data) == 0 {
			continue
		}

		buff := make([]byte, len(data)+macSize)

		myCipher.XORKeyStream(buff, data)

		myMac.Write(buff[0:len(data)])
		copy(buff[len(data):], myMac.Sum(nil))
		myMac.Reset()

		out <- buff
	}
}
Example #29
0
func (v *Vault) DecryptEnvironments(password string) (map[string]Environment, error) {
	if v.MACDigest != "sha-256" && v.Cipher != "aes" && v.CipherMode != "ctr" {
		return nil, ErrInvalidEncryptionConfig
	}

	// derive the key
	key, err := v.KeyDetails.key(password)
	if err != nil {
		return nil, err
	}

	// validate the mac
	if !hmac.Equal(v.mac(key), v.MAC) {
		return nil, ErrInvalidPassword
	}

	// decrypt the environments
	plaintext := make([]byte, len(v.Environments))

	block, err := aes.NewCipher(key)
	decrypter := cipher.NewCTR(block, v.IV)
	decrypter.XORKeyStream(plaintext, v.Environments)

	// unmarshal the environments
	environments := map[string]Environment{}
	err = json.Unmarshal(plaintext, &environments)
	if err != nil {
		return nil, err
	}

	return environments, nil
}
Example #30
0
// encode uses the given block cipher (in CTR mode) to encrypt the
// data, along with a hash, returning the iv and the ciphertext. What
// is returned looks like:
//
//   encrypted(salt + sessionData) + iv + hmac
//
func encode(block cipher.Block, hmac hash.Hash, data []byte) ([]byte, error) {

	buf := bytes.NewBuffer(nil)

	salt := make([]byte, block.BlockSize())
	if _, err := io.ReadFull(rand.Reader, salt); err != nil {
		return nil, err
	}
	buf.Write(salt)
	buf.Write(data)

	session := buf.Bytes()

	iv := make([]byte, block.BlockSize())
	if _, err := rand.Read(iv); err != nil {
		return nil, err
	}

	stream := cipher.NewCTR(block, iv)
	stream.XORKeyStream(session, session)

	buf.Write(iv)
	hmac.Write(buf.Bytes())
	buf.Write(hmac.Sum(nil))

	return buf.Bytes(), nil
}