func newCBC(b cipher.Block, IV []byte) *cbc { return &cbc{ b: b, blockSize: b.BlockSize(), IV: IV, } }
// 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 }
func newECB(b cipher.Block) *ecb { return &ecb{ b: b, blockSize: b.BlockSize(), } }
// 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 }
// 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 }
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 }
// 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 TestCipher(t *testing.T) { var aes cipher.Block var err error for cipher_id, expected := range cipher_results { aes, err = NewCipher(cipher_id, key, nil) if err != nil { t.Fatal(err) } blocksize := aes.BlockSize() ciphertext := make([]byte, blocksize) aes.Encrypt(ciphertext, cleartext) deciphertext := make([]byte, blocksize) if !strings.EqualFold(expected, fmt.Sprintf("%x", ciphertext)) { t.Fatal("couldn't encrypt") } aes, err = NewCipher(cipher_id, key, nil) aes.Decrypt(deciphertext, ciphertext) if !bytes.Equal(cleartext, deciphertext) { t.Fatal("couldn't decrypt %s %s", cleartext, deciphertext) } if err != nil { t.Fatal(err) } } }
// 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 }
// 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 newRCBC(b cipher.Block, iv []byte) *rcbc { return &rcbc{ b: b, blockSize: b.BlockSize(), iv: dup(iv), tmp: make([]byte, b.BlockSize()), } }
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 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) { bytes := make([]byte, len(iv)) copy(bytes, iv) return &cfb8{ block: block, iv: bytes, tmp: make([]byte, block.BlockSize()), decrypt: decrypt, } }
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 (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 decrypt(block cipher.Block, in io.Reader, size int, out io.WriteCloser) error { var err error var buf []byte var count int var decrypter cipher.BlockMode defer out.Close() buf = make([]byte, block.BlockSize()) if _, err = io.ReadFull(in, buf); err != nil { return err } decrypter = cipher.NewCBCDecrypter(block, buf) count = (size - block.BlockSize()) / block.BlockSize() for count > 0 && err == nil { if _, err = io.ReadFull(in, buf); err == nil { decrypter.CryptBlocks(buf, buf) if count == 1 { for count = block.BlockSize() - 1; buf[count] == 0x00; count-- { continue } if buf[count] == 0x80 { buf = buf[:count] } } _, err = out.Write(buf) } count-- } if err == io.EOF { return nil } return err }
// 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") }
// Encrypts data using the hash of key provided. func encrypt(input []byte, key []byte) []byte { var block cipher.Block key = hashBytes(key) block, _ = aes.NewCipher(key) buff := make([]byte, len(input)) copy(buff, input) cipher.NewCFBEncrypter(block, key[0:block.BlockSize()]).XORKeyStream(buff, buff) return []byte(base64.RawStdEncoding.EncodeToString(buff)) }
// 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 }
func NewServer(conn net.Conn, block cipher.Block) (sc *CryptConn, err error) { iv, err := ExchangeIV(conn, block.BlockSize()) if err != nil { return } sc = &CryptConn{ Conn: conn, block: block, in: cipher.NewCFBDecrypter(block, iv), out: cipher.NewCFBEncrypter(block, iv), } return }
func newCFB8(c cipher.Block, iv []byte, decrypt bool) *cfb8 { if len(iv) != 16 { panic("bad iv length!") } cp := make([]byte, 256) copy(cp, iv) return &cfb8{ c: c, blockSize: c.BlockSize(), iv: cp[:16], iv_real: cp, tmp: make([]byte, 16), de: decrypt, } }
func NewClient(conn net.Conn, block cipher.Block) (sc CryptConn, err error) { iv := make([]byte, block.BlockSize()) _, err = io.ReadFull(conn, iv) if err != nil { return } sc = CryptConn{ Conn: conn, block: block, in: cipher.NewCFBDecrypter(block, iv), out: cipher.NewCFBEncrypter(block, iv), } 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 }