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) } } }
func ECBDecrypt(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.Decrypt(dst[i:i+size], src[i:i+size]) } }
// 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 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 decryptBlocks(b cipher.Block, dst, src []byte) error { if len(src)%b.BlockSize() != 0 { return ErrBlockSize } if len(dst) < len(src) { return ErrOutputSize } for len(src) > 0 { b.Decrypt(dst, src[:b.BlockSize()]) src = src[b.BlockSize():] dst = dst[b.BlockSize():] } return nil }
// blockDecrypt decrypts using the block cipher blk in ECB mode. func blockDecrypt(blk cipher.Block, dst, src []byte) error { if len(src) > len(dst) || len(src)%blk.BlockSize() != 0 { return errors.New("Block decryption failed") } l := len(src) - blk.BlockSize() for i := 0; i <= l; i += blk.BlockSize() { blk.Decrypt(dst[i:], src[i:]) } return nil }
func DecryptCBC(ciph cipher.Block, iv []byte, ciphertext []byte) ([]byte, error) { var resultblocks [][]byte blocks := mobytes.SplitEvery(ciphertext, 16) for i, block := range blocks { decrypted := make([]byte, 16) ciph.Decrypt(decrypted, block) if i == 0 { decrypted = mobytes.XOR(decrypted, iv) } else { decrypted = mobytes.XOR(decrypted, blocks[i-1]) } resultblocks = append(resultblocks, decrypted) } return bytes.Join(resultblocks, nil), nil }
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 }
// decryptDES derypts ciphertext input with passed key and 3DES-flag // in DES block cipher; and returns plaintext output func decryptDES(input, output, key []byte, tripleDES bool) error { var block cipher.Block var err error if tripleDES { block, err = des.NewTripleDESCipher(key) } else { block, err = des.NewCipher(key) } if err != nil { return errors.New("Couldn't create block cipher.") } for i := 0; i < len(input)/des.BlockSize; i++ { start := des.BlockSize * i end := start + des.BlockSize block.Decrypt(output[start:end], input[start:end]) } return nil }
func AESDecryptBytes(block cipher.Block, cipherBytes []byte) (plain []byte, err error) { defer func() { if e := recover(); e != nil { plain = nil err = fmt.Errorf("%v", e) } }() blockSize := block.BlockSize() cipherBytes = utils.PadBytes(cipherBytes, blockSize) length := len(cipherBytes) // Decrypt plain = make([]byte, length) for i := 0; i < length; i += blockSize { block.Decrypt(plain[i:i+blockSize], cipherBytes[i:i+blockSize]) } return }
func keyunwrap(block cipher.Block, ciphertxt []byte) ([]byte, error) { if len(ciphertxt)%keywrapChunkLen != 0 { return nil, ErrInvalidBlockSize } n := (len(ciphertxt) / keywrapChunkLen) - 1 r := make([][]byte, n) for i := range r { r[i] = make([]byte, keywrapChunkLen) copy(r[i], ciphertxt[(i+1)*keywrapChunkLen:]) } buffer := make([]byte, keywrapChunkLen*2) tBytes := make([]byte, keywrapChunkLen) copy(buffer[:keywrapChunkLen], ciphertxt[:keywrapChunkLen]) for t := 6*n - 1; t >= 0; t-- { binary.BigEndian.PutUint64(tBytes, uint64(t+1)) for i := 0; i < keywrapChunkLen; i++ { buffer[i] = buffer[i] ^ tBytes[i] } copy(buffer[keywrapChunkLen:], r[t%n]) block.Decrypt(buffer, buffer) copy(r[t%n], buffer[keywrapChunkLen:]) } if subtle.ConstantTimeCompare(buffer[:keywrapChunkLen], keywrapDefaultIV) == 0 { return nil, errors.New("keywrap: failed to unwrap key") } out := make([]byte, n*keywrapChunkLen) for i := range r { copy(out[i*keywrapChunkLen:], r[i]) } return out, nil }
// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher. func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) { if len(ciphertext)%8 != 0 { return nil, errors.New("square/go-jose: key wrap input must be 8 byte blocks") } n := (len(ciphertext) / 8) - 1 r := make([][]byte, n) for i := range r { r[i] = make([]byte, 8) copy(r[i], ciphertext[(i+1)*8:]) } buffer := make([]byte, 16) tBytes := make([]byte, 8) copy(buffer[:8], ciphertext[:8]) for t := 6*n - 1; t >= 0; t-- { binary.BigEndian.PutUint64(tBytes, uint64(t+1)) for i := 0; i < 8; i++ { buffer[i] = buffer[i] ^ tBytes[i] } copy(buffer[8:], r[t%n]) block.Decrypt(buffer, buffer) copy(r[t%n], buffer[8:]) } if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 { return nil, errors.New("square/go-jose: failed to unwrap key") } out := make([]byte, n*8) for i := range r { copy(out[i*8:], r[i]) } return out, nil }
func TestStreamCipher(t *testing.T) { var aes cipher.Block var err error iv := []byte{0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} aes, err = NewCipher(CRYPTO_AES_CBC, key, iv) if err != nil { t.Fatal(err) } blocksize := aes.BlockSize() ciphertext := make([]byte, blocksize) aes.Encrypt(ciphertext, cleartext) deciphertext := make([]byte, blocksize) aes, err = NewCipher(CRYPTO_AES_CBC, key, iv) aes.Decrypt(deciphertext, ciphertext) if !bytes.Equal(cleartext, deciphertext) { t.Fatal("couldn't decrypt %s %s", cleartext, deciphertext) } if err != nil { t.Fatal(err) } }
func key_unwarp(block cp.Block, ciphertext []byte) ([]byte, error) { if len(ciphertext)%8 != 0 { return nil, errors.New("key warp must 8 byte") } n := (len(ciphertext) / 8) - 1 r := make([][]byte, n) for i := range r { r[i] = make([]byte, 8) copy(r[i], ciphertext[(i+1)*8:]) } buf := make([]byte, 16) tb := make([]byte, 8) copy(buf[:8], ciphertext[:8]) for t := 6*n - 1; t >= 0; t-- { binary.BigEndian.PutUint64(tb, uint64(t+1)) for i := 0; i < 8; i++ { buf[i] = buf[i] ^ tb[i] } //fmt.Println(buf, r, t%n) copy(buf[8:], r[t%n]) block.Decrypt(buf, buf) copy(r[t%n], buf[8:]) } if subtle.ConstantTimeCompare(buf[:8], default_iv) == 0 { return nil, errors.New("failed to unwarp key") } out := make([]byte, n*8) for i := range r { copy(out[i*8:], r[i]) } return out, nil }
func CBCDecrypt(block cipher.Block, iv, dst, src []byte) { size := block.BlockSize() if len(iv) != size { panic("size of IV not equal to block size") } if len(dst)%size != 0 { panic("size of dst and src should be multiples of blocksize") } if len(dst) == 0 || len(src) == 0 { return } x := make([]byte, size) oldSrc := make([]byte, size) copy(x, iv) var i int for i = 0; i < len(dst) && i < len(src); i += size { copy(oldSrc, src[i:i+size]) block.Decrypt(dst[i:i+size], src[i:i+size]) for j := 0; j < size; j++ { dst[i+j] ^= x[j] } copy(x, oldSrc) } }
// Decrypt takes a ciphertext, a nonce, and a tag as its input and outputs a decrypted // plaintext (if successful) and a boolean flag that determines whether the function // successfully decrypted the given ciphertext. // // Before using the decrpyted plaintext, the application // should verify that the computed authentication tag matches the tag that was produced when // encrypting the message (taking into consideration that OCB tags are allowed to be truncated // to a length less than ocb.TagSize). // // 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 Decrypt(cipher cipher.Block, plain []byte, encrypted []byte, nonce []byte, tag []byte) bool { 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(encrypted) for remain > BlockSize { times2(delta[0:]) xor(tmp[0:], delta[0:], encrypted[off:off+BlockSize]) cipher.Decrypt(tmp[0:], tmp[0:]) xor(plain[off:off+BlockSize], delta[0:], tmp[0:]) xor(checksum[0:], checksum[0:], plain[off:off+BlockSize]) off += BlockSize remain -= 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:]) zeros(tmp[0:]) copied := copy(tmp[0:remain], encrypted[off:off+remain]) if copied != remain { panic("ocb2: copy failed") } xor(tmp[0:], tmp[0:], pad[0:]) xor(checksum[0:], checksum[0:], tmp[0:]) copied = copy(plain[off:off+remain], tmp[0:remain]) if copied != remain { panic("ocb2: copy failed") } times3(delta[0:]) xor(tmp[0:], delta[0:], checksum[0:]) cipher.Encrypt(calcTag[0:], tmp[0:]) // Compare the calculated tag with the expected tag. Truncate // the computed tag if necessary. if subtle.ConstantTimeCompare(calcTag[:len(tag)], tag) != 1 { return false } return true }