// Encrypts the contents of a file and returns the encrypted byte slice. // AES encryption with PCKS#7 padding. func Encrypt(filename, key string) (encrypted []byte, err error) { var ( aesCipher cipher.Block data []byte tempenc = make([]byte, blockSize) ) aesCipher, err = aes.NewCipher([]byte(key)) if err != nil { return } data, err = ioutil.ReadFile(filename) if err != nil { return encrypted, err } padded, err := padding.Pad(data, blockSize) if err != nil { return encrypted, err } for i := 0; i < len(padded)/blockSize; i++ { aesCipher.Encrypt(tempenc, padded[i*blockSize:i*blockSize+blockSize]) encrypted = append(encrypted, tempenc...) } return encrypted, nil }
// Given the supplied cipher, whose block size must be 16 bytes, return two // subkeys that can be used in MAC generation. See section 5.3 of NIST SP // 800-38B. Note that the other NIST-approved block size of 8 bytes is not // supported by this function. func generateSubkeys(ciph cipher.Block) (k1 []byte, k2 []byte) { if ciph.BlockSize() != blockSize { panic("generateSubkeys requires a cipher with a block size of 16 bytes.") } // Step 1 l := make([]byte, blockSize) ciph.Encrypt(l, subkeyZero) // Step 2: Derive the first subkey. if common.Msb(l) == 0 { // TODO(jacobsa): Accept a destination buffer in ShiftLeft and then hoist // the allocation in the else branch below. k1 = common.ShiftLeft(l) } else { k1 = make([]byte, blockSize) common.Xor(k1, common.ShiftLeft(l), subkeyRb) } // Step 3: Derive the second subkey. if common.Msb(k1) == 0 { k2 = common.ShiftLeft(k1) } else { k2 = make([]byte, blockSize) common.Xor(k2, common.ShiftLeft(k1), subkeyRb) } return }
func newCBC(b cipher.Block, IV []byte) *cbc { return &cbc{ b: b, blockSize: b.BlockSize(), IV: IV, } }
func newECB(b cipher.Block) *ecb { return &ecb{ b: b, blockSize: b.BlockSize(), } }
// 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 }
// 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 }
func decrypt(src io.Reader, des io.Writer, cipher cipher.Block, length int) error { blockSize := cipher.BlockSize() if length <= 0 { return errors.New("length must be greater than 0") } buf := make([]byte, blockSize) acc := 0 n, err := src.Read(buf) for err == nil && acc < length { acc += n cipher.Decrypt(buf, buf) if acc > length { paddings := acc - length des.Write(buf[0 : blockSize-paddings]) return nil } des.Write(buf) buf = make([]byte, blockSize) n, err = src.Read(buf) } 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 }
func CTREncrypt(block cipher.Block, nonce, dst, src []byte) { size := block.BlockSize() if len(nonce) != size { panic("size of IV not equal to block size") } if len(dst) == 0 || len(src) == 0 { return } // temp key key := make([]byte, size) // copy of nonce n := make([]byte, size) copy(n, nonce) counter := binary.LittleEndian.Uint64(n[8:]) for i := 0; i < len(dst) && i < len(src); i += size { block.Encrypt(key, n) for j := 0; j < size && i+j < len(src); j++ { dst[i+j] = src[i+j] ^ key[j] } counter++ binary.LittleEndian.PutUint64(n[8:], counter) } return }
// Encrypt производит шифрования хранилища по паролю. func Encrypt(s Storage, w io.Writer, pwd string) (err error) { var ( key [keySize]byte block cipher.Block iv []byte payload []byte ) // Prepare encryptor key = sha256.Sum256([]byte(pwd)) if block, err = aes.NewCipher(key[:]); err != nil { return err } iv = make([]byte, block.BlockSize()) if _, err = rand.Read(iv); err != nil { return err } if _, err = w.Write(iv); err != nil { return err } w = cipher.StreamWriter{S: cipher.NewCFBEncrypter(block, iv), W: w} // Encode and write if _, err = w.Write(key[:]); err != nil { return err } if payload, err = json.Marshal(s); err != nil { return err } if _, err := w.Write(payload); err != nil { return err } return nil }
func newRCBC(b cipher.Block, iv []byte) *rcbc { return &rcbc{ b: b, blockSize: b.BlockSize(), iv: dup(iv), tmp: make([]byte, b.BlockSize()), } }
// aesTransform - encrypt or decrypt (according to "direction") using block // cipher "bc" (typically AES) func aesTransform(dst []byte, src []byte, direction directionConst, bc cipher.Block) { if direction == DirectionEncrypt { bc.Encrypt(dst, src) return } else if direction == DirectionDecrypt { bc.Decrypt(dst, src) return } }
func ECBEncrypt(block cipher.Block, dst, src []byte) { size := block.BlockSize() if len(dst)%size != 0 { panic("size of dst and src should be multiples of blocksize") } for i := 0; i < len(dst); i += size { block.Encrypt(dst[i:i+size], src[i:i+size]) } }
func get_key(master cipher.Block, ctr uint64) (cipher.Block, []byte) { plain := make([]byte, 16) new_key := make([]byte, 16) binary.BigEndian.PutUint64(plain, ctr) master.Encrypt(new_key, plain) new_cipher, err := aes.NewCipher(new_key) check(err) return new_cipher, new_key }
// updateMAC reseeds the given hash with encrypted seed. // it returns the first 16 bytes of the hash sum after seeding. func updateMAC(mac hash.Hash, block cipher.Block, seed []byte) []byte { aesbuf := make([]byte, aes.BlockSize) block.Encrypt(aesbuf, mac.Sum(nil)) for i := range aesbuf { aesbuf[i] ^= seed[i] } mac.Write(aesbuf) return mac.Sum(nil)[:16] }
// Encrypt encrypts the plaintext src and outputs the corresponding ciphertext into dst. // Besides outputting a ciphertext into dst, Encrypt also outputs an authentication tag // of ocb2.TagSize bytes into tag, which should be used to verify the authenticity of the // message on the receiving side. // // To ensure both authenticity and secrecy of messages, each invocation to this function must // be given an unique nonce of ocb2.NonceSize bytes. The nonce need not be secret (it can be // a counter), but it needs to be unique. // // The block cipher used in function must work on a block size equal to ocb2.BlockSize. // The tag slice used in this function must have a length equal to ocb2.TagSize. // The nonce slice used in this function must have a length equal to ocb2.NonceSize. // If any of the above are violated, Encrypt will panic. func Encrypt(cipher cipher.Block, dst []byte, src []byte, nonce []byte, tag []byte) { if cipher.BlockSize() != BlockSize { panic("ocb2: cipher blocksize is not equal to ocb2.BlockSize") } if len(nonce) != NonceSize { panic("ocb2: nonce length is not equal to ocb2.NonceSize") } var ( checksum [BlockSize]byte delta [BlockSize]byte tmp [BlockSize]byte pad [BlockSize]byte calcTag [NonceSize]byte off int ) cipher.Encrypt(delta[0:], nonce[0:]) zeros(checksum[0:]) remain := len(src) for remain > BlockSize { times2(delta[0:]) xor(tmp[0:], delta[0:], src[off:off+BlockSize]) cipher.Encrypt(tmp[0:], tmp[0:]) xor(dst[off:off+BlockSize], delta[0:], tmp[0:]) xor(checksum[0:], checksum[0:], src[off:off+BlockSize]) remain -= BlockSize off += BlockSize } times2(delta[0:]) zeros(tmp[0:]) num := remain * 8 tmp[BlockSize-2] = uint8((uint32(num) >> 8) & 0xff) tmp[BlockSize-1] = uint8(num & 0xff) xor(tmp[0:], tmp[0:], delta[0:]) cipher.Encrypt(pad[0:], tmp[0:]) copied := copy(tmp[0:], src[off:]) if copied != remain { panic("ocb2: copy failed") } if copy(tmp[copied:], pad[copied:]) != (BlockSize - remain) { panic("ocb2: copy failed") } xor(checksum[0:], checksum[0:], tmp[0:]) xor(tmp[0:], pad[0:], tmp[0:]) if copy(dst[off:], tmp[0:]) != remain { panic("ocb2: copy failed") } times3(delta[0:]) xor(tmp[0:], delta[0:], checksum[0:]) cipher.Encrypt(calcTag[0:], tmp[0:]) copy(tag, calcTag[:]) }
func aesDecrypt(block cipher.Block, src []byte) []byte { var dst = make([]byte, 16) var src_len = len(src) var dec []byte for i := 0; i < src_len; i += 16 { block.Decrypt(dst, src[i:i+16]) dec = append(dec, dst...) } return dec }
func newCFB8(block cipher.Block, iv []byte, decrypt bool) (stream cipher.Stream) { cfb8 := new(cfb8) cfb8.b = block cfb8.next = make([]byte, len(iv)) cfb8.out = make([]byte, block.BlockSize()) cfb8.decrypt = decrypt copy(cfb8.next, iv) stream = cfb8 return }
func newCFB8(block cipher.Block, iv []byte, decrypt bool) (stream cipher.Stream) { cfb8 := new(cfb8) cfb8.Block = block cfb8.Iv = make([]byte, len(iv)) cfb8.Tmp = make([]byte, block.BlockSize()) cfb8.Decrypt = decrypt copy(cfb8.Iv, iv) stream = cfb8 return }
func newCFB8(block cipher.Block, iv []byte, decrypt bool) (stream cipher.Stream) { bytes := make([]byte, len(iv)) copy(bytes, iv) return &cfb8{ block: block, iv: bytes, tmp: make([]byte, block.BlockSize()), decrypt: decrypt, } }
func (eci encryptedContentInfo) decrypt(key []byte) ([]byte, error) { alg := eci.ContentEncryptionAlgorithm.Algorithm if !alg.Equal(oidEncryptionAlgorithmDESCBC) && !alg.Equal(oidEncryptionAlgorithmDESEDE3CBC) && !alg.Equal(oidEncryptionAlgorithmAES256CBC) { fmt.Printf("Unsupported Content Encryption Algorithm: %s\n", alg) return nil, ErrUnsupportedAlgorithm } // EncryptedContent can either be constructed of multple OCTET STRINGs // or _be_ a tagged OCTET STRING var cyphertext []byte if eci.EncryptedContent.IsCompound { // Complex case to concat all of the children OCTET STRINGs var buf bytes.Buffer cypherbytes := eci.EncryptedContent.Bytes for { var part []byte cypherbytes, _ = asn1.Unmarshal(cypherbytes, &part) buf.Write(part) if cypherbytes == nil { break } } cyphertext = buf.Bytes() } else { // Simple case, the bytes _are_ the cyphertext cyphertext = eci.EncryptedContent.Bytes } var block cipher.Block var err error switch { case alg.Equal(oidEncryptionAlgorithmDESCBC): block, err = des.NewCipher(key) case alg.Equal(oidEncryptionAlgorithmDESEDE3CBC): block, err = des.NewTripleDESCipher(key) case alg.Equal(oidEncryptionAlgorithmAES256CBC): block, err = aes.NewCipher(key) } if err != nil { return nil, err } iv := eci.ContentEncryptionAlgorithm.Parameters.Bytes if len(iv) != block.BlockSize() { return nil, errors.New("pkcs7: encryption algorithm parameters are malformed") } mode := cipher.NewCBCDecrypter(block, iv) plaintext := make([]byte, len(cyphertext)) mode.CryptBlocks(plaintext, cyphertext) if plaintext, err = unpad(plaintext, mode.BlockSize()); err != nil { return nil, err } return plaintext, nil }
// encrypt encrypts a value using the given block in counter mode. // // A random initialization vector (http://goo.gl/zF67k) with the length of the // block size is prepended to the resulting ciphertext. func encrypt(block cipher.Block, value []byte) ([]byte, error) { iv := generateRandomKey(block.BlockSize()) if iv == nil { return nil, errors.New("encrypt: failed to generate random iv") } // Encrypt it. stream := cipher.NewCTR(block, iv) stream.XORKeyStream(value, value) // Return iv + ciphertext. return append(iv, value...), nil }
func decrypt(c cipher.Block, iv []byte) *cfb8 { cp := make([]byte, len(iv)) copy(cp, iv) return &cfb8{ c: c, blockSize: c.BlockSize(), iv: cp, tmp: make([]byte, c.BlockSize()), de: true, } }
// encrypt encrypts a value using the given block in counter mode. // // A random initialization vector (http://goo.gl/zF67k) with the length of the // block size is prepended to the resulting ciphertext. func encrypt(block cipher.Block, value []byte) ([]byte, error) { iv := GenerateRandomKey(block.BlockSize()) if iv == nil { return nil, errors.New("securecookie: failed to generate random iv") } // Encrypt it. stream := cipher.NewCTR(block, iv) dst := make([]byte, len(value)) stream.XORKeyStream(dst, value) // Return iv + ciphertext. return append(iv, dst...), nil }
func decrypt(input []byte, key []byte) (decoded []byte) { var block cipher.Block key = hashBytes(key) decoded, _ = base64.StdEncoding.DecodeString(string(input)) block, _ = aes.NewCipher(key) cipher.NewCFBDecrypter(block, key[0:block.BlockSize()]).XORKeyStream(decoded, decoded) return }
func AESEncryptBytes(block cipher.Block, plain []byte) (cipherBytes []byte, err error) { blockSize := block.BlockSize() plain = utils.PadBytes(plain, blockSize) length := len(plain) // Encrypt cipherBytes = make([]byte, length) for i := 0; i < length; i += blockSize { block.Encrypt(cipherBytes[i:i+blockSize], plain[i:i+blockSize]) } return }
func newCrypter(key []byte, in io.Reader, size int, newCipher func(key []byte) (cipher.Block, error)) (io.ReadCloser, int, error) { var block cipher.Block var err error if block, err = newCipher(key); err != nil { return nil, 0, err } outsize := size - size%block.BlockSize() + 2*block.BlockSize() rd, wr := io.Pipe() go encrypt(block, in, size, wr) return rd, outsize, nil }
func aesEncrypt(block cipher.Block, src []byte) []byte { var dst = make([]byte, 16) var src_len = len(src) if src_len%16 != 0 { src = append(src, make([]byte, 16-src_len%16)...) } var enc []byte for i := 0; i < src_len; i += 16 { block.Encrypt(dst, src[i:i+16]) enc = append(enc, dst...) } return enc }
// decrypt decrypts a value using the given block in counter mode. // // 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(block cipher.Block, value []byte) ([]byte, 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) return value, nil } return nil, errors.New("decrypt: the value could not be decrypted") }
// NewOCFBEncrypter returns a cipher.Stream which encrypts data with OpenPGP's // cipher feedback mode using the given cipher.Block, and an initial amount of // ciphertext. randData must be random bytes and be the same length as the // cipher.Block's block size. Resync determines if the "resynchronization step" // from RFC 4880, 13.9 step 7 is performed. Different parts of OpenPGP vary on // this point. func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) { blockSize := block.BlockSize() if len(randData) != blockSize { return nil, nil } x := &ocfbEncrypter{ b: block, fre: make([]byte, blockSize), outUsed: 0, } prefix := make([]byte, blockSize+2) block.Encrypt(x.fre, x.fre) for i := 0; i < blockSize; i++ { prefix[i] = randData[i] ^ x.fre[i] } block.Encrypt(x.fre, prefix[:blockSize]) prefix[blockSize] = x.fre[0] ^ randData[blockSize-2] prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1] if resync { block.Encrypt(x.fre, prefix[2:]) } else { x.fre[0] = prefix[blockSize] x.fre[1] = prefix[blockSize+1] x.outUsed = 2 } return x, prefix }